Package org.openrdf.sail.rdbms.optimizers

Source Code of org.openrdf.sail.rdbms.optimizers.ValueJoinOptimizer

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.rdbms.optimizers;

import java.util.ArrayList;
import java.util.List;

import org.openrdf.query.BindingSet;
import org.openrdf.query.algebra.QueryModel;
import org.openrdf.query.algebra.evaluation.QueryOptimizer;
import org.openrdf.sail.rdbms.algebra.BNodeColumn;
import org.openrdf.sail.rdbms.algebra.ColumnVar;
import org.openrdf.sail.rdbms.algebra.DatatypeColumn;
import org.openrdf.sail.rdbms.algebra.DateTimeColumn;
import org.openrdf.sail.rdbms.algebra.HashColumn;
import org.openrdf.sail.rdbms.algebra.IdColumn;
import org.openrdf.sail.rdbms.algebra.JoinItem;
import org.openrdf.sail.rdbms.algebra.LabelColumn;
import org.openrdf.sail.rdbms.algebra.LanguageColumn;
import org.openrdf.sail.rdbms.algebra.LongLabelColumn;
import org.openrdf.sail.rdbms.algebra.LongURIColumn;
import org.openrdf.sail.rdbms.algebra.NumericColumn;
import org.openrdf.sail.rdbms.algebra.RefIdColumn;
import org.openrdf.sail.rdbms.algebra.SelectQuery;
import org.openrdf.sail.rdbms.algebra.SqlEq;
import org.openrdf.sail.rdbms.algebra.URIColumn;
import org.openrdf.sail.rdbms.algebra.UnionItem;
import org.openrdf.sail.rdbms.algebra.base.FromItem;
import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
import org.openrdf.sail.rdbms.schema.BNodeTable;
import org.openrdf.sail.rdbms.schema.HashTable;
import org.openrdf.sail.rdbms.schema.LiteralTable;
import org.openrdf.sail.rdbms.schema.URITable;

/**
* Adds LEFT JOINs to the query for value tables.
*
* @author James Leigh
*/
public class ValueJoinOptimizer extends RdbmsQueryModelVisitorBase<RuntimeException> implements
    QueryOptimizer
{

  private URITable uris;

  private BNodeTable bnodes;

  private LiteralTable literals;

  private HashTable hashes;

  private FromItem join;

  private FromItem parent;

  private List<FromItem> stack = new ArrayList<FromItem>();

  private SelectQuery query;

  public void setUriTable(URITable uris) {
    this.uris = uris;
  }

  public void setBnodeTable(BNodeTable bnodes) {
    this.bnodes = bnodes;
  }

  public void setLiteralTable(LiteralTable literals) {
    this.literals = literals;
  }

  public void setHashTable(HashTable hashes) {
    this.hashes = hashes;
  }

  public void optimize(QueryModel query, BindingSet bindings) {
    join = null;
    query.visit(this);
  }

  @Override
  public void meetFromItem(FromItem node)
    throws RuntimeException
  {
    FromItem top = parent;
    parent = join;
    join = node;
    super.meetFromItem(node);
    join = parent;
    parent = top;
  }

  @Override
  public void meet(UnionItem node)
    throws RuntimeException
  {
    stack.add(node);
    super.meet(node);
    stack.remove(stack.size() - 1);
  }

  @Override
  public void meet(SelectQuery node)
    throws RuntimeException
  {
    query = node;
    parent = node.getFrom();
    join = node.getFrom();
    super.meet(node);
    join = null;
    parent = null;
    query = null;
  }

  @Override
  public void meet(HashColumn node)
    throws RuntimeException
  {
    if (hashes == null || hashes.getName() == null) {
      super.meet(node);
    }
    else {
      ColumnVar var = node.getRdbmsVar();
      String alias = "h" + getDBName(var);
      String tableName = hashes.getName();
      join(var, alias, tableName, false);
    }
  }

  @Override
  public void meet(BNodeColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "b" + getDBName(var);
    String tableName = bnodes.getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(DatatypeColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "d" + getDBName(var);
    String tableName = literals.getDatatypeTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(DateTimeColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "t" + getDBName(var);
    String tableName = literals.getDateTimeTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(LabelColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "l" + getDBName(var);
    String tableName = literals.getLabelTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(LongLabelColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "ll" + getDBName(var);
    String tableName = literals.getLongLabelTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(LanguageColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "g" + getDBName(var);
    String tableName = literals.getLanguageTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(NumericColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "n" + getDBName(var);
    String tableName = literals.getNumericTable().getName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(LongURIColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "lu" + getDBName(var);
    String tableName = uris.getLongTableName();
    join(var, alias, tableName);
  }

  @Override
  public void meet(URIColumn node)
    throws RuntimeException
  {
    ColumnVar var = node.getRdbmsVar();
    String alias = "u" + getDBName(var);
    String tableName = uris.getShortTableName();
    join(var, alias, tableName);
  }

  private CharSequence getDBName(ColumnVar var) {
    String name = var.getName();
    if (name.indexOf('-') >= 0) {
      return name.replace('-', '_');
    }
    return "_" + name; // might be a keyword otherwise
  }

  private void join(ColumnVar var, String alias, String tableName) {
    join(var, alias, tableName, true);
  }

  private void join(ColumnVar var, String alias, String tableName, boolean left) {
    if (!isJoined(alias)) {
      FromItem valueJoin = valueJoin(alias, tableName, var, left);
      if (join == parent || join.getFromItem(var.getAlias()) != null) {
        join.addJoin(valueJoin);
      }
      else {
        parent.addJoinBefore(valueJoin, join);
      }
    }
  }

  private boolean isJoined(String alias) {
    if (stack.isEmpty()) {
      return query.getFromItem(alias) != null;
    }
    return stack.get(stack.size() - 1).getFromItem(alias) != null;
  }

  private FromItem valueJoin(String alias, String tableName, ColumnVar using, boolean left) {
    JoinItem j = new JoinItem(alias, tableName);
    j.setLeft(left);
    j.addFilter(new SqlEq(new IdColumn(alias), new RefIdColumn(using)));
    return j;
  }
}
TOP

Related Classes of org.openrdf.sail.rdbms.optimizers.ValueJoinOptimizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.