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