/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.rdbms.optimizers;
import org.openrdf.query.BindingSet;
import org.openrdf.query.Dataset;
import org.openrdf.query.algebra.QueryRoot;
import org.openrdf.query.algebra.TupleExpr;
import org.openrdf.query.algebra.evaluation.EvaluationStrategy;
import org.openrdf.query.algebra.evaluation.impl.BindingAssigner;
import org.openrdf.query.algebra.evaluation.impl.CompareOptimizer;
import org.openrdf.query.algebra.evaluation.impl.ConjunctiveConstraintSplitter;
import org.openrdf.query.algebra.evaluation.impl.ConstantOptimizer;
import org.openrdf.query.algebra.evaluation.impl.QueryJoinOptimizer;
import org.openrdf.query.algebra.evaluation.impl.SameTermFilterOptimizer;
import org.openrdf.query.algebra.evaluation.util.QueryOptimizerList;
import org.openrdf.sail.rdbms.RdbmsValueFactory;
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;
/**
* Facade to the underlying RDBMS optimizations.
*
* @author James Leigh
*
*/
public class RdbmsQueryOptimizer {
private RdbmsValueFactory vf;
private URITable uris;
private BNodeTable bnodes;
private LiteralTable literals;
private SelectQueryOptimizerFactory factory;
private HashTable hashTable;
public void setSelectQueryOptimizerFactory(SelectQueryOptimizerFactory factory) {
this.factory = factory;
}
public void setValueFactory(RdbmsValueFactory vf) {
this.vf = vf;
}
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 hashTable) {
this.hashTable = hashTable;
}
public TupleExpr optimize(TupleExpr expr, Dataset dataset, BindingSet bindings, EvaluationStrategy strategy)
{
// Clone the tuple expression to allow for more aggressive optimisations
TupleExpr tupleExpr = expr.clone();
if (!(tupleExpr instanceof QueryRoot)) {
// Add a dummy root node to the tuple expressions to allow the
// optimisers to modify the actual root node
tupleExpr = new QueryRoot(tupleExpr);
}
QueryOptimizerList optimizerList = new QueryOptimizerList();
addCoreOptimizations(strategy, optimizerList);
addRdbmsOptimizations(optimizerList);
optimizerList.add(new SqlConstantOptimizer());
optimizerList.optimize(tupleExpr, dataset, bindings);
return tupleExpr;
}
protected void addCoreOptimizations(EvaluationStrategy strategy, QueryOptimizerList optimizerList) {
optimizerList.add(new BindingAssigner());
optimizerList.add(new ConstantOptimizer(strategy));
optimizerList.add(new CompareOptimizer());
optimizerList.add(new ConjunctiveConstraintSplitter());
optimizerList.add(new SameTermFilterOptimizer());
optimizerList.add(new QueryJoinOptimizer());
}
protected void addRdbmsOptimizations(QueryOptimizerList optimizerList) {
optimizerList.add(new ValueIdLookupOptimizer(vf));
optimizerList.add(factory.createRdbmsFilterOptimizer());
optimizerList.add(new VarColumnLookupOptimizer());
ValueJoinOptimizer valueJoins = new ValueJoinOptimizer();
valueJoins.setBnodeTable(bnodes);
valueJoins.setUriTable(uris);
valueJoins.setLiteralTable(literals);
valueJoins.setHashTable(hashTable);
optimizerList.add(valueJoins);
}
}