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/06/26 17:28:07 UTC
svn commit: r1496967 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/query/
main/java/org/apache/jackrabbit/oak/query/ast/
main/java/org/apache/jackrabbit/oak/query/index/
main/java/org/apache/jackrabbit/oak/spi/query/ test...
Author: thomasm
Date: Wed Jun 26 15:28:06 2013
New Revision: 1496967
URL: http://svn.apache.org/r1496967
Log:
OAK-882 Query: support conditions of type "property in(value1, value2)"
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java
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/SQL2Parser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElementFactory.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitorBase.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/FullTextSearchScoreImpl.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/Operator.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/UpperCaseImpl.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-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -37,6 +37,7 @@ import org.apache.jackrabbit.oak.query.a
import org.apache.jackrabbit.oak.query.ast.EquiJoinConditionImpl;
import org.apache.jackrabbit.oak.query.ast.FullTextSearchImpl;
import org.apache.jackrabbit.oak.query.ast.FullTextSearchScoreImpl;
+import org.apache.jackrabbit.oak.query.ast.InImpl;
import org.apache.jackrabbit.oak.query.ast.LengthImpl;
import org.apache.jackrabbit.oak.query.ast.LiteralImpl;
import org.apache.jackrabbit.oak.query.ast.LowerCaseImpl;
@@ -262,6 +263,12 @@ public class Query {
return super.visit(node);
}
+ @Override
+ public boolean visit(InImpl node) {
+ node.setQuery(query);
+ return super.visit(node);
+ }
+
}.visit(this);
source.setQueryConstraint(constraint);
source.init(this);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java Wed Jun 26 15:28:06 2013
@@ -367,6 +367,15 @@ public class SQL2Parser {
}
}
}
+ } else if (readIf("IN")) {
+ read("(");
+ ArrayList<StaticOperandImpl> list = new ArrayList<StaticOperandImpl>();
+ do {
+ StaticOperandImpl x = parseStaticOperand();
+ list.add(x);
+ } while (readIf(","));
+ read(")");
+ c = factory.in(left, list);
} else if (readIf("IS")) {
boolean not = readIf("NOT");
read("NULL");
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElementFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElementFactory.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElementFactory.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElementFactory.java Wed Jun 26 15:28:06 2013
@@ -13,6 +13,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.ArrayList;
+
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -137,4 +139,9 @@ public class AstElementFactory {
return new UpperCaseImpl(operand);
}
+ public ConstraintImpl in(DynamicOperandImpl left,
+ ArrayList<StaticOperandImpl> list) {
+ return new InImpl(left, list);
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitor.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitor.java Wed Jun 26 15:28:06 2013
@@ -35,6 +35,8 @@ public interface AstVisitor {
boolean visit(ComparisonImpl node);
+ boolean visit(InImpl node);
+
boolean visit(DescendantNodeImpl node);
boolean visit(DescendantNodeJoinConditionImpl node);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitorBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitorBase.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitorBase.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstVisitorBase.java Wed Jun 26 15:28:06 2013
@@ -42,6 +42,18 @@ public abstract class AstVisitorBase imp
node.getOperand2().accept(this);
return true;
}
+
+ /**
+ * Calls accept on the all operands in the "in" node.
+ */
+ @Override
+ public boolean visit(InImpl node) {
+ node.getOperand1().accept(this);
+ for (StaticOperandImpl s : node.getOperand2List()) {
+ s.accept(this);
+ }
+ return true;
+ }
/**
* Calls accept on the static operand in the fulltext search constraint.
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -27,6 +29,8 @@ public abstract class DynamicOperandImpl
public abstract PropertyValue currentProperty();
public abstract void restrict(FilterImpl f, Operator operator, PropertyValue v);
+
+ public abstract void restrictList(FilterImpl f, List<PropertyValue> list);
/**
* Check whether the condition can be applied to a selector (to restrict the
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -76,6 +78,11 @@ public class FullTextSearchScoreImpl ext
f.restrictProperty(Query.JCR_SCORE, operator, v);
}
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // optimizations of the type "jcr:score() in(a, b, c)" are not supported
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
Added: 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=1496967&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/InImpl.java Wed Jun 26 15:28:06 2013
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.query.ast;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+
+/**
+ * A "in" comparison operation.
+ */
+public class InImpl extends ConstraintImpl {
+
+ private final DynamicOperandImpl operand1;
+ private final List<StaticOperandImpl> operand2List;
+
+ public InImpl(DynamicOperandImpl operand1, List<StaticOperandImpl> operand2List) {
+ this.operand1 = operand1;
+ this.operand2List = operand2List;
+ }
+
+ public DynamicOperandImpl getOperand1() {
+ return operand1;
+ }
+
+ public List<StaticOperandImpl> getOperand2List() {
+ return operand2List;
+ }
+
+ @Override
+ public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
+ PropertyExistenceImpl p = operand1.getPropertyExistence();
+ if (p == null) {
+ return Collections.emptySet();
+ }
+ return Collections.singleton(p);
+ }
+
+ @Override
+ public boolean evaluate() {
+ // JCR 2.0 spec, 6.7.16 Comparison:
+ // "operand1 may evaluate to an array of values"
+ PropertyValue p1 = operand1.currentProperty();
+ if (p1 == null) {
+ return false;
+ }
+ for (StaticOperandImpl operand2 : operand2List) {
+ PropertyValue p2 = operand2.currentValue();
+ if (p2 == null) {
+ // if the property doesn't exist, the result is false
+ continue;
+ }
+ int v1Type = ComparisonImpl.getType(p1, p2.getType().tag());
+ if (v1Type != p2.getType().tag()) {
+ // "the value of operand2 is converted to the
+ // property type of the value of operand1"
+ p2 = PropertyValues.convert(p2, v1Type, query.getNamePathMapper());
+ }
+ if (PropertyValues.match(p1, p2)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ boolean accept(AstVisitor v) {
+ return v.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buff = new StringBuilder();
+ buff.append(operand1).append(" in(");
+ int i = 0;
+ for (StaticOperandImpl operand2 : operand2List) {
+ if (i++ > 0) {
+ buff.append(", ");
+ }
+ buff.append(operand2);
+ }
+ buff.append(")");
+ return buff.toString();
+ }
+
+ @Override
+ public void restrict(FilterImpl f) {
+ ArrayList<PropertyValue> list = new ArrayList<PropertyValue>();
+ for (StaticOperandImpl s : operand2List) {
+ if (!PropertyValues.canConvert(
+ s.getPropertyType(),
+ operand1.getPropertyType())) {
+ throw new IllegalArgumentException(
+ "Unsupported conversion from property type " +
+ PropertyType.nameFromValue(s.getPropertyType()) +
+ " to property type " +
+ PropertyType.nameFromValue(operand1.getPropertyType()));
+ }
+ list.add(s.currentValue());
+ }
+ if (list != null) {
+ operand1.restrictList(f, list);
+ }
+ }
+
+ @Override
+ public void restrictPushDown(SelectorImpl s) {
+ for (StaticOperandImpl op : operand2List) {
+ if (op.currentValue() == null) {
+ // one unknown value means it is not pushed down
+ return;
+ }
+ }
+ if (operand1.canRestrictSelector(s)) {
+ s.restrictSelector(this);
+ }
+ }
+
+}
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -92,6 +94,11 @@ public class LengthImpl extends DynamicO
// LENGTH(x) implies x is not null
propertyValue.restrict(f, Operator.NOT_EQUAL, null);
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // optimizations of the type "length(x) in(1, 2, 3)" are not supported
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -73,6 +75,12 @@ public class LowerCaseImpl extends Dynam
// LOWER(x) implies x is not null
operand.restrict(f, Operator.NOT_EQUAL, null);
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // "LOWER(x) IN (A, B)" implies x is not null
+ operand.restrict(f, Operator.NOT_EQUAL, null);
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -72,6 +74,11 @@ public class NodeLocalNameImpl extends D
public void restrict(FilterImpl f, Operator operator, PropertyValue v) {
// TODO support LOCALNAME index conditions
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // optimizations of type "LOCALNAME(..) IN(A, B)" are not supported
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -83,6 +85,11 @@ public class NodeNameImpl extends Dynami
}
// TODO support NAME(..) index conditions
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // optimizations of type "NAME(..) IN(A, B)" are not supported
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Operator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Operator.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Operator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Operator.java Wed Jun 26 15:28:06 2013
@@ -33,7 +33,9 @@ public enum Operator {
LESS_OR_EQUAL("<="),
- LIKE("like");
+ LIKE("like"),
+
+ IN("in");
/**
* The name of this operator.
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -170,6 +170,13 @@ public class PropertyValueImpl extends D
}
}
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ if (f.getSelector() == selector) {
+ f.restrictPropertyAsList(propertyName, list);
+ }
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.query.ast;
+import java.util.List;
+
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
@@ -73,6 +75,12 @@ public class UpperCaseImpl extends Dynam
// UPPER(x) implies x is not null
operand.restrict(f, Operator.NOT_EQUAL, null);
}
+
+ @Override
+ public void restrictList(FilterImpl f, List<PropertyValue> list) {
+ // "UPPER(x) IN (A, B)" implies x is not null
+ operand.restrict(f, Operator.NOT_EQUAL, null);
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -198,26 +198,25 @@ public class FilterImpl implements Filte
// not restricted
return;
}
- PropertyRestriction x = propertyRestrictions.get(propertyName);
- if (x == null) {
- x = new PropertyRestriction();
- x.propertyName = propertyName;
- propertyRestrictions.put(propertyName, x);
- }
+ PropertyRestriction x = addRestricition(propertyName);
if (x.propertyType != PropertyType.UNDEFINED && x.propertyType != propertyType) {
// already restricted to another property type - always false
setAlwaysFalse();
}
x.propertyType = propertyType;
}
+
+ public void restrictPropertyAsList(String propertyName, List<PropertyValue> list) {
+ PropertyRestriction x = addRestricition(propertyName);
+ if (x.list == null) {
+ x.list = list;
+ } else {
+ x.list.retainAll(list);
+ }
+ }
public void restrictProperty(String propertyName, Operator op, PropertyValue v) {
- PropertyRestriction x = propertyRestrictions.get(propertyName);
- if (x == null) {
- x = new PropertyRestriction();
- x.propertyName = propertyName;
- propertyRestrictions.put(propertyName, x);
- }
+ PropertyRestriction x = addRestricition(propertyName);
PropertyValue oldFirst = x.first;
PropertyValue oldLast = x.last;
switch (op) {
@@ -253,6 +252,8 @@ public class FilterImpl implements Filte
x.isLike = true;
x.first = v;
break;
+ case IN:
+
}
if (x.first != null && x.last != null) {
if (x.first.compareTo(x.last) > 0) {
@@ -262,7 +263,17 @@ public class FilterImpl implements Filte
}
}
}
-
+
+ private PropertyRestriction addRestricition(String propertyName) {
+ PropertyRestriction x = propertyRestrictions.get(propertyName);
+ if (x == null) {
+ x = new PropertyRestriction();
+ x.propertyName = propertyName;
+ propertyRestrictions.put(propertyName, x);
+ }
+ return x;
+ }
+
static PropertyValue maxValue(PropertyValue a, PropertyValue b) {
if (a == null) {
return b;
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -19,6 +19,7 @@
package org.apache.jackrabbit.oak.spi.query;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
@@ -159,6 +160,12 @@ public interface Filter {
* value should be taken into consideration
*/
public boolean isLike;
+
+ /**
+ * A list of possible values, for conditions of the type
+ * "x=1 or x=2 or x=3".
+ */
+ public List<PropertyValue> list;
/**
* The property type, if restricted.
@@ -168,6 +175,26 @@ public interface Filter {
@Override
public String toString() {
+ return (toStringFromTo() + " " + toStringList()).trim();
+ }
+
+ private String toStringList() {
+ if (list == null) {
+ return "";
+ }
+ StringBuilder buff = new StringBuilder("in(");
+ int i = 0;
+ for (PropertyValue p : list) {
+ if (i++ > 0) {
+ buff.append(", ");
+ }
+ buff.append(p.toString());
+ }
+ buff.append(' ');
+ return buff.toString();
+ }
+
+ private String toStringFromTo() {
String f = first == null ? "" : first.toString();
String l = last == null ? "" : last.toString();
if (f.equals(l)) {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java Wed Jun 26 15:28:06 2013
@@ -114,8 +114,10 @@ public abstract class AbstractQueryTest
protected void test(String file) throws Exception {
InputStream in = AbstractQueryTest.class.getResourceAsStream(file);
LineNumberReader r = new LineNumberReader(new InputStreamReader(in));
+ String className = getClass().getName();
+ String shortClassName = className.replaceAll("org.apache.jackrabbit.oak.plugins.index.", "oajopi.");
PrintWriter w = new PrintWriter(new OutputStreamWriter(
- new FileOutputStream("target/" + getClass().getName() + "_"
+ new FileOutputStream("target/" + shortClassName + "_"
+ file)));
HashSet<String> knownQueries = new HashSet<String>();
boolean errors = false;
Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt?rev=1496967&r1=1496966&r2=1496967&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt Wed Jun 26 15:28:06 2013
@@ -292,4 +292,4 @@ select [jcr:path] from [nt:base] where n
java.text.ParseException: Query: select [jcr:path] from [nt:base] where name =+ 'Hello(*)'; expected: Illegal operation: + Hello
select [jcr:path] from [nt:base] where name => 'Hello'
-java.text.ParseException: Query: select [jcr:path] from [nt:base] where name =>(*)'Hello'; expected: (, ., =, <>, <, >, <=, >=, LIKE, IS, NOT
+java.text.ParseException: Query: select [jcr:path] from [nt:base] where name =>(*)'Hello'; expected: (, ., =, <>, <, >, <=, >=, LIKE, IN, IS, NOT
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=1496967&r1=1496966&r2=1496967&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 Wed Jun 26 15:28:06 2013
@@ -37,6 +37,9 @@ explain select * from [nt:base] where le
explain select * from [nt:base] where [jcr:uuid] = '1' or ([jcr:uuid] = '2' and [b] = '3')
[nt:base] as [nt:base] /* property jcr:uuid */
+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 */