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)] */