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 ju...@apache.org on 2014/07/15 22:14:40 UTC

svn commit: r1610835 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/ oak-jcr/src/test/java...

Author: jukka
Date: Tue Jul 15 20:14:40 2014
New Revision: 1610835

URL: http://svn.apache.org/r1610835
Log:
OAK-1965: Support for constraints like: foo = 'X' OR bar = 'Y'

Make the per-selector constraints available to index implementations

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.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/query/index/FilterImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.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/ast/AndImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java?rev=1610835&r1=1610834&r2=1610835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java Tue Jul 15 20:14:40 2014
@@ -40,7 +40,7 @@ public class AndImpl extends ConstraintI
     private final List<ConstraintImpl> constraints;
 
     AndImpl(List<ConstraintImpl> constraints) {
-        checkArgument(constraints.size() > 1);
+        checkArgument(!constraints.isEmpty());
         this.constraints = constraints;
     }
 
@@ -153,14 +153,18 @@ public class AndImpl extends ConstraintI
 
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder();
-        for (ConstraintImpl constraint : constraints) {
-            if (builder.length() > 0) {
-                builder.append(" and ");
+        if (constraints.size() == 1) {
+            return constraints.iterator().next().toString();
+        } else {
+            StringBuilder builder = new StringBuilder();
+            for (ConstraintImpl constraint : constraints) {
+                if (builder.length() > 0) {
+                    builder.append(" and ");
+                }
+                builder.append(protect(constraint));
             }
-            builder.append(protect(constraint));
+            return builder.toString();
         }
-        return builder.toString();
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java?rev=1610835&r1=1610834&r2=1610835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java Tue Jul 15 20:14:40 2014
@@ -45,7 +45,7 @@ public class OrImpl extends ConstraintIm
     private final List<ConstraintImpl> constraints;
 
     OrImpl(List<ConstraintImpl> constraints) {
-        checkArgument(constraints.size() > 1);
+        checkArgument(!constraints.isEmpty());
         this.constraints = constraints;
     }
 

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=1610835&r1=1610834&r2=1610835&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 Tue Jul 15 20:14:40 2014
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Sets.newHashSet;
 import static org.apache.jackrabbit.JcrConstants.JCR_ISMIXIN;
 import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
@@ -33,6 +34,7 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.REP_SUPERTYPES;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
@@ -141,14 +143,14 @@ public class SelectorImpl extends Source
             new ArrayList<JoinConditionImpl>();
 
     /**
-     * The selector condition can be evaluated when the given selector is
+     * The selector constraints can be evaluated when the given selector is
      * evaluated. For example, for the query
      * "select * from nt:base a inner join nt:base b where a.x = 1 and b.y = 2",
      * the condition "a.x = 1" can be evaluated when evaluating selector a. The
      * other part of the condition can't be evaluated until b is available.
-     * This field is set during the prepare phase.
+     * These constraints are collected during the prepare phase.
      */
-    private ConstraintImpl selectorCondition;
+    private final List<ConstraintImpl> selectorConstraints = newArrayList();
 
     private Cursor cursor;
     private IndexRow currentRow;
@@ -239,7 +241,7 @@ public class SelectorImpl extends Source
     @Override
     public void unprepare() {
         plan = null;
-        selectorCondition = null;
+        selectorConstraints.clear();
         isParent = false;
         joinCondition = null;
         allJoinConditions.clear();
@@ -339,8 +341,8 @@ public class SelectorImpl extends Source
         } else {
             buff.append("no-index");
         }
-        if (selectorCondition != null) {
-            buff.append(" where ").append(selectorCondition);
+        if (!selectorConstraints.isEmpty()) {
+            buff.append(" where ").append(new AndImpl(selectorConstraints).toString());
         }
         buff.append(" */");
         return buff.toString();
@@ -384,8 +386,8 @@ public class SelectorImpl extends Source
             FullTextExpression ft = queryConstraint.getFullTextConstraint(this);
             f.setFullTextConstraint(ft);
         }
-        if (selectorCondition != null) {
-            selectorCondition.restrict(f);
+        for (ConstraintImpl constraint : selectorConstraints) {
+            constraint.restrict(f);
         }
 
         return f;
@@ -421,22 +423,30 @@ public class SelectorImpl extends Source
                     continue;
                 }
             }
-            if (!matchesAllTypes && !evaluateTypeMatch()) {
-                continue;
-            }
-            if (selectorCondition != null && !selectorCondition.evaluate()) {
-                continue;
-            }
-            if (joinCondition != null && !joinCondition.evaluate()) {
-                continue;
+            if (evaluateCurrentRow()) {
+                return true;
             }
-            return true;
         }
         cursor = null;
         currentRow = null;
         return false;
     }
 
+    private boolean evaluateCurrentRow() {
+        if (!matchesAllTypes && !evaluateTypeMatch()) {
+            return false;
+        }
+        for (ConstraintImpl constraint : selectorConstraints) {
+            if (!constraint.evaluate()) {
+                return false;
+            }
+        }
+        if (joinCondition != null && !joinCondition.evaluate()) {
+            return false;
+        }
+        return true;
+    }
+
     private boolean evaluateTypeMatch() {
         Tree tree = getTree(currentRow.getPath());
         if (tree == null || !tree.exists()) {
@@ -674,13 +684,13 @@ public class SelectorImpl extends Source
     }
 
     public void restrictSelector(ConstraintImpl constraint) {
-        if (selectorCondition == null) {
-            selectorCondition = constraint;
-        } else {
-            selectorCondition = new AndImpl(selectorCondition, constraint);
-        }
+        selectorConstraints.add(constraint);
     }
-    
+
+    public List<ConstraintImpl> getSelectorConstraints() {
+        return selectorConstraints;
+    }
+
     @Override
     public boolean equals(Object other) {
         if (this == other) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1610835&r1=1610834&r2=1610835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java Tue Jul 15 20:14:40 2014
@@ -207,6 +207,7 @@ public class FilterImpl implements Filte
         return alwaysFalse;
     }
 
+    @Override
     public SelectorImpl getSelector() {
         return selector;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java?rev=1610835&r1=1610834&r2=1610835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java Tue Jul 15 20:14:40 2014
@@ -28,6 +28,7 @@ import javax.jcr.PropertyType;
 
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
 
 /**
@@ -44,6 +45,13 @@ import org.apache.jackrabbit.oak.query.f
 public interface Filter {
 
     /**
+     * Get the selector associated with this filter.
+     *
+     * @return selector
+     */
+    SelectorImpl getSelector();
+
+    /**
      * Get the list of property restrictions, if any.
      *
      * @return the conditions (an empty collection if not used)

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java?rev=1610835&r1=1610834&r2=1610835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java Tue Jul 15 20:14:40 2014
@@ -124,10 +124,10 @@ public class QueryPlanTest extends Abstr
         String plan = it.nextRow().getValue("plan").getString();
         // System.out.println("plan: " + plan);
         // should not use the index on "jcr:uuid"
-        assertEquals("[nt:base] as [a] /* property notNull " + 
-                "where (([a].[notNull] is not null) " +
-                "and ([a].[equals] = 1)) " +
-                "and (isdescendantnode([a], [/])) */", 
+        assertEquals("[nt:base] as [a] /* property notNull " +
+                "where ([a].[notNull] is not null) " +
+                "and ([a].[equals] = 1) " +
+                "and (isdescendantnode([a], [/])) */",
                 plan);
     }           
 
@@ -165,11 +165,11 @@ public class QueryPlanTest extends Abstr
         String plan = it.nextRow().getValue("plan").getString();
         // System.out.println("plan: " + plan);
         // should not use the index on "jcr:uuid"
-        assertEquals("[nt:base] as [a] /* property tenPercent " + 
-                "where ((([a].[tenPercent] is not null) " + 
-                "and ([a].[fiftyPercent] is not null)) " + 
-                "and ([a].[hundredPercent] is not null)) " + 
-                "and (isdescendantnode([a], [/])) */", 
+        assertEquals("[nt:base] as [a] /* property tenPercent " +
+                "where ([a].[tenPercent] is not null) " +
+                "and ([a].[fiftyPercent] is not null) " +
+                "and ([a].[hundredPercent] is not null) " +
+                "and (isdescendantnode([a], [/])) */",
                 plan);
     }           
 

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=1610835&r1=1610834&r2=1610835&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 Tue Jul 15 20:14:40 2014
@@ -126,8 +126,8 @@ public class QueryTest extends AbstractR
                 .createQuery("explain " + query, "xpath").execute();
         rit = r.getRows();
         assertEquals("[nt:base] as [a] /* ordered lastMod > 2001-02-01 " +
-                "where (([a].[jcr:primaryType] = 'oak:Unstructured') " +
-                "and ([a].[content/lastMod] > '2001-02-01')) " +
+                "where ([a].[jcr:primaryType] = 'oak:Unstructured') " +
+                "and ([a].[content/lastMod] > '2001-02-01') " +
                 "and (isdescendantnode([a], [/test])) */",
                 rit.nextRow().getValue("plan").getString());