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 th...@apache.org on 2014/04/30 16:30:21 UTC

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

Author: thomasm
Date: Wed Apr 30 14:30:20 2014
New Revision: 1591314

URL: http://svn.apache.org/r1591314
Log:
OAK-1778 Ordered index: explain plan not implemented

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.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/QueryIndex.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.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/plugins/index/property/OrderedPropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java?rev=1591314&r1=1591313&r2=1591314&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java Wed Apr 30 14:30:20 2014
@@ -49,7 +49,7 @@ public class OrderedPropertyIndex extend
     }
 
     @Override
-    PropertyIndexLookup getLookup(NodeState root) {
+    OrderedPropertyIndexLookup getLookup(NodeState root) {
         return new OrderedPropertyIndexLookup(root);
     }
 
@@ -172,10 +172,70 @@ public class OrderedPropertyIndex extend
     }
 
     @Override
-    public String getPlanDescription(IndexPlan plan) {
-        LOG.debug("getPlanDescription() - plan: {}", plan);
-        LOG.error("Not implemented yet");
-        throw new UnsupportedOperationException("Not implemented yet.");
+    public String getPlanDescription(IndexPlan plan, NodeState root) {
+        LOG.debug("getPlanDescription({}, {})", plan, root);
+        StringBuilder buff = new StringBuilder("ordered");
+        OrderedPropertyIndexLookup lookup = getLookup(root);
+        Filter filter = plan.getFilter();
+        int depth = 1;
+        boolean found = false;
+        for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
+            String propertyName = PathUtils.getName(pr.propertyName);
+            if (!lookup.isIndexed(propertyName, "/", filter)) {
+                continue;
+            }
+            String operation = null;
+            PropertyValue value = null;       
+            // TODO support pr.list
+            if (pr.first == null && pr.last == null) {
+                // open query: [property] is not null
+                operation = "is not null";
+            } else if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
+                       && pr.lastIncluding) {
+                // [property]=[value]
+                operation = "=";
+                value = pr.first;
+            } else if (pr.first != null && !pr.first.equals(pr.last)) {
+                // '>' & '>=' use cases
+                if (lookup.isAscending(root, propertyName, filter)) {
+                    value = pr.first;
+                    operation = pr.firstIncluding ? ">=" : ">";
+                }
+            } else if (pr.last != null && !pr.last.equals(pr.first)) {
+                // '<' & '<='
+                if (!lookup.isAscending(root, propertyName, filter)) {
+                    value = pr.last;
+                    operation = pr.lastIncluding ? "<=" : "<";
+                }
+            }
+            if (operation != null) {
+                buff.append(' ').append(propertyName).append(' ').
+                        append(operation).append(' ').append(value);
+            } else {
+                continue;
+            }
+            // stop with the first property that is indexed
+            found = true;
+            break;
+        }
+        List<OrderEntry> sortOrder = plan.getSortOrder();
+        if (!found && sortOrder != null && !sortOrder.isEmpty()) {
+            // we could be here if we have a query where the ORDER BY makes us play it.
+            for (OrderEntry oe : sortOrder) {
+                String propertyName = PathUtils.getName(oe.getPropertyName());
+                if (!lookup.isIndexed(propertyName, "/", null)) {
+                    continue;
+                }
+                depth = PathUtils.getDepth(oe.getPropertyName());
+                buff.append(" order by ").append(propertyName);
+                // stop with the first property that is indexed
+                break;
+            }
+        }        
+        if (depth > 1) {
+            buff.append(" ancestor ").append(depth - 1);
+        }       
+        return buff.toString();
     }
 
     @Override

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=1591314&r1=1591313&r2=1591314&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 Wed Apr 30 14:30:20 2014
@@ -327,8 +327,15 @@ public class SelectorImpl extends Source
         StringBuilder buff = new StringBuilder();
         buff.append(toString());
         buff.append(" /* ");
-        if (getIndex() != null) {
-            buff.append(getIndex().getPlan(createFilter(true), rootState));
+        QueryIndex index = getIndex();
+        if (index != null) {
+            if (index instanceof AdvancedQueryIndex) {
+                AdvancedQueryIndex adv = (AdvancedQueryIndex) index;
+                IndexPlan p = plan.getIndexPlan();
+                buff.append(adv.getPlanDescription(p, rootState));
+            } else {
+                buff.append(index.getPlan(createFilter(true), rootState));
+            }
         } else {
             buff.append("no-index");
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java?rev=1591314&r1=1591313&r2=1591314&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java Wed Apr 30 14:30:20 2014
@@ -153,9 +153,10 @@ public interface QueryIndex {
          * Get the query plan description (for logging purposes).
          * 
          * @param plan the index plan
+         * @param rootState root state of the current repository snapshot
          * @return the query plan description
          */
-        String getPlanDescription(IndexPlan plan);
+        String getPlanDescription(IndexPlan plan, NodeState root);
 
         /**
          * Start a query. The filter and sort order of the index plan is to be

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java?rev=1591314&r1=1591313&r2=1591314&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java Wed Apr 30 14:30:20 2014
@@ -49,7 +49,7 @@ public class OrderedIndexCostTest extend
      */
     private static class AlwaysIndexedOrderedPropertyIndex extends OrderedPropertyIndex {
         @Override
-        PropertyIndexLookup getLookup(NodeState root) {
+        AlwaysIndexedLookup getLookup(NodeState root) {
             return new AlwaysIndexedLookup(root);
         }
 

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=1591314&r1=1591313&r2=1591314&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 Wed Apr 30 14:30:20 2014
@@ -81,7 +81,7 @@ public class QueryTest extends AbstractR
         // disable the nodetype index
         Node nodeTypeIndex = root.getNode("oak:index").getNode("nodetype");
         nodeTypeIndex.setProperty("declaringNodeTypes", new String[] {
-        }, PropertyType.NAME);
+            }, PropertyType.NAME);
 
         // add 10 nodes
         Node test = root.addNode("test");
@@ -111,11 +111,26 @@ public class QueryTest extends AbstractR
         assertEquals("/test/test9, /test/test8, /test/test7, /test/test6, /test/test5, /test/test4, /test/test3, /test/test2, /test/test1, /test/test0", 
                 buff.toString());
         
-        // TODO
-        // r = session.getWorkspace().getQueryManager()
-        //         .createQuery("explain " + query, "xpath").execute();
-        // RowIterator rit = r.getRows();
-        // assertEquals("", rit.nextRow().getValue("plan").getString());
+        RowIterator rit;
+        
+        r = session.getWorkspace().getQueryManager()
+                .createQuery("explain " + query, "xpath").execute();
+        rit = r.getRows();
+        assertEquals("[nt:base] as [a] /* ordered order by lastMod ancestor 1 " + 
+                "where ([a].[jcr:primaryType] = cast('oak:Unstructured' as string)) " + 
+                "and (isdescendantnode([a], [/test])) */", rit.nextRow().getValue("plan").getString());
+
+        query = "/jcr:root/test//*[@jcr:primaryType='oak:Unstructured' " + 
+                "and  content/@lastMod > '2001-02-01']";
+        r = session.getWorkspace().getQueryManager()
+                .createQuery("explain " + query, "xpath").execute();
+        rit = r.getRows();
+        assertEquals("[nt:base] as [a] /* ordered lastMod > 2001-02-01 " + 
+                "where (([a].[jcr:primaryType] = cast('oak:Unstructured' as string)) " + 
+                "and ([a].[content/lastMod] > cast('2001-02-01' as string))) " + 
+                "and (isdescendantnode([a], [/test])) */", 
+                rit.nextRow().getValue("plan").getString());
+        
     }
     
     @Test