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 ch...@apache.org on 2015/07/28 11:31:22 UTC

svn commit: r1693050 - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/ test/java/org/apache/jackrabbit/oak/plugins/index/lucene/

Author: chetanm
Date: Tue Jul 28 09:31:22 2015
New Revision: 1693050

URL: http://svn.apache.org/r1693050
Log:
OAK-3137 - Global fulltext index returning plan for pure NodeType queries

Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1693050&r1=1693049&r2=1693050&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Tue Jul 28 09:31:22 2015
@@ -315,7 +315,12 @@ class IndexPlanner {
     }
 
     private boolean canEvalPathRestrictions(IndexingRule rule) {
-        if (filter.getPathRestriction() == Filter.PathRestriction.NO_RESTRICTION){
+        //Opt out if one is looking for all children for '/' as its equivalent to
+        //NO_RESTRICTION
+        if (filter.getPathRestriction() == Filter.PathRestriction.NO_RESTRICTION
+                || (filter.getPathRestriction() == Filter.PathRestriction.ALL_CHILDREN
+                        && PathUtils.denotesRoot(filter.getPath()))
+                ){
             return false;
         }
         //If no other restrictions is provided and query is pure

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1693050&r1=1693049&r2=1693050&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java Tue Jul 28 09:31:22 2015
@@ -207,6 +207,25 @@ public class IndexPlannerTest {
     }
 
     @Test
+    public void pureNodeTypeWithEvaluatePathRestrictionEnabled() throws Exception{
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder defn = newLuceneIndexDefinition(index, "lucene",
+                of(TYPENAME_STRING));
+        defn.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
+        TestUtil.useV2(defn);
+
+        FilterImpl filter = createFilter("nt:file");
+        filter.restrictPath("/", Filter.PathRestriction.ALL_CHILDREN);
+
+        IndexNode node = createIndexNode(new IndexDefinition(root, defn.getNodeState()));
+        IndexPlanner planner = new IndexPlanner(node, "/foo", filter, Collections.<OrderEntry>emptyList());
+
+        // /jcr:root//element(*, nt:file)
+        //For queries like above Fulltext index should not return a plan
+        assertNull(planner.getPlan());
+    }
+
+    @Test
     public void purePropertyIndexAndNodeTypeRestriction() throws Exception{
         NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo"), "async");
         defn.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1693050&r1=1693049&r2=1693050&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Tue Jul 28 09:31:22 2015
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.oak.api.Blo
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.Result;
 import org.apache.jackrabbit.oak.api.ResultRow;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
@@ -65,6 +66,7 @@ import org.apache.jackrabbit.oak.query.A
 import org.apache.jackrabbit.oak.spi.commit.Observer;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.util.ISO8601;
 import org.junit.After;
 import org.junit.Rule;
@@ -75,6 +77,7 @@ import static com.google.common.collect.
 import static java.util.Arrays.asList;
 import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
 import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
+import static org.apache.jackrabbit.oak.api.QueryEngine.NO_BINDINGS;
 import static org.apache.jackrabbit.oak.api.QueryEngine.NO_MAPPINGS;
 import static org.apache.jackrabbit.oak.api.Type.NAMES;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
@@ -225,13 +228,38 @@ public class LucenePropertyIndexTest ext
     }
 
     @Test
+    public void indexSelectionFulltextVsNodeType() throws Exception {
+        Tree nodeTypeIdx = root.getTree("/oak:index/nodetype");
+        nodeTypeIdx.setProperty(PropertyStates.createProperty(DECLARING_NODE_TYPES, of("nt:file"), NAMES));
+        nodeTypeIdx.setProperty(IndexConstants.REINDEX_PROPERTY_NAME, true);
+        //Set the cost to highest to ensure that if Lucene index opts in then
+        //it always wins. In actual case Lucene index should not participate
+        //in such queries
+        nodeTypeIdx.setProperty(IndexConstants.ENTRY_COUNT_PROPERTY_NAME, Long.MAX_VALUE);
+
+        Tree luceneIndex = createFullTextIndex(root.getTree("/"), "lucene");
+
+        Tree test = root.getTree("/").addChild("test");
+        setNodeType(test, "nt:file");
+
+        setNodeType(test.addChild("a"), "nt:file");
+        setNodeType(test.addChild("b"), "nt:file");
+        setNodeType(test.addChild("c"), "nt:base");
+        root.commit();
+
+        String propabQuery = "/jcr:root//element(*, nt:file)";
+        System.out.println(explainXpath(propabQuery));
+        assertThat(explainXpath(propabQuery), containsString("nodeType"));
+    }
+
+    @Test
     public void declaringNodeTypeSameProp() throws Exception {
         createIndex("test1", of("propa"));
 
         Tree indexWithType = createIndex("test2", of("propa"));
         indexWithType.setProperty(PropertyStates
-            .createProperty(DECLARING_NODE_TYPES, of("nt:unstructured"),
-                Type.STRINGS));
+                .createProperty(DECLARING_NODE_TYPES, of("nt:unstructured"),
+                        Type.STRINGS));
 
         Tree test = root.getTree("/").addChild("test");
         test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
@@ -406,8 +434,8 @@ public class LucenePropertyIndexTest ext
         System.out.println(explain);
         String luceneQuery = explain.substring(0, explain.indexOf('\n'));
         assertEquals("[nt:unstructured] as [content] /* lucene:test1(/oak:index/test1) " +
-                "+(tags:Products:A tags:Products:A/B) " +
-                "+(tags:DocTypes:A tags:DocTypes:B tags:DocTypes:C tags:ProblemType:A)",
+                        "+(tags:Products:A tags:Products:A/B) " +
+                        "+(tags:DocTypes:A tags:DocTypes:B tags:DocTypes:C tags:ProblemType:A)",
                 luceneQuery);
     }
 
@@ -695,7 +723,7 @@ public class LucenePropertyIndexTest ext
         assertQuery("select [jcr:path] from [nt:base] where propa like 'hum%'",
                 asList("/test/a", "/test/c"));
         assertQuery("select [jcr:path] from [nt:base] where propa like '%ty'",
-            asList("/test/a", "/test/b"));
+                asList("/test/a", "/test/b"));
         assertQuery("select [jcr:path] from [nt:base] where propa like '%ump%'",
             asList("/test/a", "/test/b", "/test/c"));
     }
@@ -1018,8 +1046,8 @@ public class LucenePropertyIndexTest ext
 
         // Add the path of property added as timestamp string in the sorted list
         assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]",
-            Lists.newArrayList(Iterables.concat(Lists.newArrayList("/test/n0"),
-                getSortedPaths(tuples, OrderDirection.ASC))));
+                Lists.newArrayList(Iterables.concat(Lists.newArrayList("/test/n0"),
+                        getSortedPaths(tuples, OrderDirection.ASC))));
         // Append the path of property added as timestamp string to the sorted list
         assertOrderedQuery(
                 "select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC", Lists
@@ -1562,6 +1590,13 @@ public class LucenePropertyIndexTest ext
         return executeQuery(explain, "JCR-SQL2").get(0);
     }
 
+    private String explainXpath(String query) throws ParseException {
+        String explain = "explain " + query;
+        Result result = executeQuery(explain, "xpath", NO_BINDINGS);
+        ResultRow row = Iterables.getOnlyElement(result.getRows());
+        return row.getValue("plan").getValue(Type.STRING);
+    }
+
     private Tree createIndex(String name, Set<String> propNames) throws CommitFailedException {
         Tree index = root.getTree("/");
         return createIndex(index, name, propNames);
@@ -1579,6 +1614,27 @@ public class LucenePropertyIndexTest ext
         return index.getChild(INDEX_DEFINITIONS_NAME).getChild(name);
     }
 
+    private Tree createFullTextIndex(Tree index, String name) throws CommitFailedException {
+        Tree def = index.addChild(INDEX_DEFINITIONS_NAME).addChild(name);
+        def.setProperty(JcrConstants.JCR_PRIMARYTYPE, INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+        def.setProperty(TYPE_PROPERTY_NAME, LuceneIndexConstants.TYPE_LUCENE);
+        def.setProperty(REINDEX_PROPERTY_NAME, true);
+        def.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
+        def.setProperty(LuceneIndexConstants.COMPAT_MODE, IndexFormatVersion.V2.getVersion());
+
+        Tree props = def.addChild(LuceneIndexConstants.INDEX_RULES)
+                .addChild("nt:base")
+                .addChild(LuceneIndexConstants.PROP_NODE)
+                .addChild("allProps");
+
+        props.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        props.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, true);
+        props.setProperty(LuceneIndexConstants.PROP_USE_IN_EXCERPT, true);
+        props.setProperty(LuceneIndexConstants.PROP_NAME, LuceneIndexConstants.REGEX_ALL_PROPS);
+        props.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true);
+        return def;
+    }
+
     private static String dt(String date) throws ParseException {
         return String.format("CAST ('%s' AS DATE)",ISO8601.format(createCal(date)));
     }