001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail.rdbms.optimizers;
007:
008: import org.openrdf.query.BindingSet;
009: import org.openrdf.query.Dataset;
010: import org.openrdf.query.algebra.TupleExpr;
011: import org.openrdf.query.algebra.evaluation.QueryOptimizer;
012: import org.openrdf.sail.rdbms.algebra.BNodeColumn;
013: import org.openrdf.sail.rdbms.algebra.ColumnVar;
014: import org.openrdf.sail.rdbms.algebra.DatatypeColumn;
015: import org.openrdf.sail.rdbms.algebra.DateTimeColumn;
016: import org.openrdf.sail.rdbms.algebra.HashColumn;
017: import org.openrdf.sail.rdbms.algebra.IdColumn;
018: import org.openrdf.sail.rdbms.algebra.LabelColumn;
019: import org.openrdf.sail.rdbms.algebra.LanguageColumn;
020: import org.openrdf.sail.rdbms.algebra.LongLabelColumn;
021: import org.openrdf.sail.rdbms.algebra.LongURIColumn;
022: import org.openrdf.sail.rdbms.algebra.NumericColumn;
023: import org.openrdf.sail.rdbms.algebra.RefIdColumn;
024: import org.openrdf.sail.rdbms.algebra.SelectQuery;
025: import org.openrdf.sail.rdbms.algebra.SqlIsNull;
026: import org.openrdf.sail.rdbms.algebra.SqlNull;
027: import org.openrdf.sail.rdbms.algebra.URIColumn;
028: import org.openrdf.sail.rdbms.algebra.base.FromItem;
029: import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
030: import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
031:
032: /**
033: * Localises variables to use an available column in the current variable scope.
034: *
035: * @author James Leigh
036: *
037: */
038: public class VarColumnLookupOptimizer extends
039: RdbmsQueryModelVisitorBase<RuntimeException> implements
040: QueryOptimizer {
041: private FromItem parent;
042: private FromItem gparent;
043:
044: public VarColumnLookupOptimizer() {
045: super ();
046: }
047:
048: public void optimize(TupleExpr tupleExpr, Dataset dataset,
049: BindingSet bindings) {
050: parent = null;
051: tupleExpr.visit(this );
052: }
053:
054: @Override
055: public void meetFromItem(FromItem node) throws RuntimeException {
056: FromItem top = gparent;
057: gparent = parent;
058: parent = node;
059: super .meetFromItem(node);
060: parent = gparent;
061: gparent = top;
062: }
063:
064: @Override
065: public void meet(SelectQuery node) throws RuntimeException {
066: gparent = node.getFrom();
067: parent = node.getFrom();
068: super .meet(node);
069: parent = null;
070: gparent = null;
071: }
072:
073: @Override
074: public void meet(BNodeColumn node) throws RuntimeException {
075: ColumnVar var = replaceVar(node);
076: if (var == null)
077: return;
078: if (!var.getTypes().isBNodes()) {
079: node.replaceWith(new SqlNull());
080: }
081: }
082:
083: @Override
084: public void meet(DatatypeColumn node) throws RuntimeException {
085: ColumnVar var = replaceVar(node);
086: if (var == null)
087: return;
088: if (!var.getTypes().isTyped()) {
089: node.replaceWith(new SqlNull());
090: }
091: }
092:
093: @Override
094: public void meet(DateTimeColumn node) throws RuntimeException {
095: ColumnVar var = replaceVar(node);
096: if (var == null)
097: return;
098: if (!var.getTypes().isCalendar()) {
099: node.replaceWith(new SqlNull());
100: }
101: }
102:
103: @Override
104: public void meet(LabelColumn node) throws RuntimeException {
105: ColumnVar var = replaceVar(node);
106: if (var == null)
107: return;
108: if (!var.getTypes().isLiterals()) {
109: node.replaceWith(new SqlNull());
110: }
111: }
112:
113: @Override
114: public void meet(LongLabelColumn node) throws RuntimeException {
115: ColumnVar var = replaceVar(node);
116: if (var == null)
117: return;
118: if (!var.getTypes().isLong() || !var.getTypes().isLiterals()) {
119: node.replaceWith(new SqlNull());
120: }
121: }
122:
123: @Override
124: public void meet(LanguageColumn node) throws RuntimeException {
125: ColumnVar var = replaceVar(node);
126: if (var == null)
127: return;
128: if (!var.getTypes().isLanguages()) {
129: node.replaceWith(new SqlNull());
130: }
131: }
132:
133: @Override
134: public void meet(NumericColumn node) throws RuntimeException {
135: ColumnVar var = replaceVar(node);
136: if (var == null)
137: return;
138: if (!var.getTypes().isNumeric()) {
139: node.replaceWith(new SqlNull());
140: }
141: }
142:
143: @Override
144: public void meet(LongURIColumn node) throws RuntimeException {
145: ColumnVar var = replaceVar(node);
146: if (var == null)
147: return;
148: if (!var.getTypes().isLong() || !var.getTypes().isURIs()) {
149: node.replaceWith(new SqlNull());
150: }
151: }
152:
153: @Override
154: public void meet(URIColumn node) throws RuntimeException {
155: ColumnVar var = replaceVar(node);
156: if (var == null)
157: return;
158: if (!var.getTypes().isURIs()) {
159: node.replaceWith(new SqlNull());
160: }
161: }
162:
163: @Override
164: public void meet(RefIdColumn node) throws RuntimeException {
165: replaceVar(node);
166: }
167:
168: @Override
169: public void meet(HashColumn node) throws RuntimeException {
170: replaceVar(node);
171: }
172:
173: private ColumnVar replaceVar(ValueColumnBase node) {
174: ColumnVar var;
175: if (gparent == parent) {
176: var = parent.getVar(node.getVarName());
177: } else {
178: var = gparent.getVarForChildren(node.getVarName());
179: }
180: if (var == null) {
181: node.replaceWith(new SqlNull());
182: } else if (var.isImplied()
183: && node.getParentNode() instanceof SqlIsNull) {
184: node.replaceWith(new IdColumn(var.getAlias(), "subj"));
185: } else {
186: node.setRdbmsVar(var);
187: }
188: return var;
189: }
190: }
|