You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2014/02/12 15:33:38 UTC
svn commit: r1567633 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query:
./ ast/
Author: thomasm
Date: Wed Feb 12 14:33:38 2014
New Revision: 1567633
URL: http://svn.apache.org/r1567633
Log:
OAK-1372 XPath queries with both path and property restrictions are slow (WIP)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SelectorExecutionPlan.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinConditionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Wed Feb 12 14:33:38 2014
@@ -17,8 +17,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.api.Tree;
@@ -38,6 +40,9 @@ import org.apache.jackrabbit.oak.query.a
import org.apache.jackrabbit.oak.query.ast.FullTextSearchImpl;
import org.apache.jackrabbit.oak.query.ast.FullTextSearchScoreImpl;
import org.apache.jackrabbit.oak.query.ast.InImpl;
+import org.apache.jackrabbit.oak.query.ast.JoinConditionImpl;
+import org.apache.jackrabbit.oak.query.ast.JoinImpl;
+import org.apache.jackrabbit.oak.query.ast.JoinType;
import org.apache.jackrabbit.oak.query.ast.LengthImpl;
import org.apache.jackrabbit.oak.query.ast.LiteralImpl;
import org.apache.jackrabbit.oak.query.ast.LowerCaseImpl;
@@ -87,7 +92,7 @@ public class QueryImpl implements Query
private static final Logger LOG = LoggerFactory.getLogger(QueryImpl.class);
- final SourceImpl source;
+ SourceImpl source;
final String statement;
final HashMap<String, PropertyValue> bindVariableMap = new HashMap<String, PropertyValue>();
final HashMap<String, Integer> selectorIndexes = new HashMap<String, Integer>();
@@ -438,7 +443,57 @@ public class QueryImpl implements Query
return;
}
prepared = true;
- estimatedCost = source.prepare();
+ List<SourceImpl> sources = source.getInnerJoinSelectors();
+ List<JoinConditionImpl> conditions = source.getInnerJoinConditions();
+
+// if (sources.size() <= 1) {
+ // simple case (no join)
+ estimatedCost = source.prepare();
+// return;
+// }
+
+// if (sources.size() < 6) {
+// // TODO iterate over all permutations
+// }
+//
+// // use a greedy algorithm
+// SourceImpl result = null;
+// Set<SourceImpl> available = new HashSet<SourceImpl>();
+// while (sources.size() > 0) {
+// int bestIndex = 0;
+// double bestCost = Double.POSITIVE_INFINITY;
+// for (int i = 0; i < sources.size(); i++) {
+// SourceImpl source = buildJoin(result, sources.get(i).createClone(), conditions);
+// double cost = source.prepare();
+// if (cost <= bestCost) {
+// bestCost = cost;
+// bestIndex = i;
+// }
+// }
+// SourceImpl s = sources.get(bestIndex).createClone();
+// available.add(s);
+// sources.remove(bestIndex);
+// result = buildJoin(result, s, conditions);
+// }
+// source = result;
+
+ }
+
+ private static SourceImpl buildJoin(SourceImpl result, SourceImpl last, List<JoinConditionImpl> conditions) {
+ if (result == null) {
+ return last;
+ }
+ Set<SourceImpl> available = new HashSet<SourceImpl>();
+ available.addAll(result.getInnerJoinSelectors());
+ available.add(last);
+ for (JoinConditionImpl j : conditions) {
+ if (j.canEvaluate(available)) {
+ JoinImpl join = new JoinImpl(result, last, JoinType.INNER, j);
+ return join;
+ }
+ }
+ // this is an internal error
+ throw new IllegalArgumentException("No join condition was found");
}
/**
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SelectorExecutionPlan.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SelectorExecutionPlan.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SelectorExecutionPlan.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SelectorExecutionPlan.java Wed Feb 12 14:33:38 2014
@@ -28,10 +28,10 @@ import org.apache.jackrabbit.oak.spi.que
*/
public class SelectorExecutionPlan {
- public Filter filter;
-
public SelectorImpl selector;
+ public Filter filter;
+
public double estimatedCost;
public QueryIndex index;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java Wed Feb 12 14:33:38 2014
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -97,5 +99,10 @@ public class ChildNodeJoinConditionImpl
public boolean isParent(SourceImpl source) {
return source == parentSelector;
}
+
+ @Override
+ public boolean canEvaluate(Set<SourceImpl> available) {
+ return available.contains(childSelector) && available.contains(parentSelector);
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java Wed Feb 12 14:33:38 2014
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -97,5 +99,10 @@ public class DescendantNodeJoinCondition
public boolean isParent(SourceImpl source) {
return source == ancestorSelector;
}
+
+ @Override
+ public boolean canEvaluate(Set<SourceImpl> available) {
+ return available.contains(descendantSelector) && available.contains(ancestorSelector);
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java Wed Feb 12 14:33:38 2014
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
@@ -145,5 +147,10 @@ public class EquiJoinConditionImpl exten
public boolean isParent(SourceImpl source) {
return false;
}
+
+ @Override
+ public boolean canEvaluate(Set<SourceImpl> available) {
+ return available.contains(selector1) && available.contains(selector2);
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinConditionImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinConditionImpl.java Wed Feb 12 14:33:38 2014
@@ -13,6 +13,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.query.index.FilterImpl;
/**
@@ -60,5 +62,13 @@ public abstract class JoinConditionImpl
* @return true if the source is the parent
*/
public abstract boolean isParent(SourceImpl source);
+
+ /**
+ * Whether the join condition can be evaluated if the given selectors are able to retrieve data.
+ *
+ * @param available the available selectors
+ * @return true if the condition can be evaluated
+ */
+ public abstract boolean canEvaluate(Set<SourceImpl> available);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java Wed Feb 12 14:33:38 2014
@@ -13,6 +13,9 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.jackrabbit.oak.query.QueryImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -41,6 +44,51 @@ public class JoinImpl extends SourceImpl
this.joinType = joinType;
this.joinCondition = joinCondition;
}
+
+ private JoinImpl(JoinImpl clone) {
+ this.left = clone.left;
+ this.right = clone.right;
+ this.joinType = clone.joinType;
+ this.joinCondition = clone.joinCondition;
+ this.query = clone.query;
+ }
+
+ @Override
+ public ArrayList<SourceImpl> getInnerJoinSelectors() {
+ ArrayList<SourceImpl> list = new ArrayList<SourceImpl>();
+ switch (joinType) {
+ case INNER:
+ list.addAll(left.getInnerJoinSelectors());
+ list.addAll(right.getInnerJoinSelectors());
+ break;
+ case LEFT_OUTER:
+ list.addAll(left.getInnerJoinSelectors());
+ list.add(right);
+ break;
+ case RIGHT_OUTER:
+ list.addAll(right.getInnerJoinSelectors());
+ list.add(left);
+ }
+ return list;
+ }
+
+ @Override
+ public List<JoinConditionImpl> getInnerJoinConditions() {
+ ArrayList<JoinConditionImpl> set = new ArrayList<JoinConditionImpl>();
+ switch (joinType) {
+ case INNER:
+ set.add(joinCondition);
+ set.addAll(left.getInnerJoinConditions());
+ set.addAll(right.getInnerJoinConditions());
+ break;
+ }
+ return set;
+ }
+
+ @Override
+ public JoinImpl createClone() {
+ return new JoinImpl(this);
+ }
public JoinConditionImpl getJoinCondition() {
return joinCondition;
@@ -105,8 +153,6 @@ public class JoinImpl extends SourceImpl
right.addJoinCondition(joinCondition, true);
break;
}
- left.setQueryConstraint(queryConstraint);
- right.setQueryConstraint(queryConstraint);
setParent(joinCondition);
right.init(query);
left.init(query);
@@ -152,6 +198,24 @@ public class JoinImpl extends SourceImpl
}
@Override
+ public void setQueryConstraint(ConstraintImpl queryConstraint) {
+ left.setQueryConstraint(queryConstraint);
+ right.setQueryConstraint(queryConstraint);
+ }
+
+ @Override
+ public void setOuterJoin(boolean outerJoinLeftHandSide, boolean outerJoinRightHandSide) {
+ left.setOuterJoin(outerJoinLeftHandSide, outerJoinRightHandSide);
+ right.setOuterJoin(outerJoinLeftHandSide, outerJoinRightHandSide);
+ }
+
+ @Override
+ public void addJoinCondition(JoinConditionImpl joinCondition, boolean forThisSelector) {
+ left.addJoinCondition(joinCondition, forThisSelector);
+ right.addJoinCondition(joinCondition, forThisSelector);
+ }
+
+ @Override
public boolean next() {
if (end) {
return false;
@@ -185,10 +249,15 @@ public class JoinImpl extends SourceImpl
}
// for an outer join, if no matching result was found,
// one row returned (with all values set to null)
- if (right.outerJoinRightHandSide && leftNeedNext && !foundJoinedRow) {
+ if (right.isOuterJoinRightHandSide() && leftNeedNext && !foundJoinedRow) {
return true;
}
}
}
+
+ @Override
+ public boolean isOuterJoinRightHandSide() {
+ return left.isOuterJoinRightHandSide() || right.isOuterJoinRightHandSide();
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java Wed Feb 12 14:33:38 2014
@@ -71,7 +71,7 @@ public class NotImpl extends ConstraintI
@Override
public void restrict(FilterImpl f) {
- if (f.getSelector().outerJoinRightHandSide) {
+ if (f.getSelector().isOuterJoinRightHandSide()) {
// we need to be careful with the condition
// "NOT (property IS NOT NULL)"
// (which is the same as "property IS NULL")
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java Wed Feb 12 14:33:38 2014
@@ -123,7 +123,7 @@ public class PropertyInexistenceImpl ext
@Override
public void restrictPushDown(SelectorImpl s) {
- if (s.outerJoinRightHandSide) {
+ if (s.isOuterJoinRightHandSide()) {
// we need to be careful with "property IS NULL"
// because this might cause an index
// to ignore the join condition "property = x"
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java Wed Feb 12 14:33:38 2014
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -120,5 +122,10 @@ public class SameNodeJoinConditionImpl e
public boolean isParent(SourceImpl source) {
return false;
}
+
+ @Override
+ public boolean canEvaluate(Set<SourceImpl> available) {
+ return available.contains(selector1) && available.contains(selector2);
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Wed Feb 12 14:33:38 2014
@@ -60,12 +60,26 @@ import com.google.common.collect.Iterabl
* A selector within a query.
*/
public class SelectorImpl extends SourceImpl {
-
+
// TODO possibly support using multiple indexes (using index intersection / index merge)
- protected SelectorExecutionPlan plan;
+ private SelectorExecutionPlan plan;
+
+ /**
+ * The WHERE clause of the query.
+ */
+ private ConstraintImpl queryConstraint;
+
+ /**
+ * The join condition of this selector that can be evaluated at execution
+ * time. For the query "select * from nt:base as a inner join nt:base as b
+ * on a.x = b.x", the join condition "a.x = b.x" is only set for the
+ * selector b, as selector a can't evaluate it if it is executed first
+ * (until b is executed).
+ */
+ private JoinConditionImpl joinCondition;
/**
- * the node type associated with the {@link #nodeTypeName}
+ * The node type associated with the {@link #nodeTypeName}
*/
private final NodeState nodeType;
@@ -92,13 +106,34 @@ public class SelectorImpl extends Source
* flag is set
*/
private final Set<String> mixinTypes;
+
+ /**
+ * Whether this selector is the parent of a descendent or parent-child join.
+ * Access rights don't need to be checked in such selectors (unless there
+ * are conditions on the selector).
+ */
+ private boolean isParent;
+
+ /**
+ * Whether this selector is the left hand side of a left outer join.
+ * Right outer joins are converted to left outer join.
+ */
+ private boolean outerJoinLeftHandSide;
- private Cursor cursor;
- private IndexRow currentRow;
- private int scanCount;
+ /**
+ * Whether this selector is the right hand side of a left outer join.
+ * Right outer joins are converted to left outer join.
+ */
+ private boolean outerJoinRightHandSide;
- private Tree lastTree;
- private String lastPath;
+ /**
+ * The list of all join conditions this selector is involved. For the query
+ * "select * from nt:base as a inner join nt:base as b on a.x =
+ * b.x", the join condition "a.x = b.x" is set for both selectors a and b,
+ * so both can check if the property x is set.
+ */
+ private ArrayList<JoinConditionImpl> allJoinConditions =
+ new ArrayList<JoinConditionImpl>();
/**
* The selector condition can be evaluated when the given selector is
@@ -106,9 +141,17 @@ public class SelectorImpl extends Source
* "select * from nt:base a inner join nt:base b where a.x = 1 and b.y = 2",
* the condition "a.x = 1" can be evaluated when evaluating selector a. The
* other part of the condition can't be evaluated until b is available.
+ * This field is set during the prepare phase.
*/
private ConstraintImpl selectorCondition;
+ private Cursor cursor;
+ private IndexRow currentRow;
+ private int scanCount;
+
+ private Tree lastTree;
+ private String lastPath;
+
public SelectorImpl(NodeState nodeType, String selectorName) {
this.nodeType = checkNotNull(nodeType);
this.selectorName = checkNotNull(selectorName);
@@ -134,6 +177,41 @@ public class SelectorImpl extends Source
this.mixinTypes = ImmutableSet.of();
}
}
+
+ private SelectorImpl(SelectorImpl clone) {
+ this.nodeType = clone.nodeType;
+ this.selectorName = clone.selectorName;
+ this.nodeTypeName = clone.nodeTypeName;
+ this.matchesAllTypes = clone.matchesAllTypes;
+ this.supertypes = clone.supertypes;
+ this.primaryTypes = clone.primaryTypes;
+ this.mixinTypes = clone.mixinTypes;
+ this.query = clone.query;
+ this.isParent = clone.isParent;
+ this.outerJoinLeftHandSide = clone.outerJoinLeftHandSide;
+ this.outerJoinRightHandSide = clone.outerJoinRightHandSide;
+ this.allJoinConditions = clone.allJoinConditions;
+ }
+
+
+// queryConstraint;
+// protected JoinConditionImpl joinCondition;
+// protected ArrayList<JoinConditionImpl> allJoinConditions =
+// new ArrayList<JoinConditionImpl>();
+// protected boolean join;
+// protected boolean outerJoinLeftHandSide;
+// protected boolean outerJoinRightHandSide;
+// protected boolean isParent;
+
+ /**
+ * Create a shallow clone of this instance.
+ *
+ * @return the clone
+ */
+ @Override
+ public SelectorImpl createClone() {
+ return new SelectorImpl(this);
+ }
public String getSelectorName() {
return selectorName;
@@ -201,6 +279,25 @@ public class SelectorImpl extends Source
plan = query.getBestSelectorExecutionPlan(createFilter(true));
return plan.estimatedCost;
}
+
+ @Override
+ public void setQueryConstraint(ConstraintImpl queryConstraint) {
+ this.queryConstraint = queryConstraint;
+ }
+
+ @Override
+ public void setOuterJoin(boolean outerJoinLeftHandSide, boolean outerJoinRightHandSide) {
+ this.outerJoinLeftHandSide = outerJoinLeftHandSide;
+ this.outerJoinRightHandSide = outerJoinRightHandSide;
+ }
+
+ @Override
+ public void addJoinCondition(JoinConditionImpl joinCondition, boolean forThisSelector) {
+ if (forThisSelector) {
+ this.joinCondition = joinCondition;
+ }
+ allJoinConditions.add(joinCondition);
+ }
@Override
public void execute(NodeState rootState) {
@@ -568,4 +665,16 @@ public class SelectorImpl extends Source
return plan == null ? null : plan.index;
}
+ @Override
+ public ArrayList<SourceImpl> getInnerJoinSelectors() {
+ ArrayList<SourceImpl> list = new ArrayList<SourceImpl>();
+ list.add(this);
+ return list;
+ }
+
+ @Override
+ public boolean isOuterJoinRightHandSide() {
+ return this.outerJoinRightHandSide;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java?rev=1567633&r1=1567632&r2=1567633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java Wed Feb 12 14:33:38 2014
@@ -18,7 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.apache.jackrabbit.oak.query.QueryImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -28,62 +29,13 @@ import org.apache.jackrabbit.oak.spi.sta
* The base class of a selector and a join.
*/
public abstract class SourceImpl extends AstElement {
-
- /**
- * The WHERE clause of the query.
- */
- protected ConstraintImpl queryConstraint;
-
- /**
- * The join condition of this selector that can be evaluated at execution
- * time. For the query "select * from nt:base as a inner join nt:base as b
- * on a.x = b.x", the join condition "a.x = b.x" is only set for the
- * selector b, as selector a can't evaluate it if it is executed first
- * (until b is executed).
- */
- protected JoinConditionImpl joinCondition;
-
- /**
- * The list of all join conditions this selector is involved. For the query
- * "select * from nt:base as a inner join nt:base as b on a.x =
- * b.x", the join condition "a.x = b.x" is set for both selectors a and b,
- * so both can check if the property x is set.
- */
- protected ArrayList<JoinConditionImpl> allJoinConditions =
- new ArrayList<JoinConditionImpl>();
-
- /**
- * Whether this selector is the right hand side of a join.
- */
- protected boolean join;
-
- /**
- * Whether this selector is the left hand side of a left outer join.
- * Right outer joins are converted to left outer join.
- */
- protected boolean outerJoinLeftHandSide;
-
- /**
- * Whether this selector is the right hand side of a left outer join.
- * Right outer joins are converted to left outer join.
- */
- protected boolean outerJoinRightHandSide;
-
- /**
- * Whether this selector is the parent of a descendent or parent-child join.
- * Access rights don't need to be checked in such selectors (unless there
- * are conditions on the selector).
- */
- protected boolean isParent;
/**
* Set the complete constraint of the query (the WHERE ... condition).
*
* @param queryConstraint the constraint
*/
- public void setQueryConstraint(ConstraintImpl queryConstraint) {
- this.queryConstraint = queryConstraint;
- }
+ public abstract void setQueryConstraint(ConstraintImpl queryConstraint);
/**
* Add the join condition (the ON ... condition).
@@ -92,12 +44,7 @@ public abstract class SourceImpl extends
* @param forThisSelector if set, the join condition can only be evaluated
* when all previous selectors are executed.
*/
- public void addJoinCondition(JoinConditionImpl joinCondition, boolean forThisSelector) {
- if (forThisSelector) {
- this.joinCondition = joinCondition;
- }
- allJoinConditions.add(joinCondition);
- }
+ public abstract void addJoinCondition(JoinConditionImpl joinCondition, boolean forThisSelector);
/**
* Set whether this source is the left hand side or right hand side of a left outer join.
@@ -105,10 +52,7 @@ public abstract class SourceImpl extends
* @param outerJoinLeftHandSide true if yes
* @param outerJoinRightHandSide true if yes
*/
- public void setOuterJoin(boolean outerJoinLeftHandSide, boolean outerJoinRightHandSide) {
- this.outerJoinLeftHandSide = outerJoinLeftHandSide;
- this.outerJoinRightHandSide = outerJoinRightHandSide;
- }
+ public abstract void setOuterJoin(boolean outerJoinLeftHandSide, boolean outerJoinRightHandSide);
/**
* Initialize the query. This will 'wire' the selectors with the
@@ -170,6 +114,13 @@ public abstract class SourceImpl extends
* @return true if there is a next row
*/
public abstract boolean next();
+
+ /**
+ * Create a shallow clone of this instance.
+ *
+ * @return the clone
+ */
+ public abstract SourceImpl createClone();
abstract void setParent(JoinConditionImpl joinCondition);
@@ -183,4 +134,27 @@ public abstract class SourceImpl extends
*/
public abstract Filter createFilter(boolean preparing);
+ /**
+ * Get all sources that are joined via inner join. (These can be swapped.)
+ *
+ * @return the list of selectors (sorted from left to right)
+ */
+ public abstract List<SourceImpl> getInnerJoinSelectors();
+
+ /**
+ * Get the list of inner join conditions. (These match the inner join selectors.)
+ *
+ * @return the list of join conditions
+ */
+ public List<JoinConditionImpl> getInnerJoinConditions() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Whether any selector is the outer-join right hand side.
+ *
+ * @return true if there is any
+ */
+ public abstract boolean isOuterJoinRightHandSide();
+
}