jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1392927 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/lucene/ main/java/org/apache/jackrabbit/oak/plugins/unique/ main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/a...
Date Tue, 02 Oct 2012 14:30:47 GMT
Author: jukka
Date: Tue Oct  2 14:30:46 2012
New Revision: 1392927

URL: http://svn.apache.org/viewvc?rev=1392927&view=rev
Log:
OAK-237: QueryEngine can't handle node type hierarchies

Initial implementation developed together with Alex P.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
    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/ast/JoinImpl.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/main/java/org/apache/jackrabbit/oak/query/index/PrefixContentIndex.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
Tue Oct  2 14:30:46 2012
@@ -28,7 +28,17 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.annotation.CheckForNull;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeIterator;
+import javax.jcr.nodetype.NodeTypeManager;
+
+import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.ReadOnlyTree;
+import org.apache.jackrabbit.oak.plugins.type.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.type.ReadOnlyNodeTypeManager;
 import org.apache.jackrabbit.oak.query.index.IndexRowImpl;
 import org.apache.jackrabbit.oak.spi.query.Cursor;
 import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -83,8 +93,8 @@ public class LuceneIndex implements Quer
     }
 
     @Override
-    public String getPlan(Filter filter) {
-        return getQuery(filter).toString();
+    public String getPlan(Filter filter, NodeState root) {
+        return getQuery(filter, root).toString();
     }
 
     @Override
@@ -110,7 +120,7 @@ public class LuceneIndex implements Quer
                     IndexSearcher searcher = new IndexSearcher(reader);
                     Collection<String> paths = new ArrayList<String>();
 
-                    Query query = getQuery(filter);
+                    Query query = getQuery(filter, root);
                     if (query != null) {
                         TopDocs docs = searcher
                                 .search(query, Integer.MAX_VALUE);
@@ -139,9 +149,16 @@ public class LuceneIndex implements Quer
         }
     }
 
-    private static Query getQuery(Filter filter) {
+    private static Query getQuery(Filter filter, NodeState root) {
         List<Query> qs = new ArrayList<Query>();
 
+        try {
+            addNodeTypeConstraints(qs, filter.getNodeType(), root);
+        } catch (RepositoryException e) {
+            throw new RuntimeException(
+                    "Unable to process node type constraints", e);
+        }
+
         String path = filter.getPath();
         switch (filter.getPathRestriction()) {
         case ALL_CHILDREN:
@@ -206,6 +223,46 @@ public class LuceneIndex implements Quer
         }
     }
 
+    private static void addNodeTypeConstraints(
+            List<Query> qs, String name, NodeState root)
+            throws RepositoryException {
+        if (NodeTypeConstants.NT_BASE.equals(name)) {
+            return; // shortcut
+        }
+        NodeState system = root.getChildNode(NodeTypeConstants.JCR_SYSTEM);
+        if (system == null) {
+            return;
+        }
+        final NodeState types =
+                system.getChildNode(NodeTypeConstants.JCR_NODE_TYPES);
+        if (types == null) {
+            return;
+        }
+
+        NodeTypeManager manager = new ReadOnlyNodeTypeManager() {
+            @Override @CheckForNull
+            protected Tree getTypes() {
+                return new ReadOnlyTree(types);
+            }
+        };
+
+        BooleanQuery bq = new BooleanQuery();
+        NodeType type = manager.getNodeType(name);
+        bq.add(createNodeTypeQuery(type), Occur.SHOULD);
+        NodeTypeIterator iterator = type.getSubtypes();
+        while (iterator.hasNext()) {
+            bq.add(createNodeTypeQuery(iterator.nextNodeType()), Occur.SHOULD);
+        }
+    }
+
+    private static Query createNodeTypeQuery(NodeType type) {
+        String name = NodeTypeConstants.JCR_PRIMARYTYPE;
+        if (type.isMixin()) {
+            name = NodeTypeConstants.JCR_MIXINTYPES;
+        }
+        return new TermQuery(new Term(name, type.getName()));
+    }
+
     /**
      * A cursor over the resulting paths.
      */

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
Tue Oct  2 14:30:46 2012
@@ -56,7 +56,7 @@ public class UniqueIndex implements Quer
     }
 
     @Override
-    public String getPlan(Filter filter) {
+    public String getPlan(Filter filter, NodeState root) {
         return "jcr:uuid";
     }
 

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=1392927&r1=1392926&r2=1392927&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
Tue Oct  2 14:30:46 2012
@@ -311,7 +311,7 @@ public class Query {
         prepare();
         Iterator<ResultRowImpl> it;
         if (explain) {
-            String plan = source.getPlan();
+            String plan = source.getPlan(root);
             columns = new ColumnImpl[] { new ColumnImpl("explain", "plan", "plan")};
             ResultRowImpl r = new ResultRowImpl(this,
                     new String[0],

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=1392927&r1=1392926&r2=1392927&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
Tue Oct  2 14:30:46 2012
@@ -58,9 +58,9 @@ public class JoinImpl extends SourceImpl
     }
 
     @Override
-    public String getPlan() {
-        return left.getPlan() + ' ' + joinType +
-                " " + right.getPlan() + " on " + joinCondition;
+    public String getPlan(NodeState root) {
+        return left.getPlan(root) + ' ' + joinType +
+                " " + right.getPlan(root) + " on " + joinCondition;
     }
 
     @Override

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=1392927&r1=1392926&r2=1392927&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
Tue Oct  2 14:30:46 2012
@@ -18,11 +18,20 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
-import org.apache.jackrabbit.JcrConstants;
+import java.util.Set;
+
+import javax.annotation.CheckForNull;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeIterator;
+import javax.jcr.nodetype.NodeTypeManager;
+
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.plugins.memory.SinglePropertyState;
+import org.apache.jackrabbit.oak.plugins.type.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.type.ReadOnlyNodeTypeManager;
 import org.apache.jackrabbit.oak.query.Query;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.Cursor;
@@ -31,15 +40,13 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
+import com.google.common.collect.ImmutableSet;
+
 /**
  * A selector within a query.
  */
 public class SelectorImpl extends SourceImpl {
 
-    private static final String JCR_PRIMARY_TYPE = "jcr:primaryType";
-
-    private static final String TYPE_BASE = "nt:base";
-
     // TODO possibly support using multiple indexes (using index intersection / index merge)
     protected QueryIndex index;
 
@@ -93,10 +100,10 @@ public class SelectorImpl extends Source
     }
 
     @Override
-    public String getPlan() {
+    public String getPlan(NodeState root) {
         StringBuilder buff = new StringBuilder();
         buff.append(toString());
-        buff.append(" /* ").append(index.getPlan(createFilter()));
+        buff.append(" /* ").append(index.getPlan(createFilter(), root));
         if (selectorCondition != null) {
             buff.append(" where ").append(selectorCondition);
         }
@@ -122,9 +129,16 @@ public class SelectorImpl extends Source
 
     @Override
     public boolean next() {
-        while (true) {
-            if (!nextNode()) {
-                return false;
+        while (cursor != null && cursor.next()) {
+            scanCount++;
+            Tree tree = getTree(cursor.currentRow().getPath());
+            if (tree == null) {
+                continue;
+            }
+            if (nodeTypeName != null
+                    && !nodeTypeName.equals(NodeTypeConstants.NT_BASE)
+                    && !evaluateTypeMatch(tree)) {
+                continue;
             }
             if (selectorCondition != null && !selectorCondition.evaluate()) {
                 continue;
@@ -134,42 +148,62 @@ public class SelectorImpl extends Source
             }
             return true;
         }
+        return false;
     }
 
-    private boolean nextNode() {
-        if (cursor == null) {
-            return false;
-        }
-        scanCount++;
-        while (true) {
-            boolean result = cursor.next();
-            if (!result) {
-                return false;
-            }
-            if (nodeTypeName.equals(TYPE_BASE)) {
-                return true;
-            }
-            Tree tree = getTree(cursor.currentRow().getPath());
-            if (tree == null) {
-                return false;
-            }
-            PropertyState p = tree.getProperty(JCR_PRIMARY_TYPE);
-            if (p == null) {
+    private boolean evaluateTypeMatch(Tree tree) {
+        Set<String> primary =
+                getStrings(tree, NodeTypeConstants.JCR_PRIMARYTYPE);
+        Set<String> mixins =
+                getStrings(tree, NodeTypeConstants.JCR_MIXINTYPES);
+
+        // TODO: Should retrieve matching node types only once per query
+        // execution instead of again and again for each return row
+        NodeTypeManager manager = new ReadOnlyNodeTypeManager() {
+            @Override @CheckForNull
+            protected Tree getTypes() {
+                return getTree(NodeTypeConstants.NODE_TYPES_PATH);
+            }
+        };
+
+        try {
+            NodeType type = manager.getNodeType(nodeTypeName);
+            if (evaluateTypeMatch(type, primary, mixins)) {
                 return true;
             }
-            CoreValue v = p.getValue();
-            // TODO node type matching
-            if (nodeTypeName.equals(v.getString())) {
-                return true;
-            }
-            PropertyState m = tree.getProperty(JcrConstants.JCR_MIXINTYPES);
-            if (m != null) {
-                for (CoreValue value : m.getValues()) {
-                    if (nodeTypeName.equals(value.getString())) {
-                        return true;
-                    }
+            NodeTypeIterator iterator = type.getSubtypes();
+            while (iterator.hasNext()) {
+                type = iterator.nextNodeType();
+                if (evaluateTypeMatch(type, primary, mixins)) {
+                    return true;
                 }
             }
+        } catch (RepositoryException e) {
+            throw new RuntimeException(
+                    "Unable to evaluate node type constraints", e);
+        }
+
+        return false;
+    }
+
+    private Set<String> getStrings(Tree tree, String name) {
+        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+        PropertyState property = tree.getProperty(name);
+        if (property != null) {
+            for (CoreValue value : property.getValues()) {
+                builder.add(value.getString());
+            }
+        }
+        return builder.build();
+    }
+
+    private boolean evaluateTypeMatch(
+            NodeType type, Set<String> primary, Set<String> mixins) {
+        String name = type.getName();
+        if (type.isMixin()) {
+            return mixins.contains(name);
+        } else {
+            return primary.contains(name);
         }
     }
 

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=1392927&r1=1392926&r2=1392927&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
Tue Oct  2 14:30:46 2012
@@ -129,7 +129,7 @@ public abstract class SourceImpl extends
      *
      * @return the query plan
      */
-    public abstract String getPlan();
+    public abstract String getPlan(NodeState root);
 
     /**
      * Prepare executing the query. This method will decide which index to use.

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=1392927&r1=1392926&r2=1392927&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
Tue Oct  2 14:30:46 2012
@@ -96,6 +96,7 @@ public class FilterImpl implements Filte
         this.path = path;
     }
 
+    @Override
     public String getNodeType() {
         return nodeType;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PrefixContentIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PrefixContentIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PrefixContentIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PrefixContentIndex.java
Tue Oct  2 14:30:46 2012
@@ -74,7 +74,7 @@ public class PrefixContentIndex implemen
     }
 
     @Override
-    public String getPlan(Filter filter) {
+    public String getPlan(Filter filter, NodeState root) {
         Filter.PropertyRestriction restriction = getPropertyTypeRestriction(filter);
         if (restriction == null) {
             throw new IllegalArgumentException("No restriction for *");

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
Tue Oct  2 14:30:46 2012
@@ -56,7 +56,7 @@ public class PropertyContentIndex implem
     }
 
     @Override
-    public String getPlan(Filter filter) {
+    public String getPlan(Filter filter, NodeState root) {
         String propertyName = index.getPropertyName();
         Filter.PropertyRestriction restriction = filter.getPropertyRestriction(propertyName);
         return "propertyIndex \"" + restriction.propertyName + " " + restriction.toString()
+ '"';

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
Tue Oct  2 14:30:46 2012
@@ -49,7 +49,7 @@ public class TraversingIndex implements 
     }
 
     @Override
-    public String getPlan(Filter filter) {
+    public String getPlan(Filter filter, NodeState root) {
         String p = filter.getPath();
         String r = filter.getPathRestriction().toString();
         if (PathUtils.denotesRoot(p)) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
Tue Oct  2 14:30:46 2012
@@ -64,6 +64,8 @@ public interface Filter {
      */
     String getPath();
 
+    String getNodeType();
+
     /**
      * A restriction for a property.
      */

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
Tue Oct  2 14:30:46 2012
@@ -55,7 +55,7 @@ public interface QueryIndex {
      * Start a query.
      *
      * @param filter the filter
-     * @param root root state of the given revision
+     * @param root root state of the current repository snapshot
      * @return a cursor to iterate over the result
      */
     Cursor query(Filter filter, NodeState root);
@@ -64,9 +64,10 @@ public interface QueryIndex {
      * Get the query plan for the given filter.
      *
      * @param filter the filter
+     * @param root root state of the current repository snapshot
      * @return the query plan
      */
-    String getPlan(Filter filter);
+    String getPlan(Filter filter, NodeState root);
 
     /**
      * Get the unique index name.

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt?rev=1392927&r1=1392926&r2=1392927&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt
Tue Oct  2 14:30:46 2012
@@ -27,52 +27,52 @@ commit / + "parents": { "p0": {"id": "0"
 commit / + "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": {"p": "2"}, "c4": {"p":
"3"}}
 
 measure select * from [nt:base] as c right outer join [nt:base] as p on p.id = c.p where
p.id is not null and not isdescendantnode(p, '/jcr:system')
-c, 630
-p, 210
+c, 627
+p, 209
 query, 4
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 4
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null and c.p is null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 1
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null and c.p is not null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 3
 
 measure select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
-c, 630
-p, 210
+c, 627
+p, 209
 query, 3
 
 measure select * from [nt:base] as c right outer join [nt:base] as p on p.id = c.p where
p.id is not null and not isdescendantnode(p, '/jcr:system')
-c, 630
-p, 210
+c, 627
+p, 209
 query, 4
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 4
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null and c.p is null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 1
 
 measure select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id
is not null and c.p is not null
-c, 630
-p, 210
+c, 627
+p, 209
 query, 3
 
 measure select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
-c, 630
-p, 210
+c, 627
+p, 209
 query, 3
 



Mime
View raw message