Author: rhauch
Date: 2009-10-21 13:01:35 -0400 (Wed, 21 Oct 2009)
New Revision: 1298
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/AbstractMergeSelectNodes.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/MergeSetCriteria.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/And.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/BindVariableName.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNodeJoinCondition.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Column.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Comparison.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNodeJoinCondition.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/EquiJoinCondition.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearch.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Join.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Limit.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Not.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Or.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Ordering.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyExistence.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Query.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNodeJoinCondition.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Selector.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetCriteria.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetQuery.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushProjects.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushSelectCriteria.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/ReplaceViews.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizer.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanNode.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
Log:
DNA-467 Added another optimization rule to merge set criteria, and added hashCode()
methods to all of the AQM classes.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/AllNodes.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -60,6 +60,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/And.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/And.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/And.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
* A constraint that evaluates to true when <i>both</i> of the other
constraints evaluate to true.
@@ -34,6 +35,7 @@
private final Constraint left;
private final Constraint right;
+ private final int hc;
public And( Constraint left,
Constraint right ) {
@@ -41,6 +43,7 @@
CheckArg.isNotNull(right, "right");
this.left = left;
this.right = right;
+ this.hc = HashCode.compute(this.left, this.right);
}
/**
@@ -70,6 +73,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -77,6 +90,7 @@
if (obj == this) return true;
if (obj instanceof And) {
And that = (And)obj;
+ if (this.hc != that.hc) return false;
return left.equals(that.left) && right.equals(that.right);
}
return false;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/BindVariableName.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/BindVariableName.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/BindVariableName.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -59,6 +59,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return variableName.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNode.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNode.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNode.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.property.Path;
/**
@@ -34,6 +35,7 @@
public class ChildNode extends Constraint {
private final SelectorName selectorName;
private final Path parentPath;
+ private final int hc;
/**
* Create a constraint requiring that the node identified by the selector is a child
of the node reachable by the supplied
@@ -48,6 +50,7 @@
CheckArg.isNotNull(parentPath, "parentPath");
this.selectorName = selectorName;
this.parentPath = parentPath;
+ this.hc = HashCode.compute(this.selectorName, this.parentPath);
}
/**
@@ -77,6 +80,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -84,6 +97,7 @@
if (obj == this) return true;
if (obj instanceof ChildNode) {
ChildNode that = (ChildNode)obj;
+ if (this.hc != that.hc) return false;
if (!this.selectorName.equals(that.selectorName)) return false;
if (!this.parentPath.equals(that.parentPath)) return false;
return true;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNodeJoinCondition.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNodeJoinCondition.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/ChildNodeJoinCondition.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
* A join condition that evaluates to true only when the named child node is indeed a
child of the named parent node.
@@ -33,6 +34,7 @@
public class ChildNodeJoinCondition extends JoinCondition {
private final SelectorName childSelectorName;
private final SelectorName parentSelectorName;
+ private final int hc;
/**
* Create a join condition that determines whether the node identified by the child
selector is a child of the node identified
@@ -47,6 +49,7 @@
CheckArg.isNotNull(parentSelectorName, "parentSelectorName");
this.childSelectorName = childSelectorName;
this.parentSelectorName = parentSelectorName;
+ this.hc = HashCode.compute(this.childSelectorName, this.parentSelectorName);
}
/**
@@ -76,6 +79,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -83,6 +96,7 @@
if (obj == this) return true;
if (obj instanceof ChildNodeJoinCondition) {
ChildNodeJoinCondition that = (ChildNodeJoinCondition)obj;
+ if (this.hc != that.hc) return false;
if (!this.childSelectorName.equals(that.childSelectorName)) return false;
if (!this.parentSelectorName.equals(that.parentSelectorName)) return false;
return true;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Column.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Column.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Column.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -102,6 +102,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Comparison.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Comparison.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Comparison.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
* A constraint that evaluates to true when the defined operation evaluates to true.
@@ -35,6 +36,7 @@
private final DynamicOperand operand1;
private final StaticOperand operand2;
private final Operator operator;
+ private final int hc;
public Comparison( DynamicOperand operand1,
Operator operator,
@@ -45,6 +47,7 @@
this.operand1 = operand1;
this.operand2 = operand2;
this.operator = operator;
+ this.hc = HashCode.compute(this.operand1, this.operand2, this.operator);
}
/**
@@ -81,6 +84,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -88,6 +101,7 @@
if (obj == this) return true;
if (obj instanceof Comparison) {
Comparison that = (Comparison)obj;
+ if (this.hc != that.hc) return false;
if (!this.operator.equals(that.operator)) return false;
if (!this.operand1.equals(that.operand1)) return false;
if (!this.operand2.equals(that.operand2)) return false;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNode.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNode.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNode.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -77,6 +77,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNodeJoinCondition.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNodeJoinCondition.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/DescendantNodeJoinCondition.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
* A join condition that evaluates to true only when the named node is a descendant of
another named node.
@@ -33,6 +34,7 @@
public class DescendantNodeJoinCondition extends JoinCondition {
private final SelectorName descendantSelectorName;
private final SelectorName ancestorSelectorName;
+ private final int hc;
/**
* Create a join condition that determines whether the node identified by the
descendant selector is indeed a descendant of
@@ -47,6 +49,7 @@
CheckArg.isNotNull(ancestorSelectorName, "ancestorSelectorName");
this.descendantSelectorName = descendantSelectorName;
this.ancestorSelectorName = ancestorSelectorName;
+ this.hc = HashCode.compute(this.descendantSelectorName,
this.ancestorSelectorName);
}
/**
@@ -76,6 +79,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -83,6 +96,7 @@
if (obj == this) return true;
if (obj instanceof DescendantNodeJoinCondition) {
DescendantNodeJoinCondition that = (DescendantNodeJoinCondition)obj;
+ if (this.hc != that.hc) return false;
if (!this.descendantSelectorName.equals(that.descendantSelectorName)) return
false;
if (!this.ancestorSelectorName.equals(that.ancestorSelectorName)) return
false;
return true;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/EquiJoinCondition.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/EquiJoinCondition.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/EquiJoinCondition.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.property.Name;
/**
@@ -42,6 +43,7 @@
private final Name property1Name;
private final SelectorName selector2Name;
private final Name property2Name;
+ private final int hc;
public EquiJoinCondition( SelectorName selector1Name,
Name property1Name,
@@ -55,6 +57,7 @@
this.property1Name = property1Name;
this.selector2Name = selector2Name;
this.property2Name = property2Name;
+ this.hc = HashCode.compute(this.selector1Name, this.property1Name,
this.selector2Name, this.property2Name);
}
public EquiJoinCondition( Column column1,
@@ -103,6 +106,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -110,6 +123,7 @@
if (obj == this) return true;
if (obj instanceof EquiJoinCondition) {
EquiJoinCondition that = (EquiJoinCondition)obj;
+ if (this.hc != that.hc) return false;
if (!this.selector1Name.equals(that.selector1Name)) return false;
if (!this.selector2Name.equals(that.selector2Name)) return false;
if (!this.property1Name.equals(that.property1Name)) return false;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearch.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearch.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearch.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -28,6 +28,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.text.ParsingException;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.query.parse.FullTextSearchParser;
@@ -42,6 +43,7 @@
private final Name propertyName;
private final String fullTextSearchExpression;
private Term term;
+ private final int hc;
/**
* Create a constraint defining a full-text search against the property values on
node within the search scope.
@@ -60,6 +62,7 @@
this.selectorName = selectorName;
this.propertyName = propertyName;
this.fullTextSearchExpression = fullTextSearchExpression;
+ this.hc = HashCode.compute(this.selectorName, this.propertyName,
this.fullTextSearchExpression);
}
/**
@@ -78,6 +81,7 @@
this.propertyName = propertyName;
this.fullTextSearchExpression = fullTextSearchExpression;
this.term = null;
+ this.hc = HashCode.compute(this.selectorName, this.propertyName,
this.fullTextSearchExpression);
}
/**
@@ -93,6 +97,7 @@
this.selectorName = selectorName;
this.propertyName = null;
this.fullTextSearchExpression = fullTextSearchExpression;
+ this.hc = HashCode.compute(this.selectorName, this.propertyName,
this.fullTextSearchExpression);
}
/**
@@ -143,6 +148,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -150,6 +165,7 @@
if (obj == this) return true;
if (obj instanceof FullTextSearch) {
FullTextSearch that = (FullTextSearch)obj;
+ if (this.hc != that.hc) return false;
if (!this.selectorName.equals(that.selectorName)) return false;
if (!ObjectUtil.isEqualWithNulls(this.propertyName, that.propertyName))
return false;
if (!this.fullTextSearchExpression.equals(that.fullTextSearchExpression))
return false;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/FullTextSearchScore.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -67,6 +67,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Join.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Join.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Join.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
*
@@ -36,6 +37,7 @@
private final Source right;
private final JoinType type;
private final JoinCondition joinCondition;
+ private final int hc;
/**
* Create a join of the left and right sources, using the supplied join condition.
The outputs of the left and right sources
@@ -58,6 +60,7 @@
this.right = right;
this.type = type;
this.joinCondition = joinCondition;
+ this.hc = HashCode.compute(this.left, this.right, this.type,
this.joinCondition);
}
/**
@@ -101,6 +104,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -108,6 +121,7 @@
if (obj == this) return true;
if (obj instanceof Join) {
Join that = (Join)obj;
+ if (this.hc != that.hc) return false;
if (!this.type.equals(that.type)) return false;
if (!this.left.equals(that.left)) return false;
if (!this.right.equals(that.right)) return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Length.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -73,6 +73,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getPropertyValue().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Limit.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Limit.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Limit.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -107,6 +107,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return rowLimit;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Literal.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -59,6 +59,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getValue().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/LowerCase.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -74,6 +74,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return operand.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NamedSelector.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -67,6 +67,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeDepth.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -67,6 +67,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeLocalName.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -66,6 +66,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodeName.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -66,6 +66,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/NodePath.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -67,6 +67,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getSelectorName().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Not.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Not.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Not.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -67,6 +67,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getConstraint().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Or.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Or.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Or.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
/**
* A constraint that evaluates to true when either of the other constraints evaluates to
true.
@@ -34,6 +35,7 @@
private final Constraint left;
private final Constraint right;
+ private final int hc;
/**
* Create a constraint that evaluates to true if either of the two supplied
constraints evaluates to true.
@@ -48,6 +50,7 @@
CheckArg.isNotNull(right, "right");
this.left = left;
this.right = right;
+ this.hc = HashCode.compute(this.left, this.right);
}
/**
@@ -81,6 +84,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -88,6 +101,7 @@
if (obj == this) return true;
if (obj instanceof Or) {
Or that = (Or)obj;
+ if (this.hc != that.hc) return false;
return this.left.equals(that.left) && this.right.equals(that.right);
}
return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Ordering.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Ordering.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Ordering.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -81,6 +81,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return operand.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyExistence.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyExistence.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyExistence.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.property.Name;
/**
@@ -34,6 +35,7 @@
public class PropertyExistence extends Constraint {
private final SelectorName selectorName;
private final Name propertyName;
+ private final int hc;
/**
* Create a constraint requiring that a property exist on a node.
@@ -47,6 +49,7 @@
CheckArg.isNotNull(propertyName, "propertyName");
this.selectorName = selectorName;
this.propertyName = propertyName;
+ this.hc = HashCode.compute(this.selectorName, this.propertyName);
}
/**
@@ -80,6 +83,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -87,6 +100,7 @@
if (obj == this) return true;
if (obj instanceof PropertyExistence) {
PropertyExistence that = (PropertyExistence)obj;
+ if (this.hc != that.hc) return false;
return this.selectorName.equals(that.selectorName) &&
this.propertyName.equals(that.propertyName);
}
return false;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/PropertyValue.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.property.Name;
/**
@@ -34,6 +35,7 @@
public class PropertyValue extends DynamicOperand {
private final SelectorName selectorName;
private final Name propertyName;
+ private final int hc;
/**
* Create a dynamic operand that evaluates to the property values of the node
identified by the selector.
@@ -48,6 +50,7 @@
CheckArg.isNotNull(propertyName, "propertyName");
this.selectorName = selectorName;
this.propertyName = propertyName;
+ this.hc = HashCode.compute(this.selectorName, this.propertyName);
}
/**
@@ -82,6 +85,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -89,6 +102,7 @@
if (obj == this) return true;
if (obj instanceof PropertyValue) {
PropertyValue that = (PropertyValue)obj;
+ if (this.hc != that.hc) return false;
return this.selectorName.equals(that.selectorName) &&
this.propertyName.equals(that.propertyName);
}
return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Query.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Query.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Query.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -29,6 +29,7 @@
import java.util.List;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
/**
@@ -43,6 +44,7 @@
private final Constraint constraint;
private final List<Column> columns;
private final boolean distinct;
+ private final int hc;
/**
* Create a new query that uses the supplied source.
@@ -57,6 +59,7 @@
this.constraint = null;
this.columns = Collections.<Column>emptyList();
this.distinct = IS_DISTINCT_DEFAULT;
+ this.hc = HashCode.compute(this.source, this.constraint, this.columns,
this.distinct);
}
/**
@@ -84,6 +87,7 @@
this.constraint = constraint;
this.columns = columns != null ? columns :
Collections.<Column>emptyList();
this.distinct = isDistinct;
+ this.hc = HashCode.compute(this.source, this.constraint, this.columns,
this.distinct);
}
/**
@@ -189,6 +193,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -196,6 +210,7 @@
if (obj == this) return true;
if (obj instanceof Query) {
Query that = (Query)obj;
+ if (this.hc != that.hc) return false;
if (this.distinct != that.distinct) return false;
if (!this.source.equals(that.source)) return false;
if (!ObjectUtil.isEqualWithNulls(this.getLimits(), that.getLimits())) return
false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNode.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNode.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNode.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.property.Path;
/**
@@ -34,6 +35,7 @@
public class SameNode extends Constraint {
private final SelectorName selectorName;
private final Path path;
+ private final int hc;
/**
* Create a constraint requiring that the node identified by the selector is
reachable by the supplied absolute path.
@@ -48,6 +50,7 @@
CheckArg.isNotNull(path, "path");
this.selectorName = selectorName;
this.path = path;
+ this.hc = HashCode.compute(this.selectorName, this.path);
}
/**
@@ -81,6 +84,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -88,6 +101,7 @@
if (obj == this) return true;
if (obj instanceof SameNode) {
SameNode that = (SameNode)obj;
+ if (this.hc != that.hc) return false;
if (!this.selectorName.equals(that.selectorName)) return false;
if (!this.path.equals(that.path)) return false;
return true;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNodeJoinCondition.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNodeJoinCondition.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SameNodeJoinCondition.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,6 +25,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
import org.jboss.dna.graph.property.Path;
@@ -37,6 +38,7 @@
private final SelectorName selector1Name;
private final SelectorName selector2Name;
private final Path selector2Path;
+ private final int hc;
/**
* Create a join condition that determines whether the node identified by the first
selector is the same as the node at the
@@ -56,6 +58,7 @@
this.selector1Name = selector1Name;
this.selector2Name = selector2Name;
this.selector2Path = selector2Path;
+ this.hc = HashCode.compute(this.selector1Name, this.selector2Name,
this.selector2Path);
}
/**
@@ -73,6 +76,7 @@
this.selector1Name = selector1Name;
this.selector2Name = selector2Name;
this.selector2Path = null;
+ this.hc = HashCode.compute(this.selector1Name, this.selector2Name,
this.selector2Path);
}
/**
@@ -115,6 +119,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -122,6 +136,7 @@
if (obj == this) return true;
if (obj instanceof SameNodeJoinCondition) {
SameNodeJoinCondition that = (SameNodeJoinCondition)obj;
+ if (this.hc != that.hc) return false;
if (!this.selector1Name.equals(that.selector1Name)) return false;
if (!this.selector2Name.equals(that.selector2Name)) return false;
if (!ObjectUtil.isEqualWithNulls(this.selector2Path, that.selector2Path))
return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Selector.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Selector.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/Selector.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -96,5 +96,4 @@
public boolean hasAlias() {
return alias != null;
}
-
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetCriteria.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetCriteria.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetCriteria.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -23,7 +23,9 @@
*/
package org.jboss.dna.graph.query.model;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
@@ -44,6 +46,14 @@
this.setOperands = setOperands;
}
+ public SetCriteria( DynamicOperand left,
+ StaticOperand... setOperands ) {
+ CheckArg.isNotNull(left, "left");
+ CheckArg.isNotNull(setOperands, "setOperands");
+ this.left = left;
+ this.setOperands = Collections.unmodifiableList(Arrays.asList(setOperands));
+ }
+
/**
* @return operand1
*/
@@ -71,6 +81,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return left.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetQuery.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetQuery.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/SetQuery.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -31,6 +31,7 @@
import java.util.Map;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.common.util.ObjectUtil;
import org.jboss.dna.graph.ExecutionContext;
@@ -101,6 +102,7 @@
private final QueryCommand right;
private final Operation operation;
private final boolean all;
+ private final int hc;
public SetQuery( QueryCommand left,
Operation operation,
@@ -114,6 +116,7 @@
this.right = right;
this.operation = operation;
this.all = all;
+ this.hc = HashCode.compute(this.left, this.right, this.operation);
}
public SetQuery( QueryCommand left,
@@ -130,6 +133,7 @@
this.right = right;
this.operation = operation;
this.all = all;
+ this.hc = HashCode.compute(this.left, this.right, this.operation);
}
/**
@@ -181,6 +185,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -188,6 +202,7 @@
if (obj == this) return true;
if (obj instanceof SetQuery) {
SetQuery that = (SetQuery)obj;
+ if (this.hc != that.hc) return false;
if (this.operation != that.operation) return false;
if (!this.left.equals(that.left)) return false;
if (!this.right.equals(that.right)) return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/model/UpperCase.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -76,6 +76,16 @@
/**
* {@inheritDoc}
*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getOperand().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/AbstractMergeSelectNodes.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/AbstractMergeSelectNodes.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/AbstractMergeSelectNodes.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -0,0 +1,113 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.optimize;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.model.Constraint;
+import org.jboss.dna.graph.query.model.SetCriteria;
+import org.jboss.dna.graph.query.plan.PlanNode;
+import org.jboss.dna.graph.query.plan.PlanNode.Property;
+import org.jboss.dna.graph.query.plan.PlanNode.Type;
+
+/**
+ * An {@link OptimizerRule optimizer rule} that merges SELECT nodes that have {@link
SetCriteria} applied to the same column on
+ * the same selector.
+ *
+ * @param <SimilarityType> the type used to compare and identify similar nodes
+ * @param <ConstraintType> the concrete type of Constraint objects that are being
merged
+ */
+@Immutable
+public abstract class AbstractMergeSelectNodes<SimilarityType, ConstraintType extends
Constraint> implements OptimizerRule {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.optimize.OptimizerRule#execute(org.jboss.dna.graph.query.QueryContext,
+ * org.jboss.dna.graph.query.plan.PlanNode, java.util.LinkedList)
+ */
+ @SuppressWarnings( "unchecked" )
+ public PlanNode execute( QueryContext context,
+ PlanNode plan,
+ LinkedList<OptimizerRule> ruleStack ) {
+ Map<SimilarityType, LinkedList<PlanNode>> mergeables = new
HashMap<SimilarityType, LinkedList<PlanNode>>();
+ for (PlanNode source : plan.findAllAtOrBelow(Type.SOURCE)) {
+ // Walk up from the SOURCE and look for all SELECT nodes ...
+ PlanNode node = source.getParent();
+ while (node != null && node.is(Type.SELECT)) {
+ Constraint constraint = node.getProperty(Property.SELECT_CRITERIA,
Constraint.class);
+ SimilarityType operand = getSimilarityKey(constraint);
+ if (operand != null) {
+ LinkedList<PlanNode> nodes = mergeables.get(operand);
+ if (nodes == null) {
+ nodes = new LinkedList<PlanNode>();
+ mergeables.put(operand, nodes);
+ }
+ nodes.addFirst(node); // So that the list is in the downward order
they appear in the plan
+ }
+ node = node.getParent();
+ }
+
+ // Merge all mergeable SELECT nodes ...
+ for (LinkedList<PlanNode> mergeable : mergeables.values()) {
+ if (mergeable.size() > 1) {
+ Iterator<PlanNode> iter = mergeable.iterator();
+ PlanNode firstSelect = iter.next();
+ Constraint constraint =
firstSelect.getProperty(Property.SELECT_CRITERIA, Constraint.class);
+ while (iter.hasNext()) {
+ PlanNode nextSelect = iter.next();
+ Constraint nextConstraint =
nextSelect.getProperty(Property.SELECT_CRITERIA, Constraint.class);
+ constraint = merge((ConstraintType)constraint,
(ConstraintType)nextConstraint);
+ nextSelect.extractFromParent();
+ }
+ firstSelect.setProperty(Property.SELECT_CRITERIA, constraint);
+ }
+ }
+ mergeables.clear();
+ }
+ return plan;
+ }
+
+ /**
+ * Obtain the similarity key that will be used to determine whether two SELECT nodes
should be merged.
+ *
+ * @param constraint the constraint from the SELECT node
+ * @return the similarity key, or null if the constraint should not be merged
+ */
+ protected abstract SimilarityType getSimilarityKey( Constraint constraint );
+
+ /**
+ * Merge the two constraints.
+ *
+ * @param firstConstraint the first constraint
+ * @param secondConstraint the second constraint
+ * @return the merged constraint
+ */
+ protected abstract Constraint merge( ConstraintType firstConstraint,
+ ConstraintType secondConstraint );
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/AbstractMergeSelectNodes.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/MergeSetCriteria.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/MergeSetCriteria.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/MergeSetCriteria.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -0,0 +1,89 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.query.optimize;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.query.model.Constraint;
+import org.jboss.dna.graph.query.model.DynamicOperand;
+import org.jboss.dna.graph.query.model.SetCriteria;
+import org.jboss.dna.graph.query.model.StaticOperand;
+
+/**
+ * An {@link OptimizerRule optimizer rule} that merges SELECT nodes that have {@link
SetCriteria} applied to the same column on
+ * the same selector.
+ */
+@Immutable
+public class MergeSetCriteria extends AbstractMergeSelectNodes<DynamicOperand,
SetCriteria> {
+
+ public static final MergeSetCriteria INSTANCE = new MergeSetCriteria();
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.optimize.AbstractMergeSelectNodes#getSimilarityKey(org.jboss.dna.graph.query.model.Constraint)
+ */
+ @Override
+ protected DynamicOperand getSimilarityKey( Constraint constraint ) {
+ if (constraint instanceof SetCriteria) {
+ // Look for the list of plan nodes for this operand ...
+ return ((SetCriteria)constraint).getLeftOperand();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.query.optimize.AbstractMergeSelectNodes#merge(org.jboss.dna.graph.query.model.Constraint,
+ * org.jboss.dna.graph.query.model.Constraint)
+ */
+ @Override
+ protected Constraint merge( SetCriteria firstConstraint,
+ SetCriteria secondConstraint ) {
+ assert
firstConstraint.getLeftOperand().equals(secondConstraint.getLeftOperand());
+ Set<StaticOperand> allOperands = new HashSet<StaticOperand>();
+ List<StaticOperand> orderedOperands = new
ArrayList<StaticOperand>(firstConstraint.getRightOperands());
+ allOperands.addAll(firstConstraint.getRightOperands());
+ for (StaticOperand second : secondConstraint.getRightOperands()) {
+ if (allOperands.add(second)) {
+ orderedOperands.add(second);
+ }
+ }
+ return new SetCriteria(firstConstraint.getLeftOperand(), orderedOperands);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/MergeSetCriteria.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushProjects.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushProjects.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushProjects.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -65,7 +65,16 @@
// Is there already a PROJECT here ?
assert parentOfProject.getChildCount() == 1; // should only have one child
...
PlanNode child = parentOfProject.getFirstChild(); // should only have one
child ...
- if (child.is(Type.PROJECT)) continue;
+ if (child.is(Type.PROJECT)) {
+ // Check to see if there is a PROJECT above the access node ...
+ PlanNode accessParent = access.getParent();
+ if (accessParent == null || accessParent.isNot(Type.PROJECT)) continue;
+ // Otherwise, the parent is a PROJECT, but there is another PROJECT above
the ACCESS node.
+ // Remove the lower PROJECT so the next code block moves the top PROJECT
down below the ACCESS node ...
+ assert accessParent.is(Type.PROJECT);
+ child.extractFromParent();
+ child = parentOfProject.getFirstChild();
+ }
// If the parent of the ACCESS node is a PROJECT, then we can simply move it
to here ...
PlanNode accessParent = access.getParent();
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushSelectCriteria.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushSelectCriteria.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/PushSelectCriteria.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -297,6 +297,7 @@
// first look for originating nodes that exactly match the required selectors
...
for (PlanNode originatingNode : originatingNodes) {
+ if (!criteriaNode.isAbove(originatingNode)) continue;
if (originatingNode.getSelectors().equals(requiredSelectors)) return
originatingNode;
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/ReplaceViews.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/ReplaceViews.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/ReplaceViews.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -99,6 +99,7 @@
// The PROJECT from the plan may actually not be needed if there
is another PROJECT above it ...
PlanNode node = viewPlan.getParent();
while (node != null) {
+ if (node.isOneOf(Type.JOIN)) break;
if (node.is(Type.PROJECT) &&
viewPlan.getSelectors().containsAll(node.getSelectors())) {
viewPlan.extractFromParent();
break;
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RewriteIdentityJoins.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -25,13 +25,16 @@
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import net.jcip.annotations.Immutable;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.ValueFactory;
import org.jboss.dna.graph.query.QueryContext;
+import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.EquiJoinCondition;
import org.jboss.dna.graph.query.model.JoinCondition;
+import org.jboss.dna.graph.query.model.SameNodeJoinCondition;
import org.jboss.dna.graph.query.model.SelectorName;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.PlanUtil;
@@ -82,55 +85,68 @@
public PlanNode execute( QueryContext context,
PlanNode plan,
LinkedList<OptimizerRule> ruleStack ) {
+ if (!context.getHints().hasJoin) return plan;
+
// For each of the JOIN nodes ...
Map<SelectorName, SelectorName> rewrittenSelectors = null;
+ int rewrittenJoins = 0;
+ int numJoins = 0;
for (PlanNode joinNode : plan.findAllAtOrBelow(Type.JOIN)) {
+ ++numJoins;
JoinCondition condition = joinNode.getProperty(Property.JOIN_CONDITION,
JoinCondition.class);
if (condition instanceof EquiJoinCondition) {
- PlanNode leftNode = joinNode.getFirstChild();
- PlanNode rightNode = joinNode.getLastChild();
+ PlanNode leftNode = joinNode.getFirstChild().findAtOrBelow(Type.SOURCE);
+ PlanNode rightNode = joinNode.getLastChild().findAtOrBelow(Type.SOURCE);
assert leftNode != null;
assert rightNode != null;
- if (leftNode.getType() == Type.SOURCE && rightNode.getType() ==
Type.SOURCE) {
- EquiJoinCondition equiJoin = (EquiJoinCondition)condition;
- // Find the names (or aliases) of the tables ...
- Schemata schemata = context.getSchemata();
- assert schemata != null;
- SelectorName leftTableName =
leftNode.getProperty(Property.SOURCE_NAME, SelectorName.class);
- SelectorName rightTableName =
rightNode.getProperty(Property.SOURCE_NAME, SelectorName.class);
- assert leftTableName != null;
- assert rightTableName != null;
- // Presumably the join condition is using at least one alias, but we
only care about the actual name ...
- if (!leftTableName.equals(rightTableName)) {
- // The join is not joining the same table, so this doesn't
meet the condition ...
- continue;
- }
- // Find the schemata columns referenced by the join condition ...
- Table table = schemata.getTable(leftTableName);
- if (table == null) {
- context.getProblems().addError(GraphI18n.tableDoesNotExist,
leftTableName);
- continue;
- }
- ValueFactory<String> stringFactory =
context.getExecutionContext().getValueFactories().getStringFactory();
- String leftColumnName =
stringFactory.create(equiJoin.getProperty1Name());
- String rightColumnName =
stringFactory.create(equiJoin.getProperty2Name());
- Schemata.Column leftColumn = table.getColumn(leftColumnName);
- Schemata.Column rightColumn = table.getColumn(rightColumnName);
- if (leftColumn == null) {
-
context.getProblems().addError(GraphI18n.columnDoesNotExistOnTable, leftColumnName,
leftTableName);
- continue;
- }
- if (rightColumn == null) {
-
context.getProblems().addError(GraphI18n.columnDoesNotExistOnTable, rightColumnName,
leftTableName);
- continue;
- }
- // Are the join columns (on both sides) keys?
- if (table.hasKey(leftColumn) && (rightColumn == leftColumn ||
table.hasKey(rightColumn))) {
- // It meets all the criteria, so rewrite this join node ...
- if (rewrittenSelectors == null) rewrittenSelectors = new
HashMap<SelectorName, SelectorName>();
- rewriteJoinNode(context, joinNode, equiJoin,
rewrittenSelectors);
- }
+ EquiJoinCondition equiJoin = (EquiJoinCondition)condition;
+ // Find the names (or aliases) of the tables ...
+ Schemata schemata = context.getSchemata();
+ assert schemata != null;
+ SelectorName leftTableName = leftNode.getProperty(Property.SOURCE_NAME,
SelectorName.class);
+ SelectorName rightTableName = rightNode.getProperty(Property.SOURCE_NAME,
SelectorName.class);
+ assert leftTableName != null;
+ assert rightTableName != null;
+ // Presumably the join condition is using at least one alias, but we only
care about the actual name ...
+ if (!leftTableName.equals(rightTableName)) {
+ // The join is not joining the same table, so this doesn't meet
the condition ...
+ continue;
}
+ // Find the schemata columns referenced by the join condition ...
+ Table table = schemata.getTable(leftTableName);
+ if (table == null) {
+ context.getProblems().addError(GraphI18n.tableDoesNotExist,
leftTableName);
+ continue;
+ }
+ ValueFactory<String> stringFactory =
context.getExecutionContext().getValueFactories().getStringFactory();
+ String leftColumnName =
stringFactory.create(equiJoin.getProperty1Name());
+ String rightColumnName =
stringFactory.create(equiJoin.getProperty2Name());
+ Schemata.Column leftColumn = table.getColumn(leftColumnName);
+ Schemata.Column rightColumn = table.getColumn(rightColumnName);
+ if (leftColumn == null) {
+ context.getProblems().addError(GraphI18n.columnDoesNotExistOnTable,
leftColumnName, leftTableName);
+ continue;
+ }
+ if (rightColumn == null) {
+ context.getProblems().addError(GraphI18n.columnDoesNotExistOnTable,
rightColumnName, leftTableName);
+ continue;
+ }
+ // Are the join columns (on both sides) keys?
+ if (table.hasKey(leftColumn) && (rightColumn == leftColumn ||
table.hasKey(rightColumn))) {
+ // It meets all the criteria, so rewrite this join node ...
+ if (rewrittenSelectors == null) rewrittenSelectors = new
HashMap<SelectorName, SelectorName>();
+ rewriteJoinNode(context, joinNode, rewrittenSelectors);
+ ++rewrittenJoins;
+ }
+ } else if (condition instanceof SameNodeJoinCondition) {
+ SameNodeJoinCondition sameNodeCondition =
(SameNodeJoinCondition)condition;
+ if
(sameNodeCondition.getSelector1Name().equals(sameNodeCondition.getSelector2Name())
+ && sameNodeCondition.getSelector2Path() == null) {
+ // It meets all the criteria, so rewrite this join node ...
+ if (rewrittenSelectors == null) rewrittenSelectors = new
HashMap<SelectorName, SelectorName>();
+ rewriteJoinNode(context, joinNode, rewrittenSelectors);
+ ++rewrittenJoins;
+ }
}
}
@@ -140,28 +156,72 @@
// this criteria, so we need to re-run this rule...
ruleStack.addFirst(this);
+ // After this rule is done as is no longer needed, we need to try to push
SELECTs and PROJECTs again ...
+ if (!(ruleStack.peekFirst() instanceof PushSelectCriteria)) {
+ // We haven't already added these, so add them now ...
+ ruleStack.addFirst(PushProjects.INSTANCE);
+ if (context.getHints().hasCriteria) {
+ ruleStack.addFirst(PushSelectCriteria.INSTANCE);
+ }
+ }
+
// Now rewrite the various portions of the plan that make use of the
now-removed selectors ...
PlanUtil.replaceReferencesToRemovedSource(context, plan,
rewrittenSelectors);
- } else {
- // There are no-untouched JOIN nodes, which means the sole JOIN node was
rewritten as a single SOURCE node
- assert plan.findAllAtOrBelow(Type.JOIN).isEmpty();
- context.getHints().hasJoin = false;
+
+ assert rewrittenJoins > 0;
+ if (rewrittenJoins == numJoins) {
+ assert plan.findAllAtOrBelow(Type.JOIN).isEmpty();
+ context.getHints().hasJoin = false;
+ }
}
return plan;
}
protected void rewriteJoinNode( QueryContext context,
PlanNode joinNode,
- EquiJoinCondition joinCondition,
Map<SelectorName, SelectorName>
rewrittenSelectors ) {
// Remove the right source node from the join node ...
- PlanNode rightSource = joinNode.getLastChild();
- rightSource.removeFromParent();
+ PlanNode rightChild = joinNode.getLastChild();
+ rightChild.removeFromParent();
+ PlanNode rightSource = rightChild.findAtOrBelow(Type.SOURCE);
// Replace the join node with the left source node ...
- PlanNode leftSource = joinNode.getFirstChild();
+ PlanNode leftChild = joinNode.getFirstChild();
joinNode.extractFromParent();
+ PlanNode leftSource = leftChild.findAtOrBelow(Type.SOURCE);
+ // Combine the right PROJECT node with that on the left ...
+ PlanNode rightProject = rightChild.findAtOrBelow(Type.PROJECT);
+ if (rightProject != null) {
+ PlanNode leftProject = leftChild.findAtOrBelow(Type.PROJECT);
+ if (leftProject != null) {
+ List<Column> leftColumns =
leftProject.getPropertyAsList(Property.PROJECT_COLUMNS, Column.class);
+ for (Column rightColumn :
rightProject.getPropertyAsList(Property.PROJECT_COLUMNS, Column.class)) {
+ if (!leftColumns.contains(rightColumn))
leftColumns.add(rightColumn);
+ }
+ } else {
+ // Just create a project on the left side ...
+ leftProject = new PlanNode(Type.PROJECT);
+ leftProject.setProperty(Property.PROJECT_COLUMNS,
rightProject.getProperty(Property.PROJECT_COLUMNS));
+ leftChild.getFirstChild().insertAsParent(leftProject);
+ }
+ }
+
+ // Accumulate any SELECT nodes from the right side and add to the left ...
+ PlanNode topRightSelect = rightChild.findAtOrBelow(Type.SELECT);
+ if (topRightSelect != null) {
+ PlanNode bottomRightSelect = topRightSelect;
+ while (true) {
+ if (bottomRightSelect.getFirstChild().isNot(Type.SELECT)) break;
+ bottomRightSelect = bottomRightSelect.getFirstChild();
+ }
+ topRightSelect.setParent(null);
+ bottomRightSelect.removeAllChildren();
+ // Place just above the left source ...
+ leftSource.getParent().addLastChild(topRightSelect);
+ leftSource.setParent(bottomRightSelect);
+ }
+
// Now record that references to the right selector name should be removed ...
SelectorName rightTableName = rightSource.getProperty(Property.SOURCE_NAME,
SelectorName.class);
SelectorName rightTableAlias = rightSource.getProperty(Property.SOURCE_ALIAS,
SelectorName.class);
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizer.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizer.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizer.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -69,8 +69,10 @@
*/
protected void populateRuleStack( LinkedList<OptimizerRule> ruleStack,
PlanHints hints ) {
+ ruleStack.addFirst(MergeSetCriteria.INSTANCE);
if (hints.hasJoin) {
ruleStack.addFirst(ChooseJoinAlgorithm.USE_ONLY_NESTED_JOIN_ALGORITHM);
+ ruleStack.addFirst(RewriteIdentityJoins.INSTANCE);
}
ruleStack.addFirst(PushProjects.INSTANCE);
if (hints.hasCriteria) {
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/CanonicalPlanner.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -70,6 +70,8 @@
* |
* PROJECT with the list of columns being SELECTed
* |
+ * GROUP if 'GROUP BY' is used
+ * |
* SELECT1
* | One or more SELECT plan nodes that each have
* SELECT2 a single non-join constraint that are then all AND-ed
@@ -127,6 +129,9 @@
// Attach criteria (on top) ...
plan = attachCriteria(context, plan, query.getConstraint());
+ // Attach groupbys (on top) ...
+ // plan = attachGrouping(context,plan,query.getGroupBy());
+
// Attach the project ...
plan = attachProject(context, plan, query.getColumns(), usedSources);
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanNode.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanNode.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanNode.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -173,6 +173,12 @@
PROJECT_COLUMNS,
/**
+ * For GROUP nodes, the ordered collection of columns used to group the result
tuples. Value is a Collection of
+ * {@link Column} objects.
+ */
+ GROUP_COLUMNS,
+
+ /**
* For SET_OPERATION nodes, the list of orderings for the results. Value is
either a Collection of {@link Ordering}
* objects or a collection of {@link SelectorName} objects (if the sorting is
being done as an input to a merge-join).
*/
@@ -363,6 +369,31 @@
}
/**
+ * Determine if the supplied node is an ancestor of this node.
+ *
+ * @param possibleAncestor the node that is to be determined if it is an ancestor
+ * @return true if the supplied node is indeed an ancestor, or false if it is not an
ancestor
+ */
+ public boolean isBelow( PlanNode possibleAncestor ) {
+ PlanNode node = this;
+ while (node != null) {
+ if (node == possibleAncestor) return true;
+ node = node.getParent();
+ }
+ return false;
+ }
+
+ /**
+ * Determine if the supplied node is a descendant of this node.
+ *
+ * @param possibleDescendant the node that is to be determined if it is a descendant
+ * @return true if the supplied node is indeed an ancestor, or false if it is not an
ancestor
+ */
+ public boolean isAbove( PlanNode possibleDescendant ) {
+ return possibleDescendant != null && possibleDescendant.isBelow(this);
+ }
+
+ /**
* Get the parent of this node.
*
* @return the parent node, or null if this node has no parent
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java 2009-10-20
16:14:27 UTC (rev 1297)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/plan/PlanUtil.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.graph.query.plan;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -489,11 +490,10 @@
List<PlanNode> potentiallyRemovableSources = new
LinkedList<PlanNode>();
do {
// Remove the view from the selectors ...
- if (node.getSelectors().contains(viewName)) {
+ if (node.getSelectors().remove(viewName)) {
switch (node.getType()) {
case PROJECT:
// Adjust the columns ...
- node.getSelectors().remove(viewName);
List<Column> columns =
node.getPropertyAsList(Property.PROJECT_COLUMNS, Column.class);
if (columns != null) {
for (int i = 0; i != columns.size(); ++i) {
@@ -529,19 +529,41 @@
node.setProperty(Property.SELECT_CRITERIA, newConstraint);
}
break;
- case SET_OPERATION:
- break;
case SOURCE:
SelectorName sourceName = node.getProperty(Property.SOURCE_NAME,
SelectorName.class);
assert sourceName.equals(sourceName); // selector name already
matches
potentiallyRemovableSources.add(node);
break;
- default:
+ case JOIN:
+ JoinCondition joinCondition =
node.getProperty(Property.JOIN_CONDITION, JoinCondition.class);
+ JoinCondition newJoinCondition = replaceViewReferences(context,
joinCondition, mappings, node);
+ node.getSelectors().clear();
+ node.setProperty(Property.JOIN_CONDITION, newJoinCondition);
+
node.addSelectors(Visitors.getSelectorsReferencedBy(newJoinCondition));
+ List<Constraint> joinConstraints =
node.getPropertyAsList(Property.JOIN_CONSTRAINTS, Constraint.class);
+ if (joinConstraints != null &&
!joinConstraints.isEmpty()) {
+ List<Constraint> newConstraints = new
ArrayList<Constraint>(joinConstraints.size());
+ for (Constraint joinConstraint : joinConstraints) {
+ newConstraint = replaceReferences(context,
joinConstraint, mappings, node);
+ newConstraints.add(newConstraint);
+
node.addSelectors(Visitors.getSelectorsReferencedBy(newConstraint));
+ }
+ node.setProperty(Property.JOIN_CONSTRAINTS, newConstraints);
+ }
break;
+ case ACCESS:
+ // Nothing to do here, as the selector names are fixed elsewhere
+ break;
+ case SORT:
+ break;
+ case GROUP:
+ // Don't yet use GROUP BY
+ case SET_OPERATION:
+ case DUP_REMOVE:
+ case LIMIT:
+ case NULL:
+ break;
}
- if (!node.getSelectors().contains(viewName)) {
- // Used to reference view, so it needs to at least reference
- }
}
// Move to the parent ...
node = node.getParent();
@@ -704,10 +726,10 @@
return operand;
}
- public static JoinCondition replaceReferences( QueryContext context,
- JoinCondition joinCondition,
- ColumnMapping mapping,
- PlanNode node ) {
+ public static JoinCondition replaceViewReferences( QueryContext context,
+ JoinCondition joinCondition,
+ ColumnMapping mapping,
+ PlanNode node ) {
if (joinCondition instanceof EquiJoinCondition) {
EquiJoinCondition condition = (EquiJoinCondition)joinCondition;
SelectorName replacement1 = condition.getSelector1Name();
@@ -749,6 +771,7 @@
if (replacement2.equals(viewName)) replacement2 = sourceName;
if (replacement1 == condition.getSelector1Name() && replacement2 ==
condition.getSelector2Name()) return condition;
node.addSelector(replacement1, replacement2);
+ if (condition.getSelector2Path() == null) return new
SameNodeJoinCondition(replacement1, replacement2);
return new SameNodeJoinCondition(replacement1, replacement2,
condition.getSelector2Path());
}
if (joinCondition instanceof ChildNodeJoinCondition) {
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/query/validate/ImmutableSchemata.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -356,7 +356,7 @@
String... columnNames ) {
CheckArg.isNotEmpty(tableName, "tableName");
CheckArg.isNotEmpty(columnNames, "columnNames");
- ImmutableTable existing = tables.get(tableName);
+ ImmutableTable existing = tables.get(new SelectorName(tableName));
if (existing == null) {
throw new
IllegalArgumentException(GraphI18n.tableDoesNotExist.text(tableName));
}
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/ReplaceViewsTest.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -24,7 +24,6 @@
package org.jboss.dna.graph.query.optimize;
import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertThat;
import java.util.Arrays;
import java.util.LinkedList;
@@ -133,15 +132,12 @@
// Execute the rule ...
PlanNode result = rule.execute(context, project, new
LinkedList<OptimizerRule>());
+ System.out.println(project);
System.out.println(result);
- assertThat(result, is(sameInstance(project)));
+ assertThat(result.isSameAs(project), is(true));
assertChildren(project, select1);
assertChildren(select1, select2);
assertChildren(select2, select3);
- assertChildren(select3, source);
- assertSameChildren(source, viewSelect);
- assertSameChildren(source.getFirstChild(), viewSource);
- assertSameChildren(source.getFirstChild().getFirstChild());
}
protected List<Column> columns( Column... columns ) {
Modified:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java
===================================================================
---
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-graph/src/test/java/org/jboss/dna/graph/query/optimize/RuleBasedOptimizerTest.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -38,12 +38,14 @@
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Comparison;
import org.jboss.dna.graph.query.model.EquiJoinCondition;
+import org.jboss.dna.graph.query.model.FullTextSearch;
import org.jboss.dna.graph.query.model.JoinType;
import org.jboss.dna.graph.query.model.Literal;
import org.jboss.dna.graph.query.model.Operator;
import org.jboss.dna.graph.query.model.PropertyValue;
import org.jboss.dna.graph.query.model.QueryCommand;
import org.jboss.dna.graph.query.model.SelectorName;
+import org.jboss.dna.graph.query.model.SetCriteria;
import org.jboss.dna.graph.query.parse.SqlQueryParser;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
import org.jboss.dna.graph.query.plan.JoinAlgorithm;
@@ -66,6 +68,7 @@
private List<Integer> ruleExecutionOrder;
private QueryContext context;
private PlanNode node;
+ private boolean print = false;
@Before
public void beforeEach() {
@@ -73,8 +76,15 @@
ImmutableSchemata.Builder builder =
ImmutableSchemata.createBuilder(execContext);
builder.addTable("t1", "c11", "c12",
"c13");
builder.addTable("t2", "c21", "c22",
"c23");
+ builder.addTable("all", "a1", "a2", "a3",
"a4", "primaryType", "mixins");
+ builder.addKey("all", "a1");
+ builder.addKey("all", "a3");
builder.addView("v1", "SELECT c11, c12 AS c2 FROM t1 WHERE c13
< CAST('3' AS LONG)");
builder.addView("v2", "SELECT t1.c11, t1.c12, t2.c23 FROM t1 JOIN
t2 ON t1.c11 = t2.c21");
+ builder.addView("type1",
+ "SELECT all.a1, all.a2 FROM all WHERE all.primaryType IN
('t1','t0') AND all.mixins IN ('t3','t4')");
+ builder.addView("type2",
+ "SELECT all.a3, all.a4 FROM all WHERE all.primaryType IN
('t2','t0') AND all.mixins IN ('t4','t5')");
Schemata schemata = builder.build();
context = new QueryContext(execContext, new PlanHints(), schemata);
@@ -282,6 +292,136 @@
assertThat(node.isSameAs(project), is(true));
}
+ @Test
+ public void shouldOptimizePlanForQueryUsingTypeView() {
+ node = optimize("SELECT type1.a1 AS a, type1.a2 AS b FROM type1 WHERE
CONTAINS(type1.a2,'something')");
+
+ // Create the expected plan ...
+ PlanNode access = new PlanNode(Type.ACCESS, selector("all"));
+ PlanNode project = new PlanNode(Type.PROJECT, access,
selector("all"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("all",
"a1", "a"), column("all", "a2", "b")));
+ PlanNode select1 = new PlanNode(Type.SELECT, project,
selector("all"));
+ select1.setProperty(Property.SELECT_CRITERIA, new
FullTextSearch(selector("all"), name("a2"), "something"));
+ PlanNode select2 = new PlanNode(Type.SELECT, select1,
selector("all"));
+ select2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("primaryType")),
+ new
Literal("t1"), new Literal("t0")));
+ PlanNode select3 = new PlanNode(Type.SELECT, select2,
selector("all"));
+ select3.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("mixins")),
+ new
Literal("t3"), new Literal("t4")));
+ PlanNode source = new PlanNode(Type.SOURCE, select3, selector("all"));
+ source.setProperty(Property.SOURCE_NAME, selector("all"));
+ source.setProperty(Property.SOURCE_COLUMNS,
context.getSchemata().getTable(selector("all")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(access), is(true));
+ }
+
+ @Test
+ public void shouldOptimizePlanForQueryJoiningMultipleTypeViewsUsingIdentityEquiJoin()
{
+ node = optimize("SELECT type1.a1 AS a, type1.a2 AS b, type2.a3 as c,
type2.a4 as d "
+ + "FROM type1 JOIN type2 ON type1.a1 = type2.a3 WHERE
CONTAINS(type1.a2,'something')");
+
+ // Create the expected plan ...
+ PlanNode access = new PlanNode(Type.ACCESS, selector("all"));
+ PlanNode project = new PlanNode(Type.PROJECT, access,
selector("all"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("all",
"a1", "a"),
+ column("all",
"a2", "b"),
+ column("all",
"a3", "c"),
+ column("all",
"a4", "d")));
+ PlanNode select1 = new PlanNode(Type.SELECT, project,
selector("all"));
+ select1.setProperty(Property.SELECT_CRITERIA, new
FullTextSearch(selector("all"), name("a2"), "something"));
+ PlanNode select2 = new PlanNode(Type.SELECT, select1,
selector("all"));
+ select2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("primaryType")),
+ new
Literal("t1"), new Literal("t0"), new Literal("t2")));
+ PlanNode select3 = new PlanNode(Type.SELECT, select2,
selector("all"));
+ select3.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("mixins")),
+ new
Literal("t3"), new Literal("t4"), new Literal("t5")));
+ PlanNode source = new PlanNode(Type.SOURCE, select3, selector("all"));
+ source.setProperty(Property.SOURCE_NAME, selector("all"));
+ source.setProperty(Property.SOURCE_COLUMNS,
context.getSchemata().getTable(selector("all")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(access), is(true));
+ }
+
+ @Test
+ public void
shouldOptimizePlanForQueryJoiningMultipleTypeViewsUsingNonIdentityEquiJoin() {
+ node = optimize("SELECT type1.a1 AS a, type1.a2 AS b, type2.a3 as c,
type2.a4 as d "
+ + "FROM type1 JOIN type2 ON type1.a2 = type2.a3 WHERE
CONTAINS(type1.a1,'something')");
+
+ // Create the expected plan ...
+ PlanNode project = new PlanNode(Type.PROJECT, selector("all"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("all",
"a1", "a"),
+ column("all",
"a2", "b"),
+ column("all",
"a3", "c"),
+ column("all",
"a4", "d")));
+ PlanNode select1 = new PlanNode(Type.SELECT, project,
selector("all"));
+ select1.setProperty(Property.SELECT_CRITERIA, new
FullTextSearch(selector("all"), name("a1"), "something"));
+ PlanNode join = new PlanNode(Type.JOIN, select1, selector("all"));
+ join.setProperty(Property.JOIN_ALGORITHM, JoinAlgorithm.NESTED_LOOP);
+ join.setProperty(Property.JOIN_TYPE, JoinType.INNER);
+ join.setProperty(Property.JOIN_CONDITION, new
EquiJoinCondition(selector("all"), name("a2"),
selector("all"), name("a3")));
+
+ PlanNode leftAccess = new PlanNode(Type.ACCESS, join,
selector("all"));
+ PlanNode leftProject = new PlanNode(Type.PROJECT, leftAccess,
selector("all"));
+ leftProject.setProperty(Property.PROJECT_COLUMNS, columns(column("all",
"a1"), column("all", "a2")));
+ PlanNode leftSelect1 = new PlanNode(Type.SELECT, leftProject,
selector("all"));
+ leftSelect1.setProperty(Property.SELECT_CRITERIA,
+ new SetCriteria(new
PropertyValue(selector("all"), name("primaryType")), new
Literal("t1"),
+ new Literal("t0")));
+ PlanNode leftSelect2 = new PlanNode(Type.SELECT, leftSelect1,
selector("all"));
+ leftSelect2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("mixins")),
+ new
Literal("t3"), new Literal("t4")));
+ PlanNode leftSource = new PlanNode(Type.SOURCE, leftSelect2,
selector("all"));
+ leftSource.setProperty(Property.SOURCE_NAME, selector("all"));
+ leftSource.setProperty(Property.SOURCE_COLUMNS,
context.getSchemata().getTable(selector("all")).getColumns());
+
+ PlanNode rightAccess = new PlanNode(Type.ACCESS, join,
selector("all"));
+ PlanNode rightProject = new PlanNode(Type.PROJECT, rightAccess,
selector("all"));
+ rightProject.setProperty(Property.PROJECT_COLUMNS,
columns(column("all", "a3"), column("all",
"a4")));
+ PlanNode rightSelect1 = new PlanNode(Type.SELECT, rightProject,
selector("all"));
+ rightSelect1.setProperty(Property.SELECT_CRITERIA,
+ new SetCriteria(new
PropertyValue(selector("all"), name("primaryType")), new
Literal("t2"),
+ new Literal("t0")));
+ PlanNode rightSelect2 = new PlanNode(Type.SELECT, rightSelect1,
selector("all"));
+ rightSelect2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("mixins")),
+ new
Literal("t4"), new Literal("t5")));
+ PlanNode rightSource = new PlanNode(Type.SOURCE, rightSelect2,
selector("all"));
+ rightSource.setProperty(Property.SOURCE_NAME, selector("all"));
+ rightSource.setProperty(Property.SOURCE_COLUMNS,
context.getSchemata().getTable(selector("all")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(project), is(true));
+ }
+
+ @Test
+ public void shouldOptimizePlanForQueryJoiningMultipleTypeViewsUsingSameNodeJoin() {
+ node = optimize("SELECT type1.a1 AS a, type1.a2 AS b, type2.a3 as c,
type2.a4 as d "
+ + "FROM type1 JOIN type2 ON ISSAMENODE(type1,type2) WHERE
CONTAINS(type1.a2,'something')");
+
+ // Create the expected plan ...
+ PlanNode access = new PlanNode(Type.ACCESS, selector("all"));
+ PlanNode project = new PlanNode(Type.PROJECT, access,
selector("all"));
+ project.setProperty(Property.PROJECT_COLUMNS, columns(column("all",
"a1", "a"),
+ column("all",
"a2", "b"),
+ column("all",
"a3", "c"),
+ column("all",
"a4", "d")));
+ PlanNode select1 = new PlanNode(Type.SELECT, project,
selector("all"));
+ select1.setProperty(Property.SELECT_CRITERIA, new
FullTextSearch(selector("all"), name("a2"), "something"));
+ PlanNode select2 = new PlanNode(Type.SELECT, select1,
selector("all"));
+ select2.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("primaryType")),
+ new
Literal("t1"), new Literal("t0"), new Literal("t2")));
+ PlanNode select3 = new PlanNode(Type.SELECT, select2,
selector("all"));
+ select3.setProperty(Property.SELECT_CRITERIA, new SetCriteria(new
PropertyValue(selector("all"), name("mixins")),
+ new
Literal("t3"), new Literal("t4"), new Literal("t5")));
+ PlanNode source = new PlanNode(Type.SOURCE, select3, selector("all"));
+ source.setProperty(Property.SOURCE_NAME, selector("all"));
+ source.setProperty(Property.SOURCE_COLUMNS,
context.getSchemata().getTable(selector("all")).getColumns());
+
+ // Compare the expected and actual plan ...
+ assertThat(node.isSameAs(access), is(true));
+ }
+
//
----------------------------------------------------------------------------------------------------------------
// Utility methods ...
//
----------------------------------------------------------------------------------------------------------------
@@ -313,9 +453,11 @@
assertThat("Problems planning query: " + sql + "\n" +
problems, problems.hasErrors(), is(false));
PlanNode optimized = new RuleBasedOptimizer().optimize(context, plan);
assertThat("Problems optimizing query: " + sql + "\n" +
problems, problems.hasErrors(), is(false));
- System.out.println();
- System.out.println(sql);
- System.out.println(optimized);
+ if (print) {
+ System.out.println();
+ System.out.println(sql);
+ System.out.println(optimized);
+ }
return optimized;
}
}
Modified:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java
===================================================================
---
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java 2009-10-20
16:14:27 UTC (rev 1297)
+++
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/xpath/XPathToQueryTranslatorTest.java 2009-10-21
17:01:35 UTC (rev 1298)
@@ -73,7 +73,7 @@
@Test
public void shouldTranslateFromXPathContainingExplicitPath() {
assertThat(xpath("/jcr:root/a"),
- isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'a' AND DEPTH(nodeSet1) = 1"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'a' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
assertThat(xpath("/jcr:root/a/b"), isSql("SELECT * FROM
__ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b'"));
assertThat(xpath("/jcr:root/a/b/c"), isSql("SELECT * FROM
__ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c'"));
assertThat(xpath("/jcr:root/a/b/c/d"), isSql("SELECT * FROM
__ALLNODES__ AS nodeSet1 WHERE PATH(nodeSet1) = '/a/b/c/d'"));
@@ -218,13 +218,13 @@
@Test
public void shouldTranslateFromXPathOfNodeWithNameUnderRoot() {
assertThat(xpath("/jcr:root/element(nodeName,*)"),
- isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
assertThat(xpath("/jcr:root/nodeName"),
- isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
assertThat(xpath("nodeName"),
- isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = 1"));
+ isSql("SELECT * FROM __ALLNODES__ AS nodeSet1 WHERE
NAME(nodeSet1) = 'nodeName' AND DEPTH(nodeSet1) = CAST(1 AS LONG)"));
}
@Test