Author: thomasm
Date: Thu Oct 27 11:56:45 2016
New Revision: 1766810

URL: http://svn.apache.org/viewvc?rev=1766810&view=rev
Log:
OAK-5018 Warn traversal queries: false positives

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1766810&r1=1766809&r2=1766810&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
 Thu Oct 27 11:56:45 2016
@@ -1033,7 +1033,23 @@ public class QueryImpl implements Query
                 bestPlan = indexPlan;
             }
         }
-        if (bestIndex == null) {
+        boolean potentiallySlowTraversalQuery = bestIndex == null;
+        if (traversalEnabled) {
+            TraversingIndex traversal = new TraversingIndex();
+            double cost = traversal.getCost(filter, rootState);
+            if (LOG.isDebugEnabled()) {
+                logDebug("cost for " + traversal.getIndexName() + " is " + 
cost);
+            }
+            if (cost < bestCost || bestCost == Double.POSITIVE_INFINITY) {
+                bestCost = cost;
+                bestPlan = null;
+                bestIndex = traversal;
+                if (potentiallySlowTraversalQuery) {
+                    potentiallySlowTraversalQuery = 
traversal.isPotentiallySlow(filter, rootState);
+                }
+            }
+        }
+        if (potentiallySlowTraversalQuery) {
             QueryOptions.Traversal traversal = queryOptions.traversal;
             if (traversal == Traversal.DEFAULT) {
                 // use the (configured) default
@@ -1054,18 +1070,6 @@ public class QueryImpl implements Query
                 throw new IllegalArgumentException(message);
             }
         }
-        if (traversalEnabled) {
-            QueryIndex traversal = new TraversingIndex();
-            double cost = traversal.getCost(filter, rootState);
-            if (LOG.isDebugEnabled()) {
-                logDebug("cost for " + traversal.getIndexName() + " is " + 
cost);
-            }
-            if (cost < bestCost || bestCost == Double.POSITIVE_INFINITY) {
-                bestCost = cost;
-                bestPlan = null;
-                bestIndex = traversal;
-            }
-        }
         return new SelectorExecutionPlan(filter.getSelector(), bestIndex, 
bestPlan, bestCost);
     }
     

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=1766810&r1=1766809&r2=1766810&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
 Thu Oct 27 11:56:45 2016
@@ -42,6 +42,32 @@ public class TraversingIndex implements
     public Cursor query(Filter filter, NodeState rootState) {
         return Cursors.newTraversingCursor(filter, rootState);
     }
+    
+    public boolean isPotentiallySlow(Filter filter, NodeState rootState) {
+        if (filter.getFullTextConstraint() != null) {
+            // not an appropriate index for full-text search
+            return true;
+        }
+        if (filter.containsNativeConstraint()) {
+            // not an appropriate index for native search
+            return true;
+        }
+        if (filter.isAlwaysFalse()) {
+            return false;
+        }
+        PathRestriction restriction = filter.getPathRestriction();
+        switch (restriction) {
+        case EXACT:
+        case PARENT:
+        case DIRECT_CHILDREN:
+            return false;
+        case NO_RESTRICTION:
+        case ALL_CHILDREN:
+            return true;
+        default:
+            throw new IllegalArgumentException("Unknown restriction: " + 
restriction);
+        }
+    }
 
     @Override
     public double getCost(Filter filter, NodeState rootState) {

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java?rev=1766810&r1=1766809&r2=1766810&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
 Thu Oct 27 11:56:45 2016
@@ -94,6 +94,13 @@ public class QueryTest extends AbstractR
                 Query.JCR_SQL2).execute();
         qm.createQuery("select * from [nt:base] option(traversal warn)", 
                 Query.JCR_SQL2).execute();
+        // the following is not really traversal, it is just listing child 
nodes:
+        qm.createQuery("/jcr:root/*[@test] option(traversal fail)", 
+                "xpath").execute();
+        // the following is not really traversal; it is just one node:
+        qm.createQuery("/jcr:root/oak:index[@test] option(traversal fail)", 
+                "xpath").execute();
+
     }    
     
     @Test


Reply via email to