You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by al...@apache.org on 2013/05/07 15:51:59 UTC

svn commit: r1479909 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/index/property/ main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/ast/ main/java/org/apache/jackrabbit/oak/spi/...

Author: alexparvulescu
Date: Tue May  7 13:51:58 2013
New Revision: 1479909

URL: http://svn.apache.org/r1479909
Log:
OAK-812 QueryEngine support for multiple indices (tests)
 - found a small bug in the property index editor
 - added a protected flag to prevent the query engine to fallback to node traversal during the tests

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.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/SelectorImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java Tue May  7 13:51:58 2013
@@ -154,7 +154,7 @@ class PropertyIndexEditor implements Ind
         }
         List<PropertyIndexUpdate> filtered = new ArrayList<PropertyIndexUpdate>();
         for (PropertyIndexUpdate pi : indexes) {
-            if (node == null || pi.matchesNodeType(node)) {
+            if (node == null || pi.matchesNodeType(node, getPath())) {
                 filtered.add(pi);
             }
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java Tue May  7 13:51:58 2013
@@ -173,7 +173,10 @@ class PropertyIndexUpdate {
         }
     }
 
-    public boolean matchesNodeType(NodeBuilder node) {
+    public boolean matchesNodeType(NodeBuilder node, String path) {
+        if (!path.startsWith(this.path)) {
+            return false;
+        }
         if (primaryTypes == null
                 || primaryTypes.contains(node.getName(JCR_PRIMARYTYPE))) {
             return true;

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=1479909&r1=1479908&r2=1479909&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 Tue May  7 13:51:58 2013
@@ -21,6 +21,7 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
 
 import java.text.ParseException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -154,13 +155,28 @@ public abstract class QueryEngineImpl im
         return q.executeQuery();
     }
 
+    /**
+     * testing purposes only
+     */
+    private boolean traversalFallback = true;
+
+    protected void setTravesalFallback(boolean traversal) {
+        this.traversalFallback = traversal;
+    }
+
     public QueryIndex getBestIndex(Query query, NodeState rootState, Filter filter) {
         QueryIndex best = null;
         if (LOG.isDebugEnabled()) {
             LOG.debug("cost using filter " + filter);
         }
+        List<QueryIndex> indexes = new ArrayList<QueryIndex>(
+                indexProvider.getQueryIndexes(rootState));
+        if (traversalFallback) {
+            indexes.add(new TraversingIndex());
+        }
+
         double bestCost = Double.POSITIVE_INFINITY;
-        for (QueryIndex index : getIndexes(rootState)) {
+        for (QueryIndex index : indexes) {
             double cost = index.getCost(filter, rootState);
             if (LOG.isDebugEnabled()) {
                 LOG.debug("cost for " + index.getIndexName() + " is " + cost);
@@ -170,20 +186,7 @@ public abstract class QueryEngineImpl im
                 best = index;
             }
         }
-        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;
     }
 
-    private List<? extends QueryIndex> getIndexes(NodeState rootState) {
-        return indexProvider.getQueryIndexes(rootState);
-    }
-
 }

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=1479909&r1=1479908&r2=1479909&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 May  7 13:51:58 2013
@@ -32,6 +32,7 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_PRIMARY_SUBTYPES;
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_SUPERTYPES;
 
+import java.util.ArrayList;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
@@ -43,6 +44,7 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.query.Query;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Cursors;
 import org.apache.jackrabbit.oak.spi.query.Filter;
 import org.apache.jackrabbit.oak.spi.query.IndexRow;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
@@ -160,14 +162,23 @@ public class SelectorImpl extends Source
 
     @Override
     public void execute(NodeState rootState) {
-        cursor = index.query(createFilter(false), rootState);
+        if (index != null) {
+            cursor = index.query(createFilter(false), rootState);
+        } else {
+            cursor = Cursors.newPathCursor(new ArrayList<String>());
+        }
     }
 
     @Override
     public String getPlan(NodeState rootState) {
         StringBuilder buff = new StringBuilder();
         buff.append(toString());
-        buff.append(" /* ").append(index.getPlan(createFilter(true), rootState));
+        buff.append(" /* ");
+        if (index != null) {
+            buff.append(index.getPlan(createFilter(true), rootState));
+        } else {
+            buff.append("no-index");
+        }
         if (selectorCondition != null) {
             buff.append(" where ").append(selectorCondition);
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java Tue May  7 13:51:58 2013
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
 import org.apache.jackrabbit.oak.query.index.IndexRowImpl;
-import org.apache.jackrabbit.oak.query.index.TraversingIndex;
 import org.apache.jackrabbit.oak.spi.query.Filter.PathRestriction;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -190,7 +189,7 @@ public class Cursors {
      */
     private static class TraversingCursor extends AbstractCursor {
 
-        private static final Logger LOG = LoggerFactory.getLogger(TraversingIndex.class);
+        private static final Logger LOG = LoggerFactory.getLogger(TraversingCursor.class);
 
         private final Filter filter;
 

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java?rev=1479909&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java Tue May  7 13:51:58 2013
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.index.property;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getOrCreateOakIndex;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.query.Query;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.query.QueryEngineImpl;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+public class MultipleIndicesTest extends AbstractQueryTest {
+
+    @Override
+    protected ContentRepository createRepository() {
+        return new Oak()
+                .with(new InitialContent())
+                .with(new RepositoryInitializer() {
+                    @Override
+                    public NodeState initialize(NodeState state) {
+                        NodeBuilder root = state.builder();
+                        createIndexDefinition(getOrCreateOakIndex(root), "pid",
+                                true, false, ImmutableList.of("pid"), null);
+                        createIndexDefinition(
+                                getOrCreateOakIndex(root.child("content")),
+                                "pid", true, false, ImmutableList.of("pid"),
+                                null);
+                        return root.getNodeState();
+                    }
+                }).with(new OpenSecurityProvider())
+                .with(new PropertyIndexProvider())
+                .with(new PropertyIndexEditorProvider())
+                .createContentRepository();
+    }
+
+    @Test
+    public void query() throws Exception {
+
+        Tree t = root.getTree("/");
+        t.setProperty("pid", "foo");
+        t.addChild("a").setProperty("pid", "foo");
+        t.addChild("b").setProperty("pid", "bar");
+        t.addChild("c").setProperty("pid", "foo");
+        t.addChild("d").setProperty("cid", "foo");
+
+        Tree content = t.addChild("content");
+        content.addChild("x").setProperty("pid", "foo");
+        content.addChild("y").setProperty("pid", "baz");
+        content.addChild("z").setProperty("pid", "bar");
+        root.commit();
+
+        setTravesalFallback(false);
+        assertQuery("select [jcr:path] from [nt:base] where [cid] = 'foo'",
+                new ArrayList<String>());
+
+        assertQuery("select [jcr:path] from [nt:base] where [pid] = 'foo'",
+                ImmutableList.of("/", "/a", "/c", "/content/x"));
+
+        assertQuery("select [jcr:path] from [nt:base] where [pid] = 'bar'",
+                ImmutableList.of("/b", "/content/z"));
+
+        assertQuery("select [jcr:path] from [nt:base] where [pid] = 'baz'",
+                ImmutableList.of("/content/y"));
+        setTravesalFallback(true);
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java Tue May  7 13:51:58 2013
@@ -68,12 +68,9 @@ public class RelativePathTest extends Ab
         t.addChild("c").addChild("x").setProperty("myProp", "foo");
         t.setProperty("myProp", "foo");
         root.commit();
-        List<String> paths = executeQuery(
-                "select [jcr:path] from [nt:base] where [n/myProp] is not null",
-                Query.JCR_SQL2);
-        assertEquals(2, paths.size());
-        assertTrue(paths.contains("/a"));
-        assertTrue(paths.contains("/b"));
+        setTravesalFallback(false);
+        assertQuery("select [jcr:path] from [nt:base] where [n/myProp] is not null",
+                ImmutableList.of("/a", "/b"));
 
         List<String> lines = executeQuery(
                 "explain select [jcr:path] from [nt:base] where [n/myProp] is not null",
@@ -82,10 +79,9 @@ public class RelativePathTest extends Ab
         // make sure it used the property index
         assertTrue(lines.get(0).contains("property myProp"));
 
-        paths = executeQuery(
+        assertQuery(
                 "select [jcr:path] from [nt:base] where [n/myProp] = 'foo'",
-                Query.JCR_SQL2);
-        assertEquals(1, paths.size());
-        assertTrue(paths.contains("/a"));
+                ImmutableList.of("/a"));
+        setTravesalFallback(false);
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java Tue May  7 13:51:58 2013
@@ -45,6 +45,8 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -225,6 +227,19 @@ public abstract class AbstractQueryTest 
         return lines;
     }
 
+    protected List<String> assertQuery(String sql, List<String> expected) {
+        List<String> paths = executeQuery(sql, SQL2);
+        assertEquals(expected.size(), paths.size());
+        for (String p : expected) {
+            assertTrue(paths.contains(p));
+        }
+        return paths;
+    }
+
+    protected void setTravesalFallback(boolean traversal) {
+        ((QueryEngineImpl) qe).setTravesalFallback(traversal);
+    }
+
     protected static String readRow(ResultRow row) {
         StringBuilder buff = new StringBuilder();
         PropertyValue[] values = row.getValues();