/* * 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.TupleExpr; 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.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.PointColumn; import org.openrdf.sail.rdbms.algebra.RefIdColumn; import org.openrdf.sail.rdbms.algebra.SelectQuery; import org.openrdf.sail.rdbms.algebra.SqlIsNull; import org.openrdf.sail.rdbms.algebra.SqlNull; 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.algebra.base.ValueColumnBase; /** * Localises variables to use an available column in the current variable scope. * * @author James Leigh * */ public class VarColumnLookupOptimizer extends RdbmsQueryModelVisitorBase<RuntimeException> implements QueryOptimizer { private FromItem parent; private FromItem gparent; public VarColumnLookupOptimizer() { super(); } public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) { parent = null; tupleExpr.visit(this); } @Override public void meetFromItem(FromItem node) throws RuntimeException { FromItem top = gparent; gparent = parent; parent = node; super.meetFromItem(node); parent = gparent; gparent = top; } @Override public void meet(SelectQuery node) throws RuntimeException { gparent = node.getFrom(); parent = node.getFrom(); super.meet(node); parent = null; gparent = null; } @Override public void meet(BNodeColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isBNodes()) { node.replaceWith(new SqlNull()); } } @Override public void meet(DatatypeColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isTyped()) { node.replaceWith(new SqlNull()); } } @Override public void meet(DateTimeColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isCalendar()) { node.replaceWith(new SqlNull()); } } @Override public void meet(LabelColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isLiterals()) { node.replaceWith(new SqlNull()); } } @Override public void meet(LongLabelColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isLong() || !var.getTypes().isLiterals()) { node.replaceWith(new SqlNull()); } } @Override public void meet(LanguageColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isLanguages()) { node.replaceWith(new SqlNull()); } } @Override public void meet(NumericColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isNumeric()) { node.replaceWith(new SqlNull()); } } @Override public void meet(LongURIColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isLong() || !var.getTypes().isURIs()) { node.replaceWith(new SqlNull()); } } @Override public void meet(URIColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isURIs()) { node.replaceWith(new SqlNull()); } } public void meet(PointColumn node) throws RuntimeException { ColumnVar var = replaceVar(node); if (var == null) return; if (!var.getTypes().isLiterals()) { node.replaceWith(new SqlNull()); } } @Override public void meet(RefIdColumn node) throws RuntimeException { replaceVar(node); } @Override public void meet(HashColumn node) throws RuntimeException { replaceVar(node); } private ColumnVar replaceVar(ValueColumnBase node) { ColumnVar var; if (gparent == parent || gparent instanceof UnionItem) { var = parent.getVar(node.getVarName()); } else { var = gparent.getVarForChildren(node.getVarName()); } if (var == null) { node.replaceWith(new SqlNull()); } else if (var.isImplied() && node.getParentNode() instanceof SqlIsNull) { node.replaceWith(new IdColumn(var.getAlias(), "subj")); } else { node.setRdbmsVar(var); } return var; } }