Author: thomasm
Date: Wed Oct 19 12:20:56 2016
New Revision: 1765583
URL: http://svn.apache.org/viewvc?rev=1765583&view=rev
Log:
OAK-4888 Warn or fail queries above a configurable cost value
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryOptions.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/QueryEngineSettingsMBean.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
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/QueryEngineSettings.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsMBeanImpl.java
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/UnionQueryImpl.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/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/QueryEngineSettingsMBean.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/QueryEngineSettingsMBean.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/QueryEngineSettingsMBean.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/QueryEngineSettingsMBean.java
Wed Oct 19 12:20:56 2016
@@ -51,4 +51,19 @@ public interface QueryEngineSettingsMBea
*/
void setLimitReads(long limitReads);
+ /**
+ * Whether queries that don't use an index will fail (throw an exception).
+ * The default is false.
+ *
+ * @return true if they fail
+ */
+ boolean getFailTraversal();
+
+ /**
+ * Set whether queries that don't use an index will fail (throw an
exception).
+ *
+ * @param failTraversal the new value for this setting
+ */
+ void setFailTraversal(boolean failTraversal);
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/package-info.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/package-info.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/jmx/package-info.java
Wed Oct 19 12:20:56 2016
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-@Version("4.0.0")
+@Version("5.0.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.api.jmx;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
Wed Oct 19 12:20:56 2016
@@ -434,7 +434,7 @@ public class ContentMirrorStoreStrategy
readCount++;
if (readCount % TRAVERSING_WARN == 0) {
FilterIterators.checkReadLimit(readCount,
settings);
- LOG.warn("Traversed {} nodes ({} index entries)
using index {} with filter {}", readCount, intermediateNodeReadCount,
indexName, filter);
+ LOG.warn("Index-Traversed {} nodes ({} index
entries) using index {} with filter {}", readCount, intermediateNodeReadCount,
indexName, filter);
}
return;
} else {
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=1765583&r1=1765582&r2=1765583&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 Oct 19 12:20:56 2016
@@ -183,4 +183,11 @@ public interface Query {
*/
boolean containsUnfilteredFullTextCondition();
+ /**
+ * Set the query option to be used for this query.
+ *
+ * @param options the options
+ */
+ void setQueryOptions(QueryOptions options);
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettings.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettings.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettings.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettings.java
Wed Oct 19 12:20:56 2016
@@ -35,7 +35,10 @@ public class QueryEngineSettings impleme
Integer.getInteger("oak.queryLimitInMemory", Integer.MAX_VALUE);
private static final int DEFAULT_QUERY_LIMIT_READS =
- Integer.getInteger("oak.queryLimitReads", Integer.MAX_VALUE);
+ Integer.getInteger("oak.queryLimitReads", Integer.MAX_VALUE);
+
+ private static final boolean DEFAULT_FAIL_TRAVERSAL =
+ Boolean.getBoolean("oak.queryFailTraversal");
private static final boolean DEFAULT_FULL_TEXT_COMPARISON_WITHOUT_INDEX =
Boolean.getBoolean("oak.queryFullTextComparisonWithoutIndex");
@@ -44,6 +47,8 @@ public class QueryEngineSettings impleme
private long limitReads = DEFAULT_QUERY_LIMIT_READS;
+ private boolean failTraversal = DEFAULT_FAIL_TRAVERSAL;
+
private boolean fullTextComparisonWithoutIndex =
DEFAULT_FULL_TEXT_COMPARISON_WITHOUT_INDEX;
@@ -72,6 +77,16 @@ public class QueryEngineSettings impleme
this.limitReads = limitReads;
}
+ @Override
+ public boolean getFailTraversal() {
+ return failTraversal;
+ }
+
+ @Override
+ public void setFailTraversal(boolean failTraversal) {
+ this.failTraversal = failTraversal;
+ }
+
public void setFullTextComparisonWithoutIndex(boolean
fullTextComparisonWithoutIndex) {
this.fullTextComparisonWithoutIndex = fullTextComparisonWithoutIndex;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsMBeanImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsMBeanImpl.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsMBeanImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsMBeanImpl.java
Wed Oct 19 12:20:56 2016
@@ -70,6 +70,16 @@ public class QueryEngineSettingsMBeanImp
settings.setLimitReads(limitReads);
}
+ @Override
+ public boolean getFailTraversal() {
+ return settings.getFailTraversal();
+ }
+
+ @Override
+ public void setFailTraversal(boolean failQueriesWithoutIndex) {
+ settings.setFailTraversal(failQueriesWithoutIndex);
+ }
+
public void setFullTextComparisonWithoutIndex(boolean
fullTextComparisonWithoutIndex) {
settings.setFullTextComparisonWithoutIndex(fullTextComparisonWithoutIndex);
}
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=1765583&r1=1765582&r2=1765583&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
Wed Oct 19 12:20:56 2016
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.api.Res
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.QueryOptions.Traversal;
import org.apache.jackrabbit.oak.query.ast.AndImpl;
import org.apache.jackrabbit.oak.query.ast.AstVisitorBase;
import org.apache.jackrabbit.oak.query.ast.BindVariableValueImpl;
@@ -160,6 +161,11 @@ public class QueryImpl implements Query
* purposes.
*/
private boolean traversalEnabled = true;
+
+ /**
+ * The query option to be used for this query.
+ */
+ private QueryOptions queryOptions = new QueryOptions();
private OrderingImpl[] orderings;
private ColumnImpl[] columns;
@@ -948,6 +954,11 @@ public class QueryImpl implements Query
this.traversalEnabled = traversalEnabled;
}
+ @Override
+ public void setQueryOptions(QueryOptions options) {
+ this.queryOptions = options;
+ }
+
public SelectorExecutionPlan getBestSelectorExecutionPlan(FilterImpl
filter) {
return getBestSelectorExecutionPlan(context.getBaseState(), filter,
context.getIndexProvider(), traversalEnabled);
@@ -1036,7 +1047,27 @@ public class QueryImpl implements Query
bestPlan = indexPlan;
}
}
-
+ if (bestIndex == null) {
+ QueryOptions.Traversal traversal = queryOptions.traversal;
+ if (traversal == Traversal.DEFAULT) {
+ // use the (configured) default
+ traversal = settings.getFailTraversal() ? Traversal.FAIL :
Traversal.WARN;
+ } else {
+ // explicitly set in the query
+ traversal = queryOptions.traversal;
+ }
+ String message = "Traversal query (query without index): " +
statement + "; consider creating an index";
+ switch (traversal) {
+ case OK:
+ break;
+ case WARN:
+ LOG.warn(message);
+ break;
+ case FAIL:
+ LOG.warn(message);
+ throw new IllegalArgumentException(message);
+ }
+ }
if (traversalEnabled) {
QueryIndex traversal = new TraversingIndex();
double cost = traversal.getCost(filter, rootState);
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryOptions.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryOptions.java?rev=1765583&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryOptions.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryOptions.java
Wed Oct 19 12:20:56 2016
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+/**
+ * A query options (or "hints") that are used to customize the way the query
is processed.
+ */
+public class QueryOptions {
+
+ public Traversal traversal = Traversal.DEFAULT;
+
+ public enum Traversal {
+ // traversing without index is OK for this query, and does not fail or
log a warning
+ OK,
+ // traversing is OK, but logs a warning
+ WARN,
+ // traversing will fail the query
+ FAIL,
+ // the default setting
+ DEFAULT
+ };
+
+}
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=1765583&r1=1765582&r2=1765583&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 Oct 19 12:20:56 2016
@@ -24,6 +24,7 @@ import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import javax.jcr.PropertyType;
@@ -34,6 +35,7 @@ import org.apache.jackrabbit.oak.api.Que
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.query.QueryOptions.Traversal;
import org.apache.jackrabbit.oak.query.ast.AstElementFactory;
import org.apache.jackrabbit.oak.query.ast.BindVariableValueImpl;
import org.apache.jackrabbit.oak.query.ast.ColumnImpl;
@@ -161,6 +163,15 @@ public class SQL2Parser {
read("BY");
orderings = parseOrder();
}
+ QueryOptions options = new QueryOptions();
+ if (readIf("OPTION")) {
+ read("(");
+ if (readIf("TRAVERSAL")) {
+ String n = readName().toUpperCase(Locale.ENGLISH);
+ options.traversal = Traversal.valueOf(n);
+ }
+ read(")");
+ }
if (!currentToken.isEmpty()) {
throw getSyntaxError("<end>");
}
@@ -168,6 +179,7 @@ public class SQL2Parser {
q.setExplain(explain);
q.setMeasure(measure);
q.setInternal(isInternal(query));
+ q.setQueryOptions(options);
if (initialise) {
try {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
Wed Oct 19 12:20:56 2016
@@ -118,6 +118,12 @@ public class UnionQueryImpl implements Q
left.setTraversalEnabled(traversal);
right.setTraversalEnabled(traversal);
}
+
+ @Override
+ public void setQueryOptions(QueryOptions options) {
+ left.setQueryOptions(options);
+ right.setQueryOptions(options);
+ }
@Override
public void prepare() {
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=1765583&r1=1765582&r2=1765583&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
Wed Oct 19 12:20:56 2016
@@ -19,6 +19,8 @@ package org.apache.jackrabbit.oak.query.
import java.util.ArrayList;
import org.apache.jackrabbit.oak.query.QueryImpl;
+import org.apache.jackrabbit.oak.query.QueryOptions;
+import org.apache.jackrabbit.oak.query.QueryOptions.Traversal;
import org.apache.jackrabbit.oak.query.xpath.Expression.AndCondition;
import org.apache.jackrabbit.oak.query.xpath.Expression.OrCondition;
import org.apache.jackrabbit.oak.query.xpath.Expression.Property;
@@ -50,6 +52,8 @@ public class Statement {
String xpathQuery;
+ QueryOptions queryOptions = new QueryOptions();
+
public Statement optimize() {
ignoreOrderByScoreDesc();
if (where == null) {
@@ -80,6 +84,7 @@ public class Statement {
union.xpathQuery = xpathQuery;
union.measure = measure;
union.explain = explain;
+ union.queryOptions = queryOptions;
return union;
}
@@ -209,6 +214,9 @@ public class Statement {
buff.append(orderList.get(i));
}
}
+ if (queryOptions.traversal != Traversal.DEFAULT) {
+ buff.append(" option(traversal " + queryOptions.traversal +")");
+ }
// leave original xpath string as a comment
appendXPathAsComment(buff, xpathQuery);
return buff.toString();
@@ -296,6 +304,9 @@ public class Statement {
buff.append(orderList.get(i));
}
}
+ if (queryOptions.traversal != Traversal.DEFAULT) {
+ buff.append(" option(traversal " + queryOptions.traversal
+")");
+ }
// leave original xpath string as a comment
appendXPathAsComment(buff, xpathQuery);
return buff.toString();
@@ -314,4 +325,8 @@ public class Statement {
buff.append(" */");
}
+ public void setQueryOptions(QueryOptions options) {
+ this.queryOptions = options;
+ }
+
}
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=1765583&r1=1765582&r2=1765583&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
Wed Oct 19 12:20:56 2016
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.oak.query.xpath;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.query.QueryOptions;
+import org.apache.jackrabbit.oak.query.QueryOptions.Traversal;
import org.apache.jackrabbit.oak.query.xpath.Statement.UnionStatement;
import org.apache.jackrabbit.util.ISO9075;
import org.slf4j.Logger;
@@ -25,6 +27,7 @@ import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Locale;
/**
* This class can can convert a XPATH query to a SQL2 query.
@@ -324,11 +327,21 @@ public class XPathToSQL2Converter {
statement.addOrderBy(order);
} while (readIf(","));
}
+ QueryOptions options = new QueryOptions();
+ if (readIf("option")) {
+ read("(");
+ if (readIf("traversal")) {
+ String type = readIdentifier().toUpperCase(Locale.ENGLISH);
+ options.traversal = Traversal.valueOf(type);
+ }
+ read(")");
+ }
if (!currentToken.isEmpty()) {
throw getSyntaxError("<end>");
}
statement.setColumnSelector(currentSelector);
statement.setSelectors(selectors);
+ statement.setQueryOptions(options);
Expression where = null;
for (Selector s : selectors) {
@@ -1105,10 +1118,14 @@ public class XPathToSQL2Converter {
} else {
UnionStatement union = new UnionStatement(result, stat);
union.orderList = stat.orderList;
+ union.queryOptions = stat.queryOptions;
result = union;
}
- // can not use clear, because it is shared
+ // reset fields that are used in the union,
+ // but no longer in the individual statements
+ // (can not use clear, because it is shared)
stat.orderList = new ArrayList<Order>();
+ stat.queryOptions = new QueryOptions();
}
return result;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
Wed Oct 19 12:20:56 2016
@@ -54,7 +54,6 @@ public class SQL2ParserTest {
.convert("/jcr:root/test/*/nt:resource[@jcr:encoding]"));
p.parse(new XPathToSQL2Converter()
.convert("/jcr:root/test/*/*/nt:resource[@jcr:encoding]"));
-
String xpath = "/jcr:root/etc/commerce/products//*[@cq:commerceType =
'product' " +
"and ((@size = 'M' or */@size= 'M' or */*/@size = 'M' " +
"or */*/*/@size = 'M' or */*/*/*/@size = 'M' or
*/*/*/*/*/@size = 'M'))]";
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
Wed Oct 19 12:20:56 2016
@@ -34,6 +34,45 @@ public class XPathTest {
new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
@Test
+ public void queryOptions() throws ParseException {
+ verify("/jcr:root/content//*[@a] order by @c option(traversal fail)",
+ "select [jcr:path], [jcr:score], * " +
+ "from [nt:base] as a " +
+ "where [a] is not null " +
+ "and isdescendantnode(a, '/content') " +
+ "order by [c] option(traversal FAIL) " +
+ "/* xpath: /jcr:root/content//*[@a] " +
+ "order by @c " +
+ "option(traversal fail) */");
+ verify("//*[@a or @b] order by @c option(traversal warn)",
+ "select [jcr:path], [jcr:score], * " +
+ "from [nt:base] as a " +
+ "where [a] is not null " +
+ "union select [jcr:path], [jcr:score], * " +
+ "from [nt:base] as a " +
+ "where [b] is not null " +
+ "order by [c] option(traversal WARN) " +
+ "/* xpath: //*[@a or @b] " +
+ "order by @c " +
+ "option(traversal warn) */");
+ verify("/jcr:root/(content|libs)//*[@a] order by @c option(traversal
ok)",
+ "select [jcr:path], [jcr:score], * " +
+ "from [nt:base] as a " +
+ "where [a] is not null " +
+ "and isdescendantnode(a, '/content') " +
+ "/* xpath: /jcr:root/content//*[@a] " +
+ "order by @c option(traversal ok) */ " +
+ "union select [jcr:path], [jcr:score], * " +
+ "from [nt:base] as a " +
+ "where [a] is not null " +
+ "and isdescendantnode(a, '/libs') " +
+ "/* xpath: /jcr:root/libs//*[@a] " +
+ "order by @c option(traversal ok) */ " +
+ "order by [c] " +
+ "option(traversal OK)");
+ }
+
+ @Test
public void test() throws ParseException {
verify("(/jcr:root/content//*[@a] | /jcr:root/lib//*[@b]) order by @c",
"select [jcr:path], [jcr:score], * " +
@@ -121,6 +160,7 @@ public class XPathTest {
sql = sql.replaceAll(" and ", "\nand ");
sql = sql.replaceAll(" union ", "\nunion ");
sql = sql.replaceAll(" order by ", "\norder by ");
+ sql = sql.replaceAll(" option\\(", "\noption\\(");
sql = sql.replaceAll(" \\/\\* ", "\n/* ");
return sql;
}
Modified:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java?rev=1765583&r1=1765582&r2=1765583&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
Wed Oct 19 12:20:56 2016
@@ -69,6 +69,34 @@ public class QueryTest extends AbstractR
}
@Test
+ public void traversalOption() throws Exception {
+ Session session = getAdminSession();
+ QueryManager qm = session.getWorkspace().getQueryManager();
+ try {
+ qm.createQuery("//*[@test] option(traversal fail)",
+ "xpath").execute();
+ fail();
+ } catch (InvalidQueryException e) {
+ // expected
+ }
+ try {
+ qm.createQuery("select * from [nt:base] option(traversal fail)",
+ Query.JCR_SQL2).execute();
+ fail();
+ } catch (InvalidQueryException e) {
+ // expected
+ }
+ qm.createQuery("//*[@test] option(traversal ok)",
+ "xpath").execute();
+ qm.createQuery("//*[@test] option(traversal warn)",
+ "xpath").execute();
+ qm.createQuery("select * from [nt:base] option(traversal ok)",
+ Query.JCR_SQL2).execute();
+ qm.createQuery("select * from [nt:base] option(traversal warn)",
+ Query.JCR_SQL2).execute();
+ }
+
+ @Test
public void firstSelector() throws Exception {
Session session = getAdminSession();
Node root = session.getRootNode();