Author: catholicon
Date: Thu Nov  2 21:18:47 2017
New Revision: 1814107

URL: http://svn.apache.org/viewvc?rev=1814107&view=rev
Log:
OAK-6902: Cost estimation for path tranformable queries is incorrect

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

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=1814107&r1=1814106&r2=1814107&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
 Thu Nov  2 21:18:47 2017
@@ -58,6 +58,7 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.JcrConstants.NT_BASE;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getAncestorPath;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getDepth;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
 import static org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import static org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
@@ -745,7 +746,11 @@ class IndexPlanner {
         IndexStatistics indexStatistics = indexNode.getIndexStatistics();
         int minNumDocs = indexStatistics.numDocs();
         for (Map.Entry<String, PropertyDefinition> propDef : 
propDefns.entrySet()) {
-            int docCntForField = 
indexStatistics.getDocCountFor(propDef.getKey());
+            String key = propDef.getKey();
+            if (result.relPropMapping.containsKey(key)) {
+                key = getName(key);
+            }
+            int docCntForField = indexStatistics.getDocCountFor(key);
             if (docCntForField == -1) {
                 continue;
             }

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=1814107&r1=1814106&r2=1814107&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
 Thu Nov  2 21:18:47 2017
@@ -1664,6 +1664,61 @@ public class IndexPlannerTest {
             IndexStatistics.failReadingFieldJcrTitle = false;
         }
     }
+
+    @Test
+    public void costForPathTransformation() throws Exception {
+        IndexStatistics.failReadingFieldJcrTitle = true;
+        String indexPath = "/test";
+        IndexDefinitionBuilder idxBuilder = new 
IndexDefinitionBuilder(child(builder, indexPath));
+        idxBuilder.indexRule("nt:base").property("foo").propertyIndex();
+        idxBuilder.indexRule("nt:base").property("foo1").propertyIndex();
+        idxBuilder.indexRule("nt:base").property("foo2").propertyIndex();
+        Tree fooPD = 
idxBuilder.getBuilderTree().getChild("indexRules").getChild("nt:base")
+                .getChild("properties").getChild("foo2");
+        fooPD.setProperty(PROP_FUNCTION, "lower([foo])");
+        NodeState defn = idxBuilder.build();
+
+        long numOfDocs = 100;
+
+        IndexDefinition idxDefn = new IndexDefinition(root, defn, indexPath);
+        IndexNode node = createIndexNode(idxDefn, 100);
+
+        FilterImpl filter = createFilter("nt:base");
+        filter.restrictProperty("a/foo", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        IndexPlanner planner = new IndexPlanner(node, indexPath, filter, 
Collections.emptyList());
+        QueryIndex.IndexPlan plan = planner.getPlan();
+
+        assertEquals(numOfDocs, plan.getEstimatedEntryCount());
+
+        filter = createFilter("nt:base");
+        filter.restrictProperty("a/foo", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        filter.restrictProperty("foo1", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        planner = new IndexPlanner(node, indexPath, filter, 
Collections.emptyList());
+        plan = planner.getPlan();
+
+        // there is no doc with foo1
+        assertEquals(0, plan.getEstimatedEntryCount());
+
+        filter = createFilter("nt:base");
+        filter.restrictProperty("foo", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        filter.restrictProperty("a/foo1", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        planner = new IndexPlanner(node, indexPath, filter, 
Collections.emptyList());
+        plan = planner.getPlan();
+
+        //Because path transormation comes into play only when direct prop 
defs don't match
+        assertEquals(numOfDocs, plan.getEstimatedEntryCount());
+
+        filter = createFilter("nt:base");
+        filter.restrictProperty("a/foo", Operator.EQUAL, 
PropertyValues.newString("bar"));
+        filter.restrictProperty(convertToPolishNotation("lower([foo])"), 
Operator.EQUAL,
+                PropertyValues.newString("foo1"));
+        planner = new IndexPlanner(node, indexPath, filter, 
Collections.emptyList());
+        plan = planner.getPlan();
+
+        // there is no doc with lower([foo])
+        assertEquals(0, plan.getEstimatedEntryCount());
+
+    }
     //------ END - Cost via doc count per field plan tests
 
 


Reply via email to