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 2014/02/27 11:18:25 UTC
svn commit: r1572496 - 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/
test/java/org/apache/jackrabbit/oak/plugins/index/p...
Author: thomasm
Date: Thu Feb 27 10:18:24 2014
New Revision: 1572496
URL: http://svn.apache.org/r1572496
Log:
OAK-1325 Support native pass-through queries (e.g. Lucene)
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_native.txt
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/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/xpath/Expression.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexQueryTest.java
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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -46,6 +46,7 @@ import org.apache.jackrabbit.oak.query.a
import org.apache.jackrabbit.oak.query.ast.LengthImpl;
import org.apache.jackrabbit.oak.query.ast.LiteralImpl;
import org.apache.jackrabbit.oak.query.ast.LowerCaseImpl;
+import org.apache.jackrabbit.oak.query.ast.NativeFunctionImpl;
import org.apache.jackrabbit.oak.query.ast.NodeLocalNameImpl;
import org.apache.jackrabbit.oak.query.ast.NodeNameImpl;
import org.apache.jackrabbit.oak.query.ast.NotImpl;
@@ -194,6 +195,13 @@ public class QueryImpl implements Query
}
@Override
+ public boolean visit(NativeFunctionImpl node) {
+ node.setQuery(query);
+ node.bindSelector(source);
+ return super.visit(node);
+ }
+
+ @Override
public boolean visit(FullTextSearchScoreImpl node) {
node.setQuery(query);
node.bindSelector(source);
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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -513,6 +513,17 @@ public class SQL2Parser {
} else {
c = factory.descendantNode(getOnlySelectorName(), name);
}
+ } else if ("NATIVE".equalsIgnoreCase(functionName)) {
+ String selectorName;
+ if (currentTokenType == IDENTIFIER) {
+ selectorName = readName();
+ read(",");
+ } else {
+ selectorName = getOnlySelectorName();
+ }
+ String language = readString().getValue(Type.STRING);
+ read(",");
+ c = factory.nativeFunction(selectorName, language, parseStaticOperand());
} else {
return 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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -148,4 +148,8 @@ public class AstElementFactory {
return new InImpl(left, list);
}
+ public NativeFunctionImpl nativeFunction(String selectorName, String language, StaticOperandImpl expression) {
+ return new NativeFunctionImpl(selectorName, language, expression);
+ }
+
}
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=1572496&r1=1572495&r2=1572496&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 Thu Feb 27 10:18:24 2014
@@ -79,4 +79,6 @@ public interface AstVisitor {
boolean visit(UpperCaseImpl node);
+ boolean visit(NativeFunctionImpl nativeFunctionImpl);
+
}
\ No newline at end of file
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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -63,6 +63,14 @@ public abstract class AstVisitorBase imp
node.getFullTextSearchExpression().accept(this);
return true;
}
+
+ /**
+ * Calls accept on the static operand in the native search constraint.
+ */
+ @Override
+ public boolean visit(NativeFunctionImpl node) {
+ return true;
+ }
/**
* Calls accept on the two sources and the join condition in the join node.
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java?rev=1572496&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java Thu Feb 27 10:18:24 2014
@@ -0,0 +1,115 @@
+/*
+ * 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.Collections;
+import java.util.Map;
+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.FulltextQueryIndex;
+
+/**
+ * A native function condition.
+ */
+public class NativeFunctionImpl extends ConstraintImpl {
+
+ public static final String NATIVE_PREFIX = "native*";
+
+ private final String selectorName;
+ private final String language;
+ private final StaticOperandImpl nativeSearchExpression;
+ private SelectorImpl selector;
+
+ NativeFunctionImpl(String selectorName, String language, StaticOperandImpl expression) {
+ this.selectorName = selectorName;
+ this.language = language;
+ this.nativeSearchExpression = expression;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("native(");
+ builder.append(quote(selectorName));
+ builder.append(", ");
+ builder.append(quote(language));
+ builder.append(", ");
+ builder.append(getNativeSearchExpression());
+ builder.append(')');
+ return builder.toString();
+ }
+
+ @Override
+ public boolean evaluate() {
+ // disable evaluation if a fulltext index is used,
+ // and because we don't know how to process native
+ // conditions
+ if (!(selector.getIndex() instanceof FulltextQueryIndex)) {
+ throw new IllegalArgumentException("No full-text index was found that can process the condition " + toString());
+ }
+ // we assume the index only returns the requested entries
+ return true;
+ }
+
+ @Override
+ public Set<PropertyExistenceImpl> getPropertyExistenceConditions() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Map<DynamicOperandImpl, Set<StaticOperandImpl>> getInMap() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public void restrict(FilterImpl f) {
+ if (f.getSelector().equals(selector)) {
+ PropertyValue v = nativeSearchExpression.currentValue();
+ f.restrictProperty(NATIVE_PREFIX + language, Operator.EQUAL, v);
+ }
+ }
+
+ @Override
+ public void restrictPushDown(SelectorImpl s) {
+ if (s.equals(selector)) {
+ selector.restrictSelector(this);
+ }
+ }
+
+ @Override
+ public Set<SelectorImpl> getSelectors() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ boolean accept(AstVisitor v) {
+ return v.visit(this);
+ }
+
+ public void bindSelector(SourceImpl source) {
+ selector = source.getExistingSelector(selectorName);
+ }
+
+ public StaticOperandImpl getNativeSearchExpression() {
+ return nativeSearchExpression;
+ }
+
+}
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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -325,6 +325,40 @@ abstract class Expression {
}
}
+
+ /**
+ * A native call.
+ */
+ static class NativeFunction extends Expression {
+
+ final String selector;
+ final Expression language, expression;
+
+ NativeFunction(String selector, Expression language, Expression expression) {
+ this.selector = selector;
+ this.language = language;
+ this.expression = expression;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buff = new StringBuilder("native(");
+ buff.append(selector);
+ buff.append(", ").append(language).append(", ").append(expression).append(')');
+ return buff.toString();
+ }
+
+ @Override
+ boolean isCondition() {
+ return true;
+ }
+
+ @Override
+ boolean isName() {
+ return false;
+ }
+
+ }
/**
* A function call.
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=1572496&r1=1572495&r2=1572496&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 Feb 27 10:18:24 2014
@@ -606,6 +606,14 @@ public class XPathToSQL2Converter {
} else if ("jcr:deref".equals(functionName)) {
// TODO maybe support jcr:deref
throw getSyntaxError("jcr:deref is not supported");
+ } else if ("rep:native".equals(functionName)) {
+ String selectorName = currentSelector.name;
+ Expression language = parseExpression();
+ read(",");
+ Expression expr = parseExpression();
+ read(")");
+ Expression.NativeFunction f = new Expression.NativeFunction(selectorName, language, expr);
+ return f;
} else if ("rep:similar".equals(functionName)) {
// TODO maybe support rep:similar
throw getSyntaxError("rep:similar is not supported");
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexQueryTest.java?rev=1572496&r1=1572495&r2=1572496&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexQueryTest.java Thu Feb 27 10:18:24 2014
@@ -50,6 +50,11 @@ public class PropertyIndexQueryTest exte
}
@Test
+ public void nativeQuery() throws Exception {
+ test("sql2_native.txt");
+ }
+
+ @Test
public void xpath() throws Exception {
test("xpath.txt");
}
Added: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_native.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_native.txt?rev=1572496&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_native.txt (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_native.txt Thu Feb 27 10:18:24 2014
@@ -0,0 +1,45 @@
+# 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.
+#
+# Syntax:
+# * lines that start with spaces belong to the previous line
+# * lines starting with "#" are remarks.
+# * lines starting with "select" are queries, followed by expected results and an empty line
+# * lines starting with "explain" are followed by expected query plan and an empty line
+# * lines starting with "sql1" are run using the sql1 language
+# * lines starting with "xpath2sql" are just converted from xpath to sql2
+# * all other lines are are committed into the microkernel (line by line)
+# * new tests are typically be added on top, after the syntax docs
+# * use ascii character only
+
+commit / + "test": { "a": { "name": "Hello" }, "b": { "name" : "World" }}
+
+select [jcr:path] from [nt:base]
+ where native('solr', 'name:(Hello OR World)')
+java.lang.IllegalArgumentException: No full-text index was found that can process the condition native([nt:base], [solr], cast('name:(Hello OR World)' as string))
+
+select [jcr:path] from [nt:base] as a
+ where native(a, 'solr', 'path_child:\/test _val_:"recip(rord(name),1,2,3)"')
+java.lang.IllegalArgumentException: No full-text index was found that can process the condition native([a], [solr], cast('path_child:\/test _val_:"recip(rord(name),1,2,3)"' as string))
+
+select [jcr:path] from [nt:base]
+ where native('solr', 'path_child:\/test _val_:"recip(rord(name),1,2,3)"')
+java.lang.IllegalArgumentException: No full-text index was found that can process the condition native([nt:base], [solr], cast('path_child:\/test _val_:"recip(rord(name),1,2,3)"' as string))
+
+xpath2sql //*[rep:native('solr', 'xyz')]
+select [jcr:path], [jcr:score], *
+ from [nt:base] as a
+ where native(a, 'solr', 'xyz')
+ /* xpath ... */
\ No newline at end of file