jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r1437366 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/ast/ main/java/org/apache/jackrabbit/oak/query/index/ test/java/org/apache/jackrabbit/oak/query/ test/res...
Date Wed, 23 Jan 2013 12:36:24 GMT
Author: thomasm
Date: Wed Jan 23 12:36:23 2013
New Revision: 1437366

URL: http://svn.apache.org/viewvc?rev=1437366&view=rev
Log:
OAK-579 Query: for joins, sometimes no or the wrong index is used

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.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/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
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/JsopUtil.java
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Wed Jan 23 12:36:23 2013
@@ -308,7 +308,7 @@ public class Query {
         prepare();
         Iterator<ResultRowImpl> it;
         if (explain) {
-            String plan = source.getPlan(rootState);
+            String plan = getPlan();
             columns = new ColumnImpl[] { new ColumnImpl("explain", "plan", "plan")};
             ResultRowImpl r = new ResultRowImpl(this,
                     new String[0], 
@@ -317,7 +317,7 @@ public class Query {
             it = Arrays.asList(r).iterator();
         } else {
             if (LOG.isDebugEnabled()) {
-                LOG.debug("plan: " + source.getPlan(rootState));
+                LOG.debug("plan: " + getPlan());
             }
             if (orderings == null) {
                 // can apply limit and offset directly
@@ -437,6 +437,15 @@ public class Query {
         }
         return comp;
     }
+    
+    /**
+     * Get the query plan. The query must already be prepared.
+     * 
+     * @return the query plan
+     */
+    private String getPlan() {
+        return source.getPlan(rootState);
+    }
 
     void prepare() {
         if (prepared) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
Wed Jan 23 12:36:23 2013
@@ -176,11 +176,14 @@ public abstract class QueryEngineImpl im
                 best = index;
             }
         }
-        if (best == null) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("no indexes found - using TraversingIndex; indexProvider: " + indexProvider);
-            }
-            best = new TraversingIndex();
+        QueryIndex index = new TraversingIndex();
+        double cost = index.getCost(filter, rootState);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("cost for " + index.getIndexName() + " is " + cost);
+        }
+        if (cost < bestCost) {
+            bestCost = cost;
+            best = index;
         }
         return best;
     }

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -66,12 +66,22 @@ public class ChildNodeJoinConditionImpl 
     public void restrict(FilterImpl f) {
         if (f.getSelector() == parentSelector) {
             String c = childSelector.currentPath();
+            if (c == null && f.isPreparing() && childSelector.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                c = KNOWN_PATH;
+            }
             if (c != null) {
                 f.restrictPath(PathUtils.getParentPath(c), Filter.PathRestriction.EXACT);
             }
         }
         if (f.getSelector() == childSelector) {
             String p = parentSelector.currentPath();
+            if (p == null && f.isPreparing() && parentSelector.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                p = KNOWN_PATH;
+            }
             if (p != null) {
                 f.restrictPath(p, Filter.PathRestriction.DIRECT_CHILDREN);
             }

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -66,12 +66,22 @@ public class DescendantNodeJoinCondition
     public void restrict(FilterImpl f) {
         if (f.getSelector() == ancestorSelector) {
             String d = descendantSelector.currentPath();
+            if (d == null && f.isPreparing() && descendantSelector.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                d = KNOWN_PATH;
+            }
             if (d != null) {
                 f.restrictPath(PathUtils.getParentPath(d), Filter.PathRestriction.PARENT);
             }
         }
         if (f.getSelector() == descendantSelector) {
             String a = ancestorSelector.currentPath();
+            if (a == null && f.isPreparing() && ancestorSelector.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                a = KNOWN_PATH;
+            }
             if (a != null) {
                 f.restrictPath(a, Filter.PathRestriction.DIRECT_CHILDREN);
             }

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -97,21 +97,35 @@ public class EquiJoinConditionImpl exten
     public void restrict(FilterImpl f) {
         if (f.getSelector() == selector1) {
             PropertyValue p2 = selector2.currentProperty(property2Name);
+            if (p2 == null && f.isPreparing() && selector2.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                p2 = PropertyValues.newString(KNOWN_VALUE);
+            }
             if (p2 != null) {
-                if (!p2.isArray()) {
+                if (p2.isArray()) {
                     // TODO support join on multi-valued properties
-                    f.restrictProperty(property1Name, Operator.EQUAL, p2);
+                    p2 = null;
                 }
             }
+            // always set the condition, even if unkown ( -> is not null)
+            f.restrictProperty(property1Name, Operator.EQUAL, p2);
         }
         if (f.getSelector() == selector2) {
             PropertyValue p1 = selector1.currentProperty(property1Name);
+            if (p1 == null && f.isPreparing() && selector1.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                p1 = PropertyValues.newString(KNOWN_VALUE);
+            }
             if (p1 != null) {
-                if (!p1.isArray()) {
+                if (p1.isArray()) {
                     // TODO support join on multi-valued properties
-                    f.restrictProperty(property2Name, Operator.EQUAL, p1);
+                    p1 = null;
                 }
             }
+            // always set the condition, even if unkown ( -> is not null)
+            f.restrictProperty(property2Name, Operator.EQUAL, p1);
         }
     }
 

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -19,11 +19,36 @@ import org.apache.jackrabbit.oak.query.i
  * The base class for join conditions.
  */
 public abstract class JoinConditionImpl extends AstElement {
+    
+    /**
+     * A path with 6 elements, which is the expected average for a join.
+     */
+    protected static final String KNOWN_PATH = "/path/from/the/join/selector";
 
-    public abstract boolean evaluate();
+    protected static final String KNOWN_VALUE = "valueFromTheJoinSelector";
 
+    /**
+     * Evaluate the result using the currently set values.
+     * 
+     * @return true if the constraint matches
+     */
+    public abstract boolean evaluate();
+    
+    /**
+     * Apply the condition to the filter, further restricting the filter if
+     * possible. This may also verify the data types are compatible, and that
+     * paths are valid.
+     * 
+     * @param f the filter
+     */
     public abstract void restrict(FilterImpl f);
 
-    public abstract void restrictPushDown(SelectorImpl selectorImpl);
+    /**
+     * Push as much of the condition down to this selector, further restricting
+     * the selector condition if possible.
+     * 
+     * @param s the selector
+     */
+    public abstract void restrictPushDown(SelectorImpl s);
 
 }

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -60,8 +60,15 @@ public class JoinImpl extends SourceImpl
 
     @Override
     public String getPlan(NodeState rootState) {
-        return left.getPlan(rootState) + ' ' + joinType +
-                " " + right.getPlan(rootState) + " on " + joinCondition;
+        StringBuilder buff = new StringBuilder();
+        buff.append(left.getPlan(rootState)).
+            append(' ').
+            append(joinType).
+            append(' ').
+            append(right.getPlan(rootState)).
+            append(" on ").
+            append(joinCondition);
+        return buff.toString();
     }
 
     @Override

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -81,6 +81,11 @@ public class SameNodeJoinConditionImpl e
     public void restrict(FilterImpl f) {
         if (f.getSelector() == selector1) {
             String p2 = selector2.currentPath();
+            if (p2 == null && f.isPreparing() && selector2.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                p2 = KNOWN_PATH;
+            }
             if (p2 != null) {
                 if (selector2Path.equals(".")) {
                     f.restrictPath(p2, Filter.PathRestriction.EXACT);
@@ -93,6 +98,11 @@ public class SameNodeJoinConditionImpl e
         }
         if (f.getSelector() == selector2) {
             String p1 = selector1.currentPath();
+            if (p1 == null && f.isPreparing() && selector1.isPrepared())
{
+                // during the prepare phase, if the selector is already
+                // prepared, then we would know the value
+                p1 = KNOWN_PATH;
+            }
             if (p1 != null) {
                 if (selector2Path.equals(".")) {
                     f.restrictPath(p1, Filter.PathRestriction.EXACT);

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -95,6 +95,9 @@ public class SelectorImpl extends Source
         return quote(nodeTypeName) + " as " + quote(selectorName);
     }
 
+    public boolean isPrepared() {
+        return index != null;
+    }
 
     @Override
     public void prepare() {
@@ -106,19 +109,19 @@ public class SelectorImpl extends Source
                 c.restrictPushDown(this);
             }
         }
-        index = query.getBestIndex(createFilter());
+        index = query.getBestIndex(createFilter(true));
     }
 
     @Override
     public void execute(NodeState rootState) {
-        cursor = index.query(createFilter(), rootState);
+        cursor = index.query(createFilter(false), rootState);
     }
 
     @Override
     public String getPlan(NodeState rootState) {
         StringBuilder buff = new StringBuilder();
         buff.append(toString());
-        buff.append(" /* ").append(index.getPlan(createFilter(), rootState));
+        buff.append(" /* ").append(index.getPlan(createFilter(true), rootState));
         if (selectorCondition != null) {
             buff.append(" where ").append(selectorCondition);
         }
@@ -126,8 +129,15 @@ public class SelectorImpl extends Source
         return buff.toString();
     }
 
-    private Filter createFilter() {
+    /**
+     * Create the filter condition for planning or execution.
+     * 
+     * @param preparing whether a filter for the prepare phase should be made 
+     * @return the filter
+     */
+    private Filter createFilter(boolean preparing) {
         FilterImpl f = new FilterImpl(this, query.getStatement());
+        f.setPreparing(preparing);
         validateNodeType(nodeTypeName);
         f.setNodeType(nodeTypeName);
         if (joinCondition != null) {

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=1437366&r1=1437365&r2=1437366&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 Jan 23 12:36:23 2013
@@ -141,8 +141,8 @@ public abstract class SourceImpl extends
     public abstract String getPlan(NodeState rootState);
 
     /**
-     * Prepare executing the query. This method will decide which index to use.
-     *
+     * Prepare executing the query (recursively). This method will decide which
+     * index to use.
      */
     public abstract void prepare();
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
Wed Jan 23 12:36:23 2013
@@ -75,6 +75,11 @@ public class FilterImpl implements Filte
      * Only return distinct values.
      */
     private boolean distinct;
+    
+    /**
+     * Set during the prepare phase of a query.
+     */
+    private boolean preparing;
 
     // TODO support "order by"
 
@@ -82,6 +87,14 @@ public class FilterImpl implements Filte
         this.selector = selector;
         this.queryStatement = queryStatement;
     }
+    
+    public void setPreparing(boolean preparing) {
+        this.preparing = preparing;
+    }
+    
+    public boolean isPreparing() {
+        return preparing;
+    }
 
     /**
      * Get the path.

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/JsopUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/JsopUtil.java?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/JsopUtil.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/JsopUtil.java
Wed Jan 23 12:36:23 2013
@@ -176,9 +176,9 @@ public class JsopUtil {
                     String value = TypeCodes.decodeName(split, jsonString);
                     if (type == PropertyType.BINARY) {
                         throw new UnsupportedOperationException();
-                    } else if(type == PropertyType.DOUBLE) {
+                    } else if (type == PropertyType.DOUBLE) {
                         values.add(Conversions.convert(value).toDouble());
-                    } else if(type == PropertyType.DECIMAL) {
+                    } else if (type == PropertyType.DECIMAL) {
                         values.add(Conversions.convert(value).toDecimal());
                     } else {
                         values.add(value);

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt
Wed Jan 23 12:36:23 2013
@@ -34,7 +34,7 @@ explain select * from [nt:base] where pr
 [nt:base] as [nt:base] /* traverse "//*" where property([nt:base].[id], 'reference') = cast('123'
as reference) */
 
 explain select b.[jcr:path] as [jcr:path], b.[jcr:score] as [jcr:score], b.* from [nt:base]
as a inner join [nt:base] as b on ischildnode(a, b) where name(a) = 'yes' and isdescendantnode(a,
'/test') and b.[x] is not null
-[nt:base] as [a] /* traverse "/test//*" where (name([a]) = cast('yes' as string)) and (isdescendantnode([a],
[/test])) */ inner join [nt:base] as [b] /* traverse "//*" where [b].[x] is not null */ on
ischildnode([a], [b])
+[nt:base] as [a] /* traverse "/test//*" where (name([a]) = cast('yes' as string)) and (isdescendantnode([a],
[/test])) */ inner join [nt:base] as [b] /* traverse "/path/from/the/join" where [b].[x] is
not null */ on ischildnode([a], [b])
 
 select * from [nt:base] where property([*], 'REFERENCE') = CAST('123' AS REFERENCE)
 /test/a
@@ -105,7 +105,7 @@ explain select * from [nt:base] as p inn
 [nt:base] as [p] /* traverse "//*" where [p].[id] is not null */ inner join [nt:base] as
[c] /* traverse "//*" where [c].[p] is not null */ on [p].[id] = [c].[p]
 
 explain select * from [nt:base] as p inner join [nt:base] as p2 on issamenode(p2, p) where
p.[jcr:path] = '/parents'
-[nt:base] as [p] /* traverse "//*" where [p].[jcr:path] = cast('/parents' as string) */ inner
join [nt:base] as [p2] /* traverse "//*" */ on issamenode([p2], [p], [.])
+[nt:base] as [p] /* traverse "//*" where [p].[jcr:path] = cast('/parents' as string) */ inner
join [nt:base] as [p2] /* traverse "/path/from/the/join/selector" */ on issamenode([p2], [p],
[.])
 
 explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
 [nt:base] as [p] /* traverse "//*" where [p].[id] is not null */ inner join [nt:base] as
[c] /* traverse "//*" where [c].[p] is not null */ on [p].[id] = [c].[p]

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt?rev=1437366&r1=1437365&r2=1437366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
Wed Jan 23 12:36:23 2013
@@ -31,6 +31,12 @@ explain select * from [nt:base] where [j
 explain select * from [nt:base] where [jcr:uuid] is not null
 [nt:base] as [nt:base] /* p2 jcr:uuid where [nt:base].[jcr:uuid] is not null */
 
+explain select * from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null and b.[jcr:uuid] is not null
+[nt:base] as [a] /* p2 jcr:uuid where [a].[jcr:uuid] is not null */ inner join [nt:base]
as [b] /* p2 jcr:uuid where [b].[jcr:uuid] is not null */ on isdescendantnode([b], [a])
+
+explain select * from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null and b.[x] is not null
+[nt:base] as [a] /* p2 jcr:uuid where [a].[jcr:uuid] is not null */ inner join [nt:base]
as [b] /* traverse "/path/from/the/join/selector/*" where [b].[x] is not null */ on isdescendantnode([b],
[a])
+
 commit / + "test": { "jcr:uuid": "xyz", "a": { "jcr:uuid": "123" } }
 
 select * from [nt:base] where [jcr:uuid] is not null



Mime
View raw message