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 2016/09/08 13:34:38 UTC
svn commit: r1759820 - 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/xpath/
main/java/org/apache/jackrabbit/oak/spi/query/ test...
Author: thomasm
Date: Thu Sep 8 13:34:38 2016
New Revision: 1759820
URL: http://svn.apache.org/viewvc?rev=1759820&view=rev
Log:
OAK-3574 Query engine: support p=lowercase('x') and other function-based indexes
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.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/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/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/xpath/XPathToSQL2Converter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2.txt
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1759820&r1=1759819&r2=1759820&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Thu Sep 8 13:34:38 2016
@@ -31,16 +31,9 @@ import java.util.Set;
import javax.annotation.Nonnull;
-import com.google.common.base.Strings;
-import com.google.common.collect.AbstractIterator;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-
import org.apache.jackrabbit.oak.api.PropertyValue;
-import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.api.Result.SizePrecision;
+import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.namepath.JcrPathParser;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.query.ast.AndImpl;
@@ -98,6 +91,12 @@ import org.apache.jackrabbit.oak.spi.sta
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Strings;
+import com.google.common.collect.AbstractIterator;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Ordering;
+
/**
* Represents a parsed query.
*/
@@ -987,21 +986,10 @@ public class QueryImpl implements Query
sortOrder = new ArrayList<OrderEntry>();
for (OrderingImpl o : orderings) {
DynamicOperandImpl op = o.getOperand();
- if (!(op instanceof PropertyValueImpl)) {
- // ordered by a function: currently not supported
- break;
- }
- PropertyValueImpl p = (PropertyValueImpl) op;
- SelectorImpl s = p.getSelectors().iterator().next();
- if (!s.equals(filter.getSelector())) {
- // ordered by a different selector
+ OrderEntry e = op.getOrderEntry(filter.getSelector(), o);
+ if (e == null) {
continue;
}
- OrderEntry e = new OrderEntry(
- p.getPropertyName(),
- Type.UNDEFINED,
- o.isDescending() ?
- OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
sortOrder.add(e);
}
if (sortOrder.size() == 0) {
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -626,7 +626,7 @@ public class SQL2Parser {
private DynamicOperandImpl parseExpressionFunction(String functionName) throws ParseException {
DynamicOperandImpl op;
if ("LENGTH".equalsIgnoreCase(functionName)) {
- op = factory.length(parsePropertyValue(readName()));
+ op = factory.length(parseDynamicOperand());
} else if ("NAME".equalsIgnoreCase(functionName)) {
if (isToken(")")) {
op = factory.nodeName(getOnlySelectorName());
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -94,8 +94,8 @@ public class AstElementFactory {
return new JoinImpl(left, right, joinType, joinCondition);
}
- public LengthImpl length(PropertyValueImpl propertyValue) {
- return new LengthImpl(propertyValue);
+ public LengthImpl length(DynamicOperandImpl operand) {
+ return new LengthImpl(operand);
}
public LiteralImpl literal(PropertyValue literalValue) {
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -117,7 +117,7 @@ public abstract class AstVisitorBase imp
*/
@Override
public boolean visit(LengthImpl node) {
- return node.getPropertyValue().accept(this);
+ return node.getOperand().accept(this);
}
/**
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -21,6 +21,7 @@ import java.util.Set;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
/**
* The base class for dynamic operands (such as a function or property).
@@ -47,15 +48,12 @@ public abstract class DynamicOperandImpl
public abstract void restrictList(FilterImpl f, List<PropertyValue> list);
/**
- * Apply a restriction of type "function(this) = value" to the given filter.
+ * Get the function of a function-based index, in Polish notation.
*
- * @param functionName the function name (for example "upper")
- * @param f the filter where the restriction is applied.
- * @param operator the operator (for example "=").
- * @param v the value
+ * @param s the selector
+ * @return the function, or null if not supported
*/
- public abstract void restrictFunction(FilterImpl f, String functionName, Operator operator,
- PropertyValue v);
+ public abstract String getFunction(SelectorImpl s);
/**
* Check whether the condition can be applied to a selector (to restrict the
@@ -106,5 +104,14 @@ public abstract class DynamicOperandImpl
}
public abstract DynamicOperandImpl createCopy();
+
+ /**
+ * Create an entry for the "order by" list for a given filter.
+ *
+ * @param s the selector
+ * @param o the ordering
+ * @return the entry
+ */
+ public abstract OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o);
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -28,6 +28,7 @@ import org.apache.jackrabbit.oak.api.Pro
import org.apache.jackrabbit.oak.query.QueryImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
/**
* A fulltext search score expression.
@@ -92,8 +93,9 @@ public class FullTextSearchScoreImpl ext
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
+ public String getFunction(SelectorImpl s) {
// optimizations of the type "upper(jcr:score()) = '1'" are not supported
+ return null;
}
@Override
@@ -111,4 +113,9 @@ public class FullTextSearchScoreImpl ext
return new FullTextSearchScoreImpl(selectorName);
}
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ return null;
+ }
+
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -24,22 +24,25 @@ import java.util.Set;
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
/**
* The function "length(..)".
*/
public class LengthImpl extends DynamicOperandImpl {
- private final PropertyValueImpl propertyValue;
+ private final DynamicOperandImpl operand;
- public LengthImpl(PropertyValueImpl propertyValue) {
- this.propertyValue = propertyValue;
+ public LengthImpl(DynamicOperandImpl operand) {
+ this.operand = operand;
}
- public PropertyValueImpl getPropertyValue() {
- return propertyValue;
+ public DynamicOperandImpl getOperand() {
+ return operand;
}
@Override
@@ -49,22 +52,22 @@ public class LengthImpl extends DynamicO
@Override
public String toString() {
- return "length(" + propertyValue + ')';
+ return "length(" + operand + ')';
}
@Override
public PropertyExistenceImpl getPropertyExistence() {
- return propertyValue.getPropertyExistence();
+ return operand.getPropertyExistence();
}
@Override
public Set<SelectorImpl> getSelectors() {
- return propertyValue.getSelectors();
+ return operand.getSelectors();
}
@Override
public PropertyValue currentProperty() {
- PropertyValue p = propertyValue.currentProperty();
+ PropertyValue p = operand.currentProperty();
if (p == null) {
return null;
}
@@ -99,8 +102,16 @@ public class LengthImpl extends DynamicO
}
}
// LENGTH(x) implies x is not null
- propertyValue.restrict(f, Operator.NOT_EQUAL, null);
- propertyValue.restrictFunction(f, "length", operator, v);
+ operand.restrict(f, Operator.NOT_EQUAL, null);
+ if (operator == Operator.NOT_EQUAL && v != null) {
+ // not supported
+ return;
+ }
+ String fn = getFunction(f.getSelector());
+ if (fn != null) {
+ f.restrictProperty(QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ operator, v, PropertyType.LONG);
+ }
}
@Override
@@ -109,13 +120,17 @@ public class LengthImpl extends DynamicO
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- // optimizations of the type "upper(length(x)) = '1'" are not supported
+ public String getFunction(SelectorImpl s) {
+ String f = operand.getFunction(s);
+ if (f == null) {
+ return null;
+ }
+ return "length*" + f;
}
@Override
public boolean canRestrictSelector(SelectorImpl s) {
- return propertyValue.canRestrictSelector(s);
+ return operand.canRestrictSelector(s);
}
@Override
@@ -125,7 +140,20 @@ public class LengthImpl extends DynamicO
@Override
public DynamicOperandImpl createCopy() {
- return new LengthImpl(propertyValue.createCopy());
+ return new LengthImpl(operand.createCopy());
+ }
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ String fn = getFunction(s);
+ if (fn != null) {
+ return new OrderEntry(
+ QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ Type.LONG,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
+ return null;
}
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -24,8 +24,11 @@ import java.util.Set;
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
import com.google.common.base.Function;
@@ -94,7 +97,15 @@ public class LowerCaseImpl extends Dynam
public void restrict(FilterImpl f, Operator operator, PropertyValue v) {
// LOWER(x) implies x is not null
operand.restrict(f, Operator.NOT_EQUAL, null);
- operand.restrictFunction(f, "lower", operator, v);
+ if (operator == Operator.NOT_EQUAL && v != null) {
+ // not supported
+ return;
+ }
+ String fn = getFunction(f.getSelector());
+ if (fn != null) {
+ f.restrictProperty(QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ operator, v, PropertyType.STRING);
+ }
}
@Override
@@ -102,10 +113,14 @@ public class LowerCaseImpl extends Dynam
// "LOWER(x) IN (A, B)" implies x is not null
operand.restrict(f, Operator.NOT_EQUAL, null);
}
-
+
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- // optimizations of the type "lower(upper(x)) = 'x'" are not currently supported
+ public String getFunction(SelectorImpl s) {
+ String f = operand.getFunction(s);
+ if (f == null) {
+ return null;
+ }
+ return "lower*" + f;
}
@Override
@@ -122,5 +137,18 @@ public class LowerCaseImpl extends Dynam
public DynamicOperandImpl createCopy() {
return new LowerCaseImpl(operand.createCopy());
}
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ String fn = getFunction(s);
+ if (fn != null) {
+ return new OrderEntry(
+ QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ Type.STRING,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
+ return null;
+ }
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -25,10 +25,12 @@ import java.util.Set;
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
/**
* The function "localname(..)".
@@ -89,6 +91,10 @@ public class NodeLocalNameImpl extends D
if (v == null) {
return;
}
+ if (operator == Operator.NOT_EQUAL && v != null) {
+ // not supported
+ return;
+ }
String name = NodeNameImpl.getName(query, v);
if (name != null && f.getSelector().equals(selector)
&& NodeNameImpl.supportedOperator(operator)) {
@@ -103,25 +109,13 @@ public class NodeLocalNameImpl extends D
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- // optimizations of the type "lower(LOCALNAME(x)) = 'x'"
- if (operator == Operator.NOT_EQUAL) {
- // not supported
- return;
- }
- if (v == null) {
- return;
- }
- String name = NodeNameImpl.getName(query, v);
- if (name != null && f.getSelector().equals(selector)
- && NodeNameImpl.supportedOperator(operator)) {
- String restrictionName = QueryConstants.FUNCTION_RESTRICTION_PREFIX +
- functionName + "*@" + QueryConstants.RESTRICTION_LOCAL_NAME;
- f.restrictProperty(restrictionName,
- operator, PropertyValues.newString(name));
+ public String getFunction(SelectorImpl s) {
+ if (!s.equals(selector)) {
+ return null;
}
+ return "@" + QueryConstants.RESTRICTION_LOCAL_NAME;
}
-
+
@Override
public boolean supportsRangeConditions() {
return false;
@@ -141,5 +135,18 @@ public class NodeLocalNameImpl extends D
public DynamicOperandImpl createCopy() {
return new NodeLocalNameImpl(selectorName);
}
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ if (!s.equals(selector)) {
+ // ordered by a different selector
+ return null;
+ }
+ return new OrderEntry(
+ QueryConstants.RESTRICTION_LOCAL_NAME,
+ Type.STRING,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -32,6 +32,7 @@ import org.apache.jackrabbit.oak.query.Q
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
import org.apache.jackrabbit.util.ISO9075;
/**
@@ -91,6 +92,10 @@ public class NodeNameImpl extends Dynami
if (v == null) {
return;
}
+ if (operator == Operator.NOT_EQUAL && v != null) {
+ // not supported
+ return;
+ }
String name = getName(query, v);
if (name != null && f.getSelector().equals(selector)
&& NodeNameImpl.supportedOperator(operator)) {
@@ -106,23 +111,11 @@ public class NodeNameImpl extends Dynami
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- if (operator == Operator.NOT_EQUAL) {
- // not supported
- return;
- }
- if (v == null) {
- return;
- }
- String name = getName(query, v);
- if (name != null && f.getSelector().equals(selector)
- && NodeNameImpl.supportedOperator(operator)) {
- String localName = NodeLocalNameImpl.getLocalName(name);
- String restrictionName = QueryConstants.FUNCTION_RESTRICTION_PREFIX +
- functionName + "*@" + QueryConstants.RESTRICTION_LOCAL_NAME;
- f.restrictProperty(restrictionName,
- operator, PropertyValues.newString(localName));
+ public String getFunction(SelectorImpl s) {
+ if (!s.equals(selector)) {
+ return null;
}
+ return "@" + QueryConstants.RESTRICTION_NAME;
}
@Override
@@ -179,5 +172,18 @@ public class NodeNameImpl extends Dynami
public DynamicOperandImpl createCopy() {
return new NodeNameImpl(selectorName);
}
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ if (!s.equals(selector)) {
+ // ordered by a different selector
+ return null;
+ }
+ return new OrderEntry(
+ QueryConstants.RESTRICTION_NAME,
+ Type.STRING,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -31,7 +31,7 @@ import org.apache.jackrabbit.oak.query.Q
import org.apache.jackrabbit.oak.query.SQL2Parser;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Filter.PathRestriction;
-import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
/**
* A property expression.
@@ -143,17 +143,12 @@ public class PropertyValueImpl extends D
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- if (operator == Operator.NOT_EQUAL) {
- // not supported
- return;
- }
- if (f.getSelector().equals(selector)) {
- String pn = normalizePropertyName(propertyName);
- String restrictionName = QueryConstants.FUNCTION_RESTRICTION_PREFIX +
- functionName + "*@" + pn;
- f.restrictProperty(restrictionName, operator, v, propertyType);
+ public String getFunction(SelectorImpl s) {
+ if (!s.equals(selector)) {
+ return null;
}
+ String pn = normalizePropertyName(propertyName);
+ return "@" + pn;
}
@Override
@@ -170,4 +165,19 @@ public class PropertyValueImpl extends D
public PropertyValueImpl createCopy() {
return new PropertyValueImpl(selectorName, propertyName);
}
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ if (!s.equals(selector)) {
+ // ordered by a different selector
+ return null;
+ }
+ String pn = normalizePropertyName(propertyName);
+ return new OrderEntry(
+ pn,
+ Type.UNDEFINED,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
+
}
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -24,8 +24,11 @@ import java.util.Set;
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
import static org.apache.jackrabbit.oak.api.Type.STRING;
@@ -80,7 +83,15 @@ public class UpperCaseImpl extends Dynam
public void restrict(FilterImpl f, Operator operator, PropertyValue v) {
// UPPER(x) implies x is not null
operand.restrict(f, Operator.NOT_EQUAL, null);
- operand.restrictFunction(f, "upper", operator, v);
+ if (operator == Operator.NOT_EQUAL && v != null) {
+ // not supported
+ return;
+ }
+ String fn = getFunction(f.getSelector());
+ if (fn != null) {
+ f.restrictProperty(QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ operator, v, PropertyType.STRING);
+ }
}
@Override
@@ -90,9 +101,13 @@ public class UpperCaseImpl extends Dynam
}
@Override
- public void restrictFunction(FilterImpl f, String functionName, Operator operator, PropertyValue v) {
- // optimizations of the type "lower(upper(x)) = 'x'" are not supported
- }
+ public String getFunction(SelectorImpl s) {
+ String f = operand.getFunction(s);
+ if (f == null) {
+ return null;
+ }
+ return "upper*" + f;
+ }
@Override
public boolean canRestrictSelector(SelectorImpl s) {
@@ -108,5 +123,18 @@ public class UpperCaseImpl extends Dynam
public DynamicOperandImpl createCopy() {
return new UpperCaseImpl(operand.createCopy());
}
+
+ @Override
+ public OrderEntry getOrderEntry(SelectorImpl s, OrderingImpl o) {
+ String fn = getFunction(s);
+ if (fn != null) {
+ return new OrderEntry(
+ QueryConstants.FUNCTION_RESTRICTION_PREFIX + fn,
+ Type.STRING,
+ o.isDescending() ?
+ OrderEntry.Order.DESCENDING : OrderEntry.Order.ASCENDING);
+ }
+ return null;
+ }
}
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=1759820&r1=1759819&r2=1759820&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 Sep 8 13:34:38 2016
@@ -651,6 +651,11 @@ public class XPathToSQL2Converter {
f.params.add(parseExpression());
read(")");
return f;
+ } else if ("fn:string-length".equals(functionName)) {
+ Expression.Function f = new Expression.Function("length");
+ f.params.add(parseExpression());
+ read(")");
+ return f;
} else if ("fn:name".equals(functionName)) {
Expression.Function f = new Expression.Function("name");
if (!readIf(")")) {
@@ -658,6 +663,15 @@ public class XPathToSQL2Converter {
read(".");
read(")");
}
+ f.params.add(new Expression.SelectorExpr(currentSelector));
+ return f;
+ } else if ("fn:local-name".equals(functionName)) {
+ Expression.Function f = new Expression.Function("localname");
+ if (!readIf(")")) {
+ // only localname(.) and localname() are currently supported
+ read(".");
+ read(")");
+ }
f.params.add(new Expression.SelectorExpr(currentSelector));
return f;
} else if ("jcr:deref".equals(functionName)) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java?rev=1759820&r1=1759819&r2=1759820&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java Thu Sep 8 13:34:38 2016
@@ -26,7 +26,13 @@ public abstract class QueryConstants {
* via NAME and LOCALNAME functions
*/
public static final String RESTRICTION_LOCAL_NAME = ":localname";
-
+
+ /**
+ * Name of the property restriction used to express query performed
+ * via NAME and LOCALNAME functions
+ */
+ public static final String RESTRICTION_NAME = ":name";
+
/**
* The prefix for restrictions for function-based indexes, for example
* upper(propertyName). Syntax: "function*expression". In order to support
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -321,7 +321,7 @@ public abstract class AbstractQueryTest
assertTrue("Expected path " + p + " not found, got " + actual, checkNotNull(actual)
.contains(p));
}
- assertEquals("Result set size is different", expected.size(),
+ assertEquals("Result set size is different: " + actual, expected.size(),
actual.size());
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java?rev=1759820&r1=1759819&r2=1759820&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java Thu Sep 8 13:34:38 2016
@@ -71,13 +71,13 @@ public class FilterTest {
assertEquals("Filter(query=select [jcr:path] from [nt:base] " +
"where upper(name()) = 'ACME:TEST', " +
"path=*, property=[" +
- "function*upper*@:localname=[TEST]])", createFilterSQL(sql2).toString());
+ "function*upper*@:name=[ACME:TEST]])", createFilterSQL(sql2).toString());
- sql2 = "select [jcr:path] from [nt:base] where lower(localname()) = 'test'";
+ sql2 = "select [jcr:path] from [nt:base] where lower(localname()) > 'test'";
assertEquals("Filter(query=select [jcr:path] from [nt:base] " +
- "where lower(localname()) = 'test', " +
+ "where lower(localname()) > 'test', " +
"path=*, property=[" +
- "function*lower*@:localname=[test]])", createFilterSQL(sql2).toString());
+ "function*lower*@:localname=[(test..]])", createFilterSQL(sql2).toString());
sql2 = "select [jcr:path] from [nt:base] where length([test]) <= 10";
assertEquals("Filter(query=select [jcr:path] from [nt:base] " +
@@ -85,13 +85,11 @@ public class FilterTest {
"path=*, property=[function*length*@test=[..10]], " +
"test=[is not null]])", createFilterSQL(sql2).toString());
- sql2 = "select [jcr:path] from [nt:base] where length([test]) > 2";
+ sql2 = "select [jcr:path] from [nt:base] where length([data/test]) > 2";
assertEquals("Filter(query=select [jcr:path] from [nt:base] " +
- "where length([test]) > 2, " +
- "path=*, property=[function*length*@test=[(2..], " +
- "test=[is not null]])", createFilterSQL(sql2).toString());
-
-
+ "where length([data/test]) > 2, " +
+ "path=*, property=[data/test=[is not null], " +
+ "function*length*@data/test=[(2..]])", createFilterSQL(sql2).toString());
}
@Test
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=1759820&r1=1759819&r2=1759820&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 Thu Sep 8 13:34:38 2016
@@ -468,6 +468,11 @@ select [jcr:path]
select [jcr:path]
from [nt:base]
+ where upper(name) = '10%'
+/testRoot/test4
+
+select [jcr:path]
+ from [nt:base]
where upper(name) like '10\%'
/testRoot/test4