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 2013/10/24 15:40:51 UTC

svn commit: r1535377 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/xpath/ test/resources/org/apache/jackrabbit/oak/query/

Author: thomasm
Date: Thu Oct 24 13:40:51 2013
New Revision: 1535377

URL: http://svn.apache.org/r1535377
Log:
OAK-1116 Query: use indexes for queries with "or" conditions (xpath queries only so far)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
    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/xpath/Expression.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java?rev=1535377&r1=1535376&r2=1535377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java Thu Oct 24 13:40:51 2013
@@ -202,6 +202,28 @@ abstract class Expression {
         }
     
     }
+    
+    /**
+     * An "or" condition.
+     */
+    static class OrCondition extends Condition {
+
+        OrCondition(Expression left, Expression right) {
+            super(left, "or", right, Expression.PRECEDENCE_OR);
+        }
+        
+    }
+    
+    /**
+     * An "and" condition.
+     */
+    static class AndCondition extends Condition {
+
+        AndCondition(Expression left, Expression right) {
+            super(left, "and", right, Expression.PRECEDENCE_AND);
+        }
+        
+    }
 
     /**
      * A function call.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java?rev=1535377&r1=1535376&r2=1535377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java Thu Oct 24 13:40:51 2013
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.query.
 import java.util.ArrayList;
 
 import org.apache.jackrabbit.oak.query.QueryImpl;
+import org.apache.jackrabbit.oak.query.xpath.Expression.OrCondition;
 import org.apache.jackrabbit.oak.query.xpath.Expression.Property;
 
 /**
@@ -43,9 +44,36 @@ public class Statement {
      * All selectors.
      */
     private ArrayList<Selector> selectors;
+    
+    private Expression where;
 
     private ArrayList<Order> orderList = new ArrayList<Order>();
     
+    public Statement optimize() {
+        if (explain || measure || orderList.size() > 0) {
+            return this;
+        }
+        if (where == null) {
+            return this;
+        }
+        if (where instanceof OrCondition) {
+            OrCondition or = (OrCondition) where;
+            Statement s1 = new Statement();
+            s1.columnSelector = columnSelector;
+            s1.selectors = selectors;
+            s1.columnList = columnList;
+            s1.where = or.left;
+            Statement s2 = new Statement();
+            s2.columnSelector = columnSelector;
+            s2.selectors = selectors;
+            s2.columnList = columnList;
+            s2.where = or.right;
+            s2.xpathQuery = xpathQuery;
+            return new UnionStatement(s1, s2);
+        }
+        return this;
+    }
+    
     @Override
     public String toString() {
         StringBuilder buff = new StringBuilder();
@@ -101,10 +129,6 @@ public class Statement {
         }
         
         // where ...
-        Expression where = null;
-        for (Selector s : selectors) {
-            where = Expression.and(where, s.condition);
-        }
         if (where != null) {
             buff.append(" where ").append(where.toString());
         }
@@ -121,9 +145,12 @@ public class Statement {
         }
 
         // leave original xpath string as a comment
-        buff.append(" /* xpath: ");
-        buff.append(xpathQuery);
-        buff.append(" */");
+        if (xpathQuery != null) {
+            buff.append(" /* xpath: ");
+            buff.append(xpathQuery);
+            buff.append(" */");
+        }
+        
         return buff.toString();        
     }
 
@@ -142,6 +169,10 @@ public class Statement {
     public void setSelectors(ArrayList<Selector> selectors) {
         this.selectors = selectors;
     }
+    
+    public void setWhere(Expression where) {
+        this.where = where;
+    }
 
     public void addOrderBy(Order order) {
         this.orderList.add(order);
@@ -154,5 +185,24 @@ public class Statement {
     public void setOriginalQuery(String xpathQuery) {
         this.xpathQuery = xpathQuery;
     }
+    
+    /**
+     * A union statement.
+     */
+    static class UnionStatement extends Statement {
+        
+        private final Statement s1, s2;
+        
+        UnionStatement(Statement s1, Statement s2) {
+            this.s1 = s1;
+            this.s2 = s2;
+        }
+        
+        @Override
+        public String toString() {
+            return s1 + " union " + s2;
+        }
+        
+    }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java?rev=1535377&r1=1535376&r2=1535377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java Thu Oct 24 13:40:51 2013
@@ -279,6 +279,14 @@ public class XPathToSQL2Converter {
         statement.setColumnSelector(currentSelector);
         statement.setSelectors(selectors);
         
+        Expression where = null;
+        for (Selector s : selectors) {
+            where = Expression.and(where, s.condition);
+        }
+        statement.setWhere(where);
+        
+        statement = statement.optimize();
+        
         return statement.toString();
 
     }
@@ -404,7 +412,7 @@ public class XPathToSQL2Converter {
     private Expression parseConstraint() throws ParseException {
         Expression a = parseAnd();
         while (readIf("or")) {
-            a = new Expression.Condition(a, "or", parseAnd(), Expression.PRECEDENCE_OR);
+            a = new Expression.OrCondition(a, parseAnd());
         }
         return a;
     }
@@ -412,7 +420,7 @@ public class XPathToSQL2Converter {
     private Expression parseAnd() throws ParseException {
         Expression a = parseCondition();
         while (readIf("and")) {
-            a = new Expression.Condition(a, "and", parseCondition(), Expression.PRECEDENCE_AND);
+            a = new Expression.AndCondition(a, parseCondition());
         }
         return 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=1535377&r1=1535376&r2=1535377&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 Thu Oct 24 13:40:51 2013
@@ -406,7 +406,7 @@ xpath2sql //element(*, my:type)[(not(@my
 select [jcr:path], [jcr:score], * from [my:type] as a where [my:title] is null and [my:subject] is not null /* xpath: //element(*, my:type)[(not(@my:title) and @my:subject)] */
 
 xpath2sql //element(*, my:type)[not(@my:title) or @my:subject]
-select [jcr:path], [jcr:score], * from [my:type] as a where [my:title] is null or [my:subject] is not null /* xpath: //element(*, my:type)[not(@my:title) or @my:subject] */
+select [jcr:path], [jcr:score], * from [my:type] as a where [my:title] is null union select [jcr:path], [jcr:score], * from [my:type] as a where [my:subject] is not null /* xpath: //element(*, my:type)[not(@my:title) or @my:subject] */
 
 xpath2sql //element(*, my:type)[not(@my:value > 0 and @my:value < 100)]
 select [jcr:path], [jcr:score], * from [my:type] as a where not([my:value] > 0 and [my:value] < 100) /* xpath: //element(*, my:type)[not(@my:value > 0 and @my:value < 100)] */