jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r1498379 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/ast/ test/resources/org/apache/jackrabbit/oak/query/
Date Mon, 01 Jul 2013 11:15:05 GMT
Author: thomasm
Date: Mon Jul  1 11:15:05 2013
New Revision: 1498379

URL: http://svn.apache.org/r1498379
Log:
OAK-882 Query: support conditions of type "property in(value1, value2)" (auto-convert from
"x=1 or x=2" to "x in(1, 2)", possibly using an index)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
    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/ChildNodeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.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/PropertyExistenceImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.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/ast/UpperCaseImpl.java
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Mon Jul  1 11:15:05 2013
@@ -25,6 +25,7 @@ import org.apache.jackrabbit.oak.api.Tre
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.namepath.JcrPathParser;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.query.ast.AndImpl;
 import org.apache.jackrabbit.oak.query.ast.AstVisitorBase;
 import org.apache.jackrabbit.oak.query.ast.BindVariableValueImpl;
 import org.apache.jackrabbit.oak.query.ast.ChildNodeImpl;
@@ -43,6 +44,8 @@ import org.apache.jackrabbit.oak.query.a
 import org.apache.jackrabbit.oak.query.ast.LowerCaseImpl;
 import org.apache.jackrabbit.oak.query.ast.NodeLocalNameImpl;
 import org.apache.jackrabbit.oak.query.ast.NodeNameImpl;
+import org.apache.jackrabbit.oak.query.ast.NotImpl;
+import org.apache.jackrabbit.oak.query.ast.OrImpl;
 import org.apache.jackrabbit.oak.query.ast.OrderingImpl;
 import org.apache.jackrabbit.oak.query.ast.PropertyExistenceImpl;
 import org.apache.jackrabbit.oak.query.ast.PropertyValueImpl;
@@ -124,8 +127,8 @@ public class Query {
                 bindVariableMap.put(node.getBindVariableName(), null);
                 return true;
             }
-
-            @Override
+            
+             @Override
             public boolean visit(ChildNodeImpl node) {
                 node.setQuery(query);
                 node.bindSelector(source);
@@ -268,6 +271,24 @@ public class Query {
                 node.setQuery(query);
                 return super.visit(node);
             }
+            
+            @Override
+            public boolean visit(AndImpl node) {
+                node.setQuery(query);
+                return super.visit(node);
+            }
+
+            @Override
+            public boolean visit(OrImpl node) {
+                node.setQuery(query);
+                return super.visit(node);
+            }
+
+            @Override
+            public boolean visit(NotImpl node) {
+                node.setQuery(query);
+                return super.visit(node);
+            }
 
         }.visit(this);
         source.setQueryConstraint(constraint);

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=1498379&r1=1498378&r2=1498379&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
Mon Jul  1 11:15:05 2013
@@ -18,10 +18,13 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
 /**
@@ -52,6 +55,40 @@ public class AndImpl extends ConstraintI
         result.addAll(s2);
         return result;
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        Set<SelectorImpl> s1 = constraint1.getSelectors();
+        Set<SelectorImpl> s2 = constraint1.getSelectors();
+        if (s1.isEmpty()) {
+            return s2;
+        } else if (s2.isEmpty()) {
+            return s1;
+        }
+        return Sets.union(s1, s2);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> m1 = constraint1.getInMap();
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> m2 = constraint2.getInMap();
+        if (m1.isEmpty()) {
+            return m2;
+        } else if (m2.isEmpty()) {
+            return m1;
+        }
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> result = Maps.newHashMap();
+        result.putAll(m1);
+        for (Entry<DynamicOperandImpl, Set<StaticOperandImpl>> e2 : m2.entrySet())
{
+            Set<StaticOperandImpl> s = result.get(e2.getKey());
+            if (s != null) {
+                s.retainAll(e2.getValue());
+            } else {
+                result.put(e2.getKey(), e2.getValue());
+            }
+        }
+        return result;
+    }
 
     @Override
     public boolean evaluate() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -57,7 +58,17 @@ public class ChildNodeImpl extends Const
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
         return Collections.emptySet();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
 
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }    
+    
     @Override
     public boolean evaluate() {
         String p = selector.currentPath();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.PropertyType;
@@ -70,7 +71,20 @@ public class ComparisonImpl extends Cons
         }
         return Collections.singleton(p);
     }
-
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return operand1.getSelectors();
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        if (operator == Operator.EQUAL) {
+            return Collections.singletonMap(operand1, Collections.singleton(operand2));
+        }
+        return Collections.emptyMap();
+    }    
+    
     @Override
     public boolean evaluate() {
         // JCR 2.0 spec, 6.7.16 Comparison:

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
Mon Jul  1 11:15:05 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -42,6 +43,20 @@ public abstract class ConstraintImpl ext
      * @return the common property existence condition (possibly empty)
      */
     public abstract Set<PropertyExistenceImpl> getPropertyExistenceConditions();
+    
+    /**
+     * Get the set of selectors for the given condition.
+     * 
+     * @return the set of selectors (possibly empty)
+     */
+    public abstract Set<SelectorImpl> getSelectors();
+    
+    /**
+     * Get the map of "in(..)" conditions.
+     * 
+     * @return the map
+     */
+    public abstract Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap();
 
     /**
      * Apply the condition to the filter, further restricting the filter if
@@ -54,7 +69,12 @@ public abstract class ConstraintImpl ext
 
     /**
      * Push as much of the condition down to this selector, further restricting
-     * the selector condition if possible.
+     * the selector condition if possible. This is important for a join: for
+     * example, the query
+     * "select * from a inner join b on a.x=b.x where a.y=1 and b.y=1", the
+     * condition "a.y=1" can be pushed down to "a", and the condition "b.y=1"
+     * can be pushed down to "b". That means it is possible to use an index in
+     * this case.
      *
      * @param s the selector
      */

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -43,6 +44,16 @@ public class DescendantNodeImpl extends 
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
         return Collections.emptySet();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }    
 
     @Override
     public boolean evaluate() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
Mon Jul  1 11:15:05 2013
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -57,4 +58,27 @@ public abstract class DynamicOperandImpl
      */
     public abstract PropertyExistenceImpl getPropertyExistence();
 
+    /**
+     * Get the set of selectors for this operand.
+     * 
+     * @return the set of selectors
+     */
+    public abstract Set<SelectorImpl> getSelectors();
+    
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (!(other instanceof DynamicOperandImpl)) {
+            return false;
+        }
+        DynamicOperandImpl o = (DynamicOperandImpl) other;
+        return o.toString().equals(toString());
+    }
+    
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
Mon Jul  1 11:15:05 2013
@@ -24,6 +24,7 @@ import static org.apache.jackrabbit.oak.
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -108,6 +109,16 @@ public class FullTextSearchImpl extends 
         }
         return Collections.singleton(new PropertyExistenceImpl(selector, selectorName, propertyName));
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }    
 
     @Override
     public boolean evaluate() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
Mon Jul  1 11:15:05 2013
@@ -18,7 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -53,6 +55,11 @@ public class FullTextSearchScoreImpl ext
     public PropertyExistenceImpl getPropertyExistence() {
         return null;
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java
Mon Jul  1 11:15:05 2013
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.query.
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.PropertyType;
@@ -29,6 +30,8 @@ import org.apache.jackrabbit.oak.api.Pro
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
 
+import com.google.common.collect.Sets;
+
 /**
  * A "in" comparison operation.
  */
@@ -58,6 +61,17 @@ public class InImpl extends ConstraintIm
         }
         return Collections.singleton(p);
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return operand1.getSelectors();
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        Set<StaticOperandImpl> set = Sets.newHashSet(operand2List);
+        return Collections.singletonMap(operand1, set);
+    }  
 
     @Override
     public boolean evaluate() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -55,6 +56,11 @@ public class LengthImpl extends DynamicO
     public PropertyExistenceImpl getPropertyExistence() {
         return propertyValue.getPropertyExistence();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return propertyValue.getSelectors();
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -57,6 +58,11 @@ public class LowerCaseImpl extends Dynam
     public PropertyExistenceImpl getPropertyExistence() {
         return operand.getPropertyExistence();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return operand.getSelectors();
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
Mon Jul  1 11:15:05 2013
@@ -18,7 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -58,6 +60,11 @@ public class NodeLocalNameImpl extends D
     public PropertyExistenceImpl getPropertyExistence() {
         return null;
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
Mon Jul  1 11:15:05 2013
@@ -18,7 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -65,6 +67,11 @@ public class NodeNameImpl extends Dynami
     public PropertyExistenceImpl getPropertyExistence() {
         return null;
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -47,6 +48,16 @@ public class NotImpl extends ConstraintI
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
         return Collections.emptySet();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return constraint.getSelectors();
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }    
 
     @Override
     boolean accept(AstVisitor v) {
@@ -61,12 +72,11 @@ public class NotImpl extends ConstraintI
     @Override
     public void restrict(FilterImpl f) {
         if (f.getSelector().outerJoinRightHandSide) {
-            // we need to be careful with the condition 
+            // we need to be careful with the condition
             // "NOT (property IS NOT NULL)"
-            // (which is the same as 
-            // "property IS NULL") because
-            // this might cause an index to ignore
-            // the join condition "property = x"
+            // (which is the same as "property IS NULL")
+            // because this might cause an index
+            // to ignore the join condition "property = x"
             // for example in:
             // "select * from a left outer join b on a.x = b.y
             // where not b.y is not null"

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=1498379&r1=1498378&r2=1498379&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
Mon Jul  1 11:15:05 2013
@@ -18,10 +18,14 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
 /**
@@ -47,6 +51,8 @@ public class OrImpl extends ConstraintIm
     
     @Override
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
+        // for the condition "x=1 or x=2", the existence condition
+        // "x is not null" be be derived
         Set<PropertyExistenceImpl> s1 = constraint1.getPropertyExistenceConditions();
         if (s1.isEmpty()) {
             return s1;
@@ -57,6 +63,39 @@ public class OrImpl extends ConstraintIm
         }
         return Sets.intersection(s1, s2);
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        Set<SelectorImpl> s1 = constraint1.getSelectors();
+        Set<SelectorImpl> s2 = constraint1.getSelectors();
+        if (s1.isEmpty()) {
+            return s2;
+        } else if (s2.isEmpty()) {
+            return s1;
+        }
+        return Sets.union(s1, s2);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> m1 = constraint1.getInMap();
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> m2 = constraint2.getInMap();
+        if (m1.isEmpty()) {
+            return m1;
+        } else if (m2.isEmpty()) {
+            return m2;
+        }
+        Map<DynamicOperandImpl, Set<StaticOperandImpl>> result = Maps.newHashMap();
+        result.putAll(m1);
+        for (Entry<DynamicOperandImpl, Set<StaticOperandImpl>> e2 : m2.entrySet())
{
+            Set<StaticOperandImpl> l2 = e2.getValue();
+            Set<StaticOperandImpl> l1 = m1.get(e2.getKey());
+            // l1 might be null (l2 not, as it's from the iterator)
+            Set<StaticOperandImpl> list = l1 == null ? l2 : Sets.union(l1, l2);
+            result.put(e2.getKey(), list);
+        }
+        return result;
+    }    
 
     @Override
     public boolean evaluate() {
@@ -86,11 +125,71 @@ public class OrImpl extends ConstraintIm
 
     @Override
     public void restrictPushDown(SelectorImpl s) {
-        // ignore
-        // TODO some OR conditions can be applied to a selector,
-        // for example WHERE X.ID = 1 OR X.ID = 2
-        // can be applied to X as a whole,
-        // but X.ID = 1 OR Y.ID = 2 can't be applied to either
+        restrictPushDownNotExists(s);
+        restrictPushDownInList(s);
+    }
+    
+    /**
+     * Push down the "property in(1, 2, 3)" conditions to the selector, if there
+     * are any that can be derived.
+     * 
+     * @param s the selector
+     */
+    private void restrictPushDownInList(SelectorImpl s) {
+        if (isOnlySelector(s)) {
+            Map<DynamicOperandImpl, Set<StaticOperandImpl>> m = getInMap();
+            for (Entry<DynamicOperandImpl, Set<StaticOperandImpl>> e : m.entrySet())
{
+                Set<StaticOperandImpl> set = e.getValue();
+                if (set.size() > 1) {
+                    InImpl in = new InImpl(e.getKey(), Lists.newArrayList(set));
+                    in.setQuery(query);
+                    in.restrictPushDown(s);
+                }
+            }
+        }
+    }
+
+    /**
+     * Push down the "not exists" conditions to the selector.
+     * 
+     * @param s the selector
+     */
+    private void restrictPushDownNotExists(SelectorImpl s) {
+        Set<PropertyExistenceImpl> set = getPropertyExistenceConditions();
+        if (set.isEmpty()) {
+            return;
+        }
+        for (PropertyExistenceImpl p : set) {
+            p.restrictPushDown(s);
+        }
+    }
+
+    /**
+     * Check whether there are no other selectors in this "or" condition.
+     * 
+     * @param s the selector
+     * @return true if there are no other selectors
+     */
+    private boolean isOnlySelector(SelectorImpl s) {
+        Set<SelectorImpl> set = getSelectors();
+        if (set.size() == 0) {
+            // conditions without selectors, for example "1=0":
+            // the condition can be pushed down; 
+            // (currently there are no such conditions,
+            // but in the future we might add them)
+            return true;
+        } else if (set.size() > 1) {
+            // "x.a=1 or y.a=2" can't be pushed down to either "x" or "y"
+            return false;
+        } else {
+            // exactly one selector: check if it's the right one
+            SelectorImpl s2 = set.iterator().next();
+            if (s2 != s) {
+                // a different selector
+                return false;
+            }
+        }
+        return true;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -52,6 +53,16 @@ public class PropertyExistenceImpl exten
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
         return Collections.singleton(this);
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }  
 
     @Override
     boolean accept(AstVisitor v) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,8 +19,10 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -97,6 +99,11 @@ public class PropertyValueImpl extends D
         }
         return new PropertyExistenceImpl(selector, selectorName, propertyName);
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -49,6 +50,16 @@ public class SameNodeImpl extends Constr
     public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
         return Collections.emptySet();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return Collections.singleton(selector);
+    }
+    
+    @Override 
+    public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+        return Collections.emptyMap();
+    }  
 
     @Override
     boolean accept(AstVisitor v) {

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=1498379&r1=1498378&r2=1498379&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
Mon Jul  1 11:15:05 2013
@@ -351,5 +351,20 @@ public class SelectorImpl extends Source
             selectorCondition = new AndImpl(selectorCondition, constraint);
         }
     }
+    
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (!(this instanceof SelectorImpl)) {
+            return false;
+        }
+        return selectorName.equals(((SelectorImpl) other).selectorName);
+    }
+    
+    @Override
+    public int hashCode() {
+        return selectorName.hashCode();
+    }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java
Mon Jul  1 11:15:05 2013
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import java.util.List;
+import java.util.Set;
 
 import javax.jcr.PropertyType;
 
@@ -57,6 +58,11 @@ public class UpperCaseImpl extends Dynam
     public PropertyExistenceImpl getPropertyExistence() {
         return operand.getPropertyExistence();
     }
+    
+    @Override
+    public Set<SelectorImpl> getSelectors() {
+        return operand.getSelectors();
+    }
 
     @Override
     public PropertyValue currentProperty() {

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
Mon Jul  1 11:15:05 2013
@@ -31,17 +31,20 @@ explain select excerpt(.) from [nt:resou
 explain select * from [nt:base] where [jcr:uuid]=1 or [b]=2
 [nt:base] as [nt:base] /* traverse "*" */
 
+explain select b.[jcr:uuid] from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b,
a) where (a.[jcr:uuid] = '1' or a.[jcr:uuid] = '2') and b.[jcr:uuid] is not null
+[nt:base] as [a] /* property jcr:uuid where ([a].[jcr:uuid] is not null) and ([a].[jcr:uuid]
in(cast('1' as string), cast('2' as string))) */ inner join [nt:base] as [b] /* property jcr:uuid
where [b].[jcr:uuid] is not null */ on isdescendantnode([b], [a])
+
 explain select * from [nt:base] where length([jcr:uuid])=1 or upper([jcr:uuid])='1' or lower([jcr:uuid])='3'
-[nt:base] as [nt:base] /* property jcr:uuid */
+[nt:base] as [nt:base] /* property jcr:uuid where [nt:base].[jcr:uuid] is not null */
 
 explain select * from [nt:base] where [jcr:uuid] = '1' or ([jcr:uuid] = '2' and [b] = '3')
-[nt:base] as [nt:base] /* property jcr:uuid */
+[nt:base] as [nt:base] /* property jcr:uuid where ([nt:base].[jcr:uuid] is not null) and
([nt:base].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
 
 explain select * from [nt:base] where [jcr:uuid] in('1', '2')
 [nt:base] as [nt:base] /* property jcr:uuid where [nt:base].[jcr:uuid] in(cast('1' as string),
cast('2' as string)) */
 
 explain select * from [nt:base] where [jcr:uuid] = '1' or [jcr:uuid] = '2'
-[nt:base] as [nt:base] /* property jcr:uuid */
+[nt:base] as [nt:base] /* property jcr:uuid where ([nt:base].[jcr:uuid] is not null) and
([nt:base].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
 
 explain select * from [nt:base] where [jcr:uuid] = '123'
 [nt:base] as [nt:base] /* property jcr:uuid=123 where [nt:base].[jcr:uuid] = cast('123' as
string) */
@@ -52,6 +55,9 @@ explain select * from [nt:base] where [j
 explain select * from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null and b.[jcr:uuid] is not null
 [nt:base] as [a] /* property jcr:uuid where [a].[jcr:uuid] is not null */ inner join [nt:base]
as [b] /* property jcr:uuid where [b].[jcr:uuid] is not null */ on isdescendantnode([b], [a])
 
+explain select * from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a)
where (a.[jcr:uuid]=1 or a.[jcr:uuid]=2) and (b.[jcr:uuid]=3 or b.[jcr:uuid]=4)
+[nt:base] as [a] /* property jcr:uuid where ([a].[jcr:uuid] is not null) and ([a].[jcr:uuid]
in(cast('1' as long), cast('2' as long))) */ inner join [nt:base] as [b] /* property jcr:uuid
where ([b].[jcr:uuid] is not null) and ([b].[jcr:uuid] in(cast('3' as long), cast('4' as long)))
*/ on isdescendantnode([b], [a])
+
 explain select * from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null and b.[x] is not null
 [nt:base] as [a] /* property jcr:uuid where [a].[jcr:uuid] is not null */ inner join [nt:base]
as [b] /* traverse "/path/from/the/join/selector/*" where [b].[x] is not null */ on isdescendantnode([b],
[a])
 

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt?rev=1498379&r1=1498378&r2=1498379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
Mon Jul  1 11:15:05 2013
@@ -28,6 +28,9 @@
 xpath2sql testroot//child/..[@foo1]
 select b.[jcr:path] as [jcr:path], b.[jcr:score] as [jcr:score], b.* from [nt:base] as a
inner join [nt:base] as b on ischildnode(a, b) where name(a) = 'child' and isdescendantnode(a,
'/testroot') and b.[foo1] is not null /* xpath: testroot//child/..[@foo1] */
 
+xpath2sql //*[@jcr:uuid='1' or @jcr:uuid='2']//*[@jcr:uuid]/(@jcr:uuid)
+select b.[jcr:path] as [jcr:path], b.[jcr:score] as [jcr:score], b.[jcr:uuid] as [jcr:uuid]
from [nt:base] as a inner join [nt:base] as b on isdescendantnode(b, a) where (a.[jcr:uuid]
= '1' or a.[jcr:uuid] = '2') and b.[jcr:uuid] is not null /* xpath: //*[@jcr:uuid='1' or @jcr:uuid='2']//*[@jcr:uuid]/(@jcr:uuid)
*/
+
 xpath2sql testroot//child/.[@foo1]
 select [jcr:path], [jcr:score], * from [nt:base] as a where [foo1] is not null and name(a)
= 'child' and isdescendantnode(a, '/testroot') /* xpath: testroot//child/.[@foo1] */
 



Mime
View raw message