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 2023/11/03 08:32:11 UTC
(jackrabbit-oak) 01/01: OAK-10527 Improve readability of the explain query output
This is an automated email from the ASF dual-hosted git repository.
thomasm pushed a commit to branch OAK-10527
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 8551bae413d52f4f8373e2ee0dc803e91b6030d4
Author: Thomas Mueller <th...@apache.org>
AuthorDate: Fri Nov 3 09:31:50 2023 +0100
OAK-10527 Improve readability of the explain query output
---
.../oak/plugins/index/nodetype/NodeTypeIndex.java | 5 +-
.../plugins/index/property/PropertyIndexPlan.java | 22 +-
.../plugins/index/reference/ReferenceIndex.java | 17 +-
.../jackrabbit/oak/query/QueryEngineImpl.java | 5 +-
.../jackrabbit/oak/query/QueryFormatter.java | 103 +++++++++
.../org/apache/jackrabbit/oak/query/QueryImpl.java | 4 -
.../jackrabbit/oak/query/ast/SelectorImpl.java | 9 +-
.../oak/query/index/TraversingIndex.java | 25 +-
.../index/nodetype/NodeTypeIndexQueryTest.java | 15 +-
.../index/property/MultiPropertyOrTest.java | 15 +-
.../index/property/OptionIndexTagTests.java | 8 +-
.../index/property/PropertyIndexDisabledTest.java | 12 +-
.../org/apache/jackrabbit/oak/query/sql2_index.txt | 253 ++++++++++++++-------
.../CompositeNodeStoreLuceneIndexTest.java | 20 +-
.../oak/composite/CompositeNodeStoreQueryTest.java | 10 +-
.../oak/jcr/query/QueryFormatterTest.java | 77 +++++++
.../index/lucene/LuceneIndexAugmentTest.java | 12 +-
.../index/lucene/LuceneIndexQueryCommonTest.java | 3 +-
.../lucene/LucenePropertyIndexCommonTest.java | 4 +-
.../index/lucene/LucenePropertyIndexTest.java | 117 +++++-----
.../dynamicBoost/LuceneDynamicBoostTest.java | 5 +-
.../property/SynchronousPropertyIndexTest.java | 4 +-
.../index/elastic/ElasticDynamicBoostTest.java | 5 +-
.../index/elastic/ElasticIndexQueryCommonTest.java | 16 +-
.../index/elastic/ElasticPropertyIndexTest.java | 2 +-
.../index/search/spi/query/FulltextIndex.java | 32 ++-
.../search/spi/query/FulltextIndexPlanner.java | 2 +-
.../oak/plugins/index/DynamicBoostCommonTest.java | 17 +-
.../oak/plugins/index/FunctionIndexCommonTest.java | 42 ++--
.../oak/plugins/index/IndexQueryCommonTest.java | 4 +-
.../oak/plugins/index/OrderByCommonTest.java | 24 +-
.../oak/plugins/index/PropertyIndexCommonTest.java | 16 +-
32 files changed, 599 insertions(+), 306 deletions(-)
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
index 672158d620..0f50c74ff6 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
@@ -102,7 +102,10 @@ class NodeTypeIndex implements QueryIndex, JcrConstants {
@Override
public String getPlan(Filter filter, NodeState root) {
- return "nodeType " + filter.toString();
+ return "nodeType\n" +
+ " path: " + filter.getPath() + "\n" +
+ " primaryTypes: " + filter.getPrimaryTypes().toString() + "\n" +
+ " mixinTypes: " + filter.getMixinTypes().toString() + "\n";
}
@Override
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
index 0c7e9d7cf7..22408fb72e 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
@@ -32,6 +32,7 @@ import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
import org.apache.jackrabbit.oak.plugins.index.IndexUtils;
import org.apache.jackrabbit.oak.plugins.index.cursor.Cursors;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.IndexStoreStrategy;
+import org.apache.jackrabbit.oak.query.SQL2Parser;
import org.apache.jackrabbit.oak.spi.filter.PathFilter;
import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
@@ -238,27 +239,30 @@ public class PropertyIndexPlan {
@Override
public String toString() {
- StringBuilder buffer = new StringBuilder("property ");
- buffer.append(name);
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("property ").append(name).append("\n");
+ buffer.append(" indexDefinition: /");
+ buffer.append(IndexConstants.INDEX_DEFINITIONS_NAME);
+ buffer.append("/").append(name).append("\n");
+ buffer.append(" estimatedCost: ").append(cost).append("\n");
+ buffer.append(" values: ");
if (values == null) {
- buffer.append(" IS NOT NULL");
+ buffer.append("all values in the index (warning: may be slow)");
} else if (values.isEmpty()) {
- buffer.append(" NOT APPLICABLE");
+ buffer.append("not applicable");
} else if (values.size() == 1) {
- buffer.append(" = ");
- buffer.append(values.iterator().next());
+ buffer.append(SQL2Parser.escapeStringLiteral(values.iterator().next()));
} else {
- buffer.append(" IN (");
boolean comma = false;
for (String value : values) {
if (comma) {
buffer.append(", ");
}
- buffer.append(value);
+ buffer.append(SQL2Parser.escapeStringLiteral(value));
comma = true;
}
- buffer.append(")");
}
+ buffer.append("\n");
return buffer.toString();
}
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
index 639e94aa80..438ede13c0 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
@@ -36,6 +36,7 @@ import java.util.Set;
import org.apache.jackrabbit.oak.plugins.index.property.Multiplexers;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.IndexStoreStrategy;
+import org.apache.jackrabbit.oak.query.SQL2Parser;
import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.query.Cursor;
@@ -163,23 +164,25 @@ class ReferenceIndex implements QueryIndex {
@Override
public String getPlan(Filter filter, NodeState root) {
- StringBuilder buff = new StringBuilder("reference");
+ StringBuilder buff = new StringBuilder();
+ buff.append("reference\n");
for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
if (pr.propertyType == REFERENCE) {
- buff.append(" PROPERTY([");
+ buff.append(" on: property([");
buff.append(pr.propertyName);
buff.append("], 'Reference') = ");
- buff.append(pr.first.getValue(STRING));
- return buff.toString();
+ buff.append(SQL2Parser.escapeStringLiteral(pr.first.getValue(STRING)));
+ break;
}
if (pr.propertyType == WEAKREFERENCE) {
- buff.append(" PROPERTY([");
+ buff.append(" on: property([");
buff.append(pr.propertyName);
buff.append("], 'WeakReference') = ");
- buff.append(pr.first.getValue(STRING));
- return buff.toString();
+ buff.append(SQL2Parser.escapeStringLiteral(pr.first.getValue(STRING)));
+ break;
}
}
+ buff.append("\n");
return buff.toString();
}
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
index 576cbab2f4..37a122e17a 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
@@ -151,7 +151,10 @@ public abstract class QueryEngineImpl implements QueryEngine {
if (isInternal) {
LOG.trace("Parsing {} statement: {}", language, statement);
} else {
- LOG.debug("Parsing {} statement: {}", language, statement);
+ if (LOG.isDebugEnabled()) {
+ String formattedStatement = QueryFormatter.format(statement, language);
+ LOG.debug("Parsing {} statement: {}", language, formattedStatement);
+ }
}
QueryEngineSettings settings = context.getSettings();
if (statement.length() > (settings.getQueryLengthErrorLimit())){
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryFormatter.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryFormatter.java
new file mode 100644
index 0000000000..3a2cd811b8
--- /dev/null
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryFormatter.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import java.util.Locale;
+
+/**
+ * Formatter for JCR queries in order to make them easier to read. Formatting is
+ * done on a best-effort basis.
+ *
+ * Warning: formatting is also done within e.g. string literals. So there is no
+ * guarantee that the formatted query is semantically equal to the original one!
+ */
+public class QueryFormatter {
+
+ /**
+ * Detect whether the query is an XPath query.
+ *
+ * @param query the query
+ * @param language the language, if known, or null
+ * @return true if xpath
+ */
+ public static boolean isXPath(String query, String language) {
+ if (language != null) {
+ return "xpath".equals(language);
+ }
+ query = query.trim().toLowerCase(Locale.ENGLISH);
+ // explain queries
+ if (query.startsWith("explain")) {
+ query = query.substring("explain".length()).trim();
+ if (query.startsWith("measure")) {
+ query = query.substring("explain".length()).trim();
+ }
+ }
+ // union queries
+ while (query.startsWith("(")) {
+ query = query.substring("(".length()).trim();
+ }
+ if (query.startsWith("select")) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Format the query into a more human-readable way, by adding newlines.
+ * Warning: newlines are also added inside e.g. string literals.
+ *
+ * @param query the query (may not be null)
+ * @param language the query language, or null if unknown
+ * @return the formatted query
+ */
+ public static String format(String query, String language) {
+ boolean xpath = isXPath(query, language);
+ if (xpath) {
+ return formatXPath(query);
+ } else {
+ return formatSQL(query);
+ }
+ }
+
+ private static String formatXPath(String query) {
+ query = query.replaceAll("\\[", "\\[\n ");
+ for (String term : new String[] {
+ "and ", "or ", "order by ", "option\\("
+ }) {
+ // xpath is case sensitive
+ query = query.replaceAll(" (" + term + ")", "\n $1");
+ }
+ // remove duplicate newlines
+ query = query.replaceAll("\n+", "\n");
+ return query;
+ }
+
+ private static String formatSQL(String query) {
+ for (String term : new String[] {
+ "union ", "from ", "where ", "and ", "or ", "order by ", "option\\("
+ }) {
+ // SQL is case insensitive, so we use (?i)
+ query = query.replaceAll("(?i) (" + term + ")", "\n $1");
+ }
+ // remove duplicate newlines
+ query = query.replaceAll("\n+", "\n");
+ return query;
+ }
+
+}
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
index eee7a71dfa..028c0dceab 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
@@ -1154,10 +1154,6 @@ public class QueryImpl implements Query {
almostBestPlan = p;
}
}
-
- if (indexPlan != null && indexPlan.getPlanName() != null) {
- indexName += "[" + indexPlan.getPlanName() + "]";
- }
} else {
cost = index.getCost(filter, rootState);
}
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
index 2e57f144b5..e097611bd9 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
@@ -25,7 +25,6 @@ import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -427,10 +426,14 @@ public class SelectorImpl extends SourceImpl {
buff.append(index.getPlan(createFilter(true), rootState));
}
} else {
- buff.append("no-index");
+ buff.append("no-index\n");
}
if (!selectorConstraints.isEmpty()) {
- buff.append(" where ").append(new AndImpl(selectorConstraints).toString());
+ // we could add the selector constraints here,
+ // but it turns out this distracts more than it helps -
+ // however for the JSON representation it would be useful,
+ // that's why I think it makes sense to keep the commented code for now
+ // buff.append(" selectorCondition: ").append(new AndImpl(selectorConstraints).toString()).append("\n");
}
buff.append(" */");
return buff.toString();
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
index b61ace1eb1..3f6a1e473f 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
@@ -158,7 +158,30 @@ public class TraversingIndex implements QueryIndex {
@Override
public String getPlan(Filter filter, NodeState rootState) {
- return "traverse \"" + filter.getPathPlan() + '"';
+ StringBuilder buff = new StringBuilder();
+ buff.append("traverse\n");
+ PathRestriction restriction = filter.getPathRestriction();
+ String path = filter.getPath();
+ switch (restriction) {
+ case EXACT:
+ buff.append(" oneNode: ").append(path);
+ break;
+ case PARENT:
+ buff.append(" parent: ").append(path);
+ break;
+ case NO_RESTRICTION:
+ buff.append(" allNodes (warning: slow)");
+ break;
+ case ALL_CHILDREN:
+ buff.append(" allDescendents: ").append(path);
+ break;
+ case DIRECT_CHILDREN:
+ buff.append(" onlyDirectChildren: ").append(path);
+ break;
+ }
+ buff.append("\n").append(" estimatedEntries: ").append(getCost(filter, rootState));
+ buff.append("\n");
+ return buff.toString();
}
@Override
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
index e44f123419..b641d3bb32 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
@@ -120,9 +120,8 @@ public class NodeTypeIndexQueryTest extends AbstractQueryTest {
Query.JCR_SQL2, false);
assertEquals(1, plan.size());
assertTrue(plan.get(0).contains("no-index"));
- assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n" +
- " where (isdescendantnode([nt:unstructured], [/test]))\n" +
- " and (contains([nt:unstructured].[foo], 'bar')) */",
+ assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n"
+ + " */",
plan.get(0));
plan = executeQuery(
@@ -132,9 +131,8 @@ public class NodeTypeIndexQueryTest extends AbstractQueryTest {
Query.JCR_SQL2, false);
assertEquals(1, plan.size());
assertTrue(plan.get(0).contains("no-index"));
- assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n" +
- " where (isdescendantnode([nt:unstructured], [/test]))\n" +
- " and (not contains([nt:unstructured].[foo], 'bar')) */",
+ assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n"
+ + " */",
plan.get(0));
plan = executeQuery(
@@ -144,9 +142,8 @@ public class NodeTypeIndexQueryTest extends AbstractQueryTest {
Query.JCR_SQL2, false);
assertEquals(1, plan.size());
assertTrue(plan.get(0).contains("no-index"));
- assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n" +
- " where (isdescendantnode([nt:unstructured], [/test]))\n" +
- " and (contains([nt:unstructured].[foo], 'bar')) */",
+ assertEquals("[nt:unstructured] as [nt:unstructured] /* no-index\n"
+ + " */",
plan.get(0));
setTraversalEnabled(true);
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultiPropertyOrTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultiPropertyOrTest.java
index 0b3f12e0a0..65a9b13d85 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultiPropertyOrTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultiPropertyOrTest.java
@@ -85,22 +85,22 @@ public class MultiPropertyOrTest extends AbstractQueryTest {
Query.JCR_SQL2);
assertEquals(1, lines.size());
// make sure it used the property index
- assertTrue(lines.get(0).contains("property xyz IS NOT NULL"));
+ assertTrue(lines.toString(), lines.get(0).contains("all values in the index"));
lines = executeQuery(
"explain select [jcr:path] from [nt:base] where [x] = 'foo' OR [y] = 'foo'",
Query.JCR_SQL2);
assertEquals(1, lines.size());
// make sure it used the property index
- assertTrue(lines.get(0).contains("property xyz = foo"));
+ assertTrue(lines.toString(), lines.get(0).contains("values: 'foo'"));
lines = executeQuery(
"explain select [jcr:path] from [nt:base] where [x] = 'foo' OR [y] = 'bar'",
Query.JCR_SQL2);
assertEquals(1, lines.size());
// make sure it used the property index
- assertTrue(lines.get(0), lines.get(0).contains("property xyz = foo"));
- assertTrue(lines.get(0), lines.get(0).contains("property xyz = bar"));
+ assertTrue(lines.get(0), lines.get(0).contains("values: 'foo'"));
+ assertTrue(lines.get(0), lines.get(0).contains("values: 'bar'"));
assertQuery(
"select [jcr:path] from [nt:base] where [x] = 'foo' OR [y] = 'foo'",
@@ -121,22 +121,17 @@ public class MultiPropertyOrTest extends AbstractQueryTest {
root.commit();
List<Integer> nodes = Lists.newArrayList();
- Random r = new Random();
- int seed = -2;
+ Random r = new Random(1);
for (int i = 0; i < 1000; i++) {
Tree a = test.addChild("a" + i);
a.setProperty("x", "fooa");
- seed += 2;
int num = r.nextInt(100);
a.setProperty("z", num);
nodes.add(num);
}
-
- seed = -1;
for (int i = 0; i < 1000; i++) {
Tree a = test.addChild("b" + i);
a.setProperty("y", "foob");
- seed += 2;
int num = 100 + r.nextInt(100);
a.setProperty("z", num);
nodes.add(num);
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OptionIndexTagTests.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OptionIndexTagTests.java
index f4d3abc528..40606e3481 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OptionIndexTagTests.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OptionIndexTagTests.java
@@ -73,14 +73,14 @@ public class OptionIndexTagTests extends AbstractQueryTest {
statement = "explain select * from [mix:versionable] where [jcr:uuid] = 1 option(index tag y, index name nodetype)";
result = executeQuery(statement, Query.JCR_SQL2, false, false).toString();
- assertTrue(result, result.indexOf("/* nodeType ") >= 0);
+ assertTrue(result, result.indexOf("/* nodeType") >= 0);
statement = "explain select * from [mix:versionable] where [jcr:uuid] = 1 option(index name nodetype)";
result = executeQuery(statement, Query.JCR_SQL2, false, false).toString();
- assertTrue(result, result.indexOf("/* nodeType ") >= 0);
+ assertTrue(result, result.indexOf("/* nodeType") >= 0);
statement = "explain select * from [mix:versionable] where [jcr:uuid] = 1 option(index tag y)";
result = executeQuery(statement, Query.JCR_SQL2, false, false).toString();
- assertTrue(result, result.indexOf("/* traverse ") >= 0);
+ assertTrue(result, result.indexOf("/* traverse") >= 0);
}
@Test
@@ -95,7 +95,7 @@ public class OptionIndexTagTests extends AbstractQueryTest {
assertTrue(result, result.indexOf("/* property uuid") >= 0);
statement = "explain select * from [mix:versionable] where [jcr:uuid] = 1 option(index name nodetype)";
result = executeQuery(statement, Query.JCR_SQL2, false, false).toString();
- assertTrue(result, result.indexOf("/* nodeType ") >= 0);
+ assertTrue(result, result.indexOf("/* nodeType") >= 0);
}
@Test
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java
index 3bd7044ca7..f754ff34e6 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java
@@ -77,7 +77,11 @@ public class PropertyIndexDisabledTest {
f.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("x10"));
PropertyIndex propertyIndex = new PropertyIndex(Mounts.defaultMountInfoProvider());
assertTrue(propertyIndex.getCost(f, root) != Double.POSITIVE_INFINITY);
- assertEquals("property foo = x10", propertyIndex.getPlan(f, root));
+ assertEquals("property foo\n"
+ + " indexDefinition: /oak:index/foo\n"
+ + " estimatedCost: 7.0\n"
+ + " values: 'x10'\n"
+ + "", propertyIndex.getPlan(f, root));
// now test with a node that doesn't exist
index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
@@ -95,7 +99,11 @@ public class PropertyIndexDisabledTest {
// need to create a new one - otherwise the cached plan is used
propertyIndex = new PropertyIndex(Mounts.defaultMountInfoProvider());
assertTrue(propertyIndex.getCost(f, root) != Double.POSITIVE_INFINITY);
- assertEquals("property foo = x10", propertyIndex.getPlan(f, root));
+ assertEquals("property foo\n"
+ + " indexDefinition: /oak:index/foo\n"
+ + " estimatedCost: 7.0\n"
+ + " values: 'x10'\n"
+ + "", propertyIndex.getPlan(f, root));
// test with a property that does not exist
index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
diff --git a/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt b/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
index 980f86655e..1cb403b7a6 100644
--- a/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
+++ b/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
@@ -25,38 +25,56 @@
# * use ascii characters only
explain select [jcr:path], [jcr:score], * from [nt:base] as a where lower([test]) <> 'lower'
-[nt:base] as [a] /* traverse "*"
- where lower([a].[test]) <> 'lower' */
+[nt:base] as [a] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
explain select * from [nt:base] where [jcr:uuid] <> '1'
-[nt:base] as [nt:base] /* property uuid IS NOT NULL
- where [nt:base].[jcr:uuid] <> '1' */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
explain select * from [nt:base] as a
left outer join [nt:base] as b on a.x=b.y
where a.y is null and b.z = 1
-[nt:base] as [a] /* traverse "*"
- where [a].[y] is null */ left outer join [nt:base] as [b] /* traverse "*"
- where [b].[z] = 1 */
+[nt:base] as [a] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */ left outer join [nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on [a].[x] = [b].[y]
explain select * from [nt:base] as a
right outer join [nt:base] as b on a.x=b.y
where a.y is null and b.z = 1
-[nt:base] as [b] /* traverse "*"
- where [b].[z] = 1 */ left outer join [nt:base] as [a] /* traverse "*" */
+[nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */ left outer join [nt:base] as [a] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on [a].[x] = [b].[y]
explain select * from [nt:base] where (p=1 or p=2) and (p=3 or p=4)
-[nt:base] as [nt:base] /* traverse "*"
- where ([nt:base].[p] in(1, 2))
- and ([nt:base].[p] in(3, 4)) */
+[nt:base] as [nt:base] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
explain select *
from [nt:base]
where [jcr:uuid] like '%'
-[nt:base] as [nt:base] /* property uuid IS NOT NULL
- where [nt:base].[jcr:uuid] like '%' */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
explain select e.[jcr:path]
from [nt:base] as a
@@ -70,20 +88,30 @@ explain select e.[jcr:path]
and name(c) = 'd'
and name(d) = 'e'
and (e.[jcr:uuid] = '1' or e.[jcr:uuid] = '2' or e.[jcr:uuid] = '3' or e.[jcr:uuid] = '4')
-[nt:base] as [e] /* property uuid IN (1, 2, 3, 4)
- where [e].[jcr:uuid] in('1', '2', '3', '4') */
- inner join [nt:base] as [d] /* traverse "* && //parent/of/join"
- where name([d]) = 'e' */
+[nt:base] as [e] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 6.0
+ values: '1', '2', '3', '4'
+ */
+ inner join [nt:base] as [d] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([e], [d])
- inner join [nt:base] as [c] /* traverse "* && //parent/of/join"
- where name([c]) = 'd' */
+ inner join [nt:base] as [c] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([d], [c])
- inner join [nt:base] as [b] /* traverse "* && //parent/of/join"
- where name([b]) = 'c' */
+ inner join [nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([c], [b])
- inner join [nt:base] as [a] /* traverse "//* && //parent/of/join"
- where (name([a]) = 'a')
- and (isdescendantnode([a], [/])) */
+ inner join [nt:base] as [a] /* traverse
+ allDescendents: /
+ estimatedEntries: 1.0E8
+ */
on ischildnode([b], [a])
explain select e.[jcr:path]
@@ -98,55 +126,78 @@ explain select e.[jcr:path]
and name(c) = 'd'
and name(d) = 'e'
and (e.[jcr:uuid] = '1' or e.[jcr:uuid] = '2' or e.[jcr:uuid] = '3' or e.[jcr:uuid] = '4')
-[nt:base] as [e] /* property uuid IN (1, 2, 3, 4)
- where [e].[jcr:uuid] in('1', '2', '3', '4') */
- inner join [nt:base] as [d] /* traverse "* && //parent/of/join"
- where name([d]) = 'e' */
+[nt:base] as [e] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 6.0
+ values: '1', '2', '3', '4'
+ */
+ inner join [nt:base] as [d] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([e], [d])
- inner join [nt:base] as [c] /* traverse "* && //parent/of/join"
- where name([c]) = 'd' */
+ inner join [nt:base] as [c] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([d], [c])
- inner join [nt:base] as [b] /* traverse "* && //parent/of/join"
- where name([b]) = 'c' */
+ inner join [nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on ischildnode([c], [b])
- inner join [nt:base] as [a] /* traverse "//* && //parent/of/join"
- where (name([a]) = 'a')
- and (isdescendantnode([a], [/])) */
+ inner join [nt:base] as [a] /* traverse
+ allDescendents: /
+ estimatedEntries: 1.0E8
+ */
on ischildnode([b], [a])
explain select excerpt(.)
from [nt:resource]
where contains(*, 'jackrabbit')
-[nt:resource] as [nt:resource] /* traverse "*"
- where contains([nt:resource].[*], 'jackrabbit') */
+[nt:resource] as [nt:resource] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: Infinity
+ */
explain select excerpt(.)
from [nt:resource]
where contains(*, 'jackrabbit') or contains(*, 'jackrabbit')
-[nt:resource] as [nt:resource] /* traverse "*"
- where contains([nt:resource].[*], 'jackrabbit') */
+[nt:resource] as [nt:resource] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: Infinity
+ */
explain select excerpt(.)
from [nt:resource]
where (contains(*, 'jackrabbit') or contains(*, 'jackrabbit'))
and x = '1'
-[nt:resource] as [nt:resource] /* traverse "*"
- where (contains([nt:resource].[*], 'jackrabbit'))
- and ([nt:resource].[x] = '1') */
+[nt:resource] as [nt:resource] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: Infinity
+ */
explain select *
from [nt:base]
where [jcr:uuid]=1 or [b]=2
-[nt:base] as [nt:base] /* traverse "*"
- where ([nt:base].[jcr:uuid] = 1) or ([nt:base].[b] = 2) */
+[nt:base] as [nt:base] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
explain select b.[jcr:uuid]
from [nt:base] as a
inner join [nt:base] as b on isdescendantnode(b, a)
where (a.[jcr:uuid] = '1' or a.[jcr:uuid] = '2')
-[nt:base] as [a] /* property uuid IN (1, 2)
- where [a].[jcr:uuid] in('1', '2') */
- inner join [nt:base] as [b] /* traverse "* && //path/from/join//*" */
+[nt:base] as [a] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
+ inner join [nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on isdescendantnode([b], [a])
explain select b.[jcr:uuid]
@@ -154,60 +205,88 @@ explain select b.[jcr:uuid]
inner join [nt:base] as b on isdescendantnode(b, a)
where (a.[jcr:uuid] = '1' or a.[jcr:uuid] = '2')
and b.[jcr:uuid] is not null
-[nt:base] as [a] /* property uuid IN (1, 2)
- where [a].[jcr:uuid] in('1', '2') */
- inner join [nt:base] as [b] /* property uuid IS NOT NULL
- where [b].[jcr:uuid] is not null */
+[nt:base] as [a] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
+ inner join [nt:base] as [b] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
on isdescendantnode([b], [a])
explain select *
from [nt:base]
where length([jcr:uuid])=1 or upper([jcr:uuid])='1' or lower([jcr:uuid])='3'
-[nt:base] as [nt:base] /* property uuid IS NOT NULL
- where ([nt:base].[jcr:uuid] is not null)
- and ((length([nt:base].[jcr:uuid]) = 1) or (upper([nt:base].[jcr:uuid]) = '1') or (lower([nt:base].[jcr:uuid]) = '3')) */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
explain select *
from [nt:base]
where [jcr:uuid] = '1' or ([jcr:uuid] = '2'
and [b] = '3')
-[nt:base] as [nt:base] /* property uuid IN (1, 2)
- where ([nt:base].[jcr:uuid] is not null)
- and ([nt:base].[jcr:uuid] in('1', '2')) */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
explain select *
from [nt:base]
where [jcr:uuid] in('1', '2')
-[nt:base] as [nt:base] /* property uuid IN (1, 2)
- where [nt:base].[jcr:uuid] in('1', '2') */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
explain select *
from [nt:base]
where [jcr:uuid] = '1' or [jcr:uuid] = '2'
-[nt:base] as [nt:base] /* property uuid IN (1, 2)
- where [nt:base].[jcr:uuid] in('1', '2') */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
explain select *
from [nt:base]
where [jcr:uuid] = '123'
-[nt:base] as [nt:base] /* property uuid = 123
- where [nt:base].[jcr:uuid] = '123' */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 2.0
+ values: '123'
+ */
explain select *
from [nt:base]
where [jcr:uuid] is not null
-[nt:base] as [nt:base] /* property uuid IS NOT NULL
- where [nt:base].[jcr:uuid] is not null */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
explain select *
from [nt:base] as a
inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null
and b.[jcr:uuid] is not null
-[nt:base] as [a] /* property uuid IS NOT NULL
- where [a].[jcr:uuid] is not null */
- inner join [nt:base] as [b] /* property uuid IS NOT NULL
- where [b].[jcr:uuid] is not null */
+[nt:base] as [a] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
+ inner join [nt:base] as [b] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
on isdescendantnode([b], [a])
explain select *
@@ -215,10 +294,16 @@ explain select *
inner join [nt:base] as b on isdescendantnode(b, a)
where (a.[jcr:uuid]=1 or a.[jcr:uuid]=2)
and (b.[jcr:uuid]=3 or b.[jcr:uuid]=4)
-[nt:base] as [a] /* property uuid IN (1, 2)
- where [a].[jcr:uuid] in(1, 2) */
- inner join [nt:base] as [b] /* property uuid IN (3, 4)
- where [b].[jcr:uuid] in(3, 4) */
+[nt:base] as [a] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '1', '2'
+ */
+ inner join [nt:base] as [b] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 4.0
+ values: '3', '4'
+ */
on isdescendantnode([b], [a])
explain select *
@@ -226,17 +311,25 @@ explain select *
inner join [nt:base] as b on isdescendantnode(b, a)
where a.[jcr:uuid] is not null
and b.[x] is not null
-[nt:base] as [a] /* property uuid IS NOT NULL
- where [a].[jcr:uuid] is not null */
- inner join [nt:base] as [b] /* traverse "* && //path/from/join//*"
- where [b].[x] is not null */
+[nt:base] as [a] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
+ inner join [nt:base] as [b] /* traverse
+ allNodes (warning: slow)
+ estimatedEntries: 1.0E8
+ */
on isdescendantnode([b], [a])
explain select [rep:excerpt]
from [nt:base]
where [jcr:uuid] is not null
-[nt:base] as [nt:base] /* property uuid IS NOT NULL
- where [nt:base].[jcr:uuid] is not null */
+[nt:base] as [nt:base] /* property uuid
+ indexDefinition: /oak:index/uuid
+ estimatedCost: 12.0
+ values: all values in the index (warning: may be slow)
+ */
commit / + "test": { "jcr:uuid": "xyz", "a": { "jcr:uuid": "123" } }
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreLuceneIndexTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreLuceneIndexTest.java
index 5ad27c76c8..5e1a3c0eab 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreLuceneIndexTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreLuceneIndexTest.java
@@ -158,7 +158,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// since it is now disabled as path corresponding to useIfExists property is not present in new read only lib
QueryResult result = repoV2.executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* traverse \"//*\" where ([a].[foo] = 'bar'"));
+ containsString("allDescendents: /"));
// Check that proper nodes are returned by the query
// even after traversal from both readonly version 2 and global read write parts
@@ -169,7 +169,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// Now just for sake of completeness - check that the index is still used if we use V1 of composite app.
result = repoV1.executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:luceneTest(/oak:index/luceneTest) foo:bar"));
+ containsString("/oak:index/luceneTest"));
result = repoV1.executeQuery("/jcr:root//*[@foo = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-foo/node-0, " +
@@ -188,7 +188,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
result = repoV2.executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* traverse \"//*\" where ([a].[foo] = 'bar'"));
+ containsString("allDescendents: /"));
// Check that proper nodes are returned by the query
// even after traversal from both readonly version 2 and global read write parts
@@ -232,7 +232,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// Check V2 now uses luceneTest2_V2 for foo2 and no index for foo i.e traversal
QueryResult result = repoV2.executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* traverse \"//*\" where ([a].[foo] = 'bar'"));
+ containsString("allDescendents: /"));
// Check that proper nodes are returned by the query
// even after traversal from both readonly version 2 and global read write parts
@@ -242,7 +242,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// Checking for prop foo2 now
result = repoV2.executeQuery("explain /jcr:root//*[@foo2 = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:luceneTest2_V2(/oak:index/luceneTest2_V2) foo2:bar"));
+ containsString("/oak:index/luceneTest2_V2"));
result = repoV2.executeQuery("/jcr:root//*[@foo2 = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-foo2/node-0, /content-foo2/node-1, " +
@@ -253,7 +253,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// Checking for foo3 now - new index on V2
result = repoV2.executeQuery("explain /jcr:root//*[@foo3 = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:luceneTest3(/oak:index/luceneTest3) foo3:bar"));
+ containsString("/oak:index/luceneTest3"));
// Check that proper nodes are returned by the query
// even after traversal from both readonly version 2 and global read write parts
@@ -267,7 +267,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// Now check that the V1 instance still uses B for foo2 , A for foo and traverses for foo3
result = repoV1.executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:luceneTest(/oak:index/luceneTest) foo:bar"));
+ containsString("/oak:index/luceneTest"));
result = repoV1.executeQuery("/jcr:root//*[@foo = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-foo/node-0, " +
@@ -279,7 +279,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
// foo 2 check
result = repoV1.executeQuery("explain /jcr:root//*[@foo2 = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:luceneTest2(/oak:index/luceneTest2) foo2:bar"));
+ containsString("/oak:index/luceneTest2"));
result = repoV1.executeQuery("/jcr:root//*[@foo2 = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-foo2/node-0, " +
@@ -292,7 +292,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
repoV1.login();
result = repoV1.executeQuery("explain /jcr:root//*[@foo3 = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* traverse \"//*\" where ([a].[foo3] = 'bar'"));
+ containsString("allDescendents: /"));
result = repoV1.executeQuery("/jcr:root//*[@foo3 = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-foo3/node-0, " +
@@ -429,7 +429,7 @@ public class CompositeNodeStoreLuceneIndexTest extends CompositeNodeStoreQueryTe
QueryResult result = executeQuery("explain /jcr:root//*[@" + indexedProperty + " = 'bar']", "xpath");
assertThat(result.getRows().next().toString(),
- containsString("/* lucene:" + indexName + "(/oak:index/" + indexName + ") " + indexedProperty + ":bar"));
+ containsString("/oak:index/" + indexName));
result = executeQuery("/jcr:root//*[@" + indexedProperty + " = 'bar'] order by @jcr:path", "xpath");
assertEquals("/content-" + indexedProperty + "/node-0, " +
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreQueryTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreQueryTest.java
index 2f97919743..4f65eab8d9 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreQueryTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreQueryTest.java
@@ -99,7 +99,7 @@ public class CompositeNodeStoreQueryTest extends CompositeNodeStoreQueryTestBase
qe = root.getQueryEngine();
assertThat(
executeQuery("explain /jcr:root//*[@foo = 'bar']", "xpath", false).toString(),
- containsString("/* property foo = bar"));
+ containsString("/oak:index/foo"));
assertEquals("[/readOnly/node-0, /readOnly/node-1, /readOnly/node-2]",
executeQuery("/jcr:root//*[@foo = 'bar']", "xpath").toString());
@@ -116,7 +116,7 @@ public class CompositeNodeStoreQueryTest extends CompositeNodeStoreQueryTestBase
"/readOnly/node-0, /readOnly/node-1, /readOnly/node-2]",
executeQuery("/jcr:root//*[@foo = 'bar']", "xpath").toString());
assertThat(executeQuery("explain /jcr:root/content//*[@foo = 'bar']", "xpath", false).toString(),
- containsString("/* property foo = bar"));
+ containsString("/oak:index/foo"));
// remove all data
builder = store.getRoot().builder();
@@ -170,7 +170,7 @@ public class CompositeNodeStoreQueryTest extends CompositeNodeStoreQueryTestBase
qe = root.getQueryEngine();
assertThat(executeQuery("explain select * from [nt:base] " +
"where property([*], 'Reference') = cast('u1' as reference)", Query.JCR_SQL2, false).toString(),
- containsString("/* reference "));
+ containsString("/* reference"));
// expected: also /readOnly/node-0 .. 2
assertEquals("[/a/x, /readOnly/node-0, /readOnly/node-1, /readOnly/node-2]",
executeQuery("select [jcr:path] from [nt:base] " +
@@ -268,7 +268,7 @@ public class CompositeNodeStoreQueryTest extends CompositeNodeStoreQueryTestBase
assertThat(
executeQuery("explain /jcr:root//*[@asyncFoo = 'bar']", "xpath", false).toString(),
- containsString("/* lucene:lucene(/oak:index/lucene) asyncFoo:bar"));
+ containsString("/oak:index/lucene"));
assertEquals("[/readOnly/node-0, /readOnly/node-1, /readOnly/node-2]",
executeQuery("/jcr:root//*[@asyncFoo = 'bar']", "xpath").toString());
@@ -283,7 +283,7 @@ public class CompositeNodeStoreQueryTest extends CompositeNodeStoreQueryTestBase
// run a query
assertThat(
executeQuery("explain /jcr:root//*[@asyncFoo = 'bar']", "xpath", false).toString(),
- containsString("/* lucene:lucene(/oak:index/lucene) asyncFoo:bar"));
+ containsString("/oak:index/lucene"));
assertEquals("[/content/node-0, /content/node-1, /content/node-2, " +
"/readOnly/node-0, /readOnly/node-1, /readOnly/node-2]",
executeQuery("/jcr:root//*[@asyncFoo = 'bar']", "xpath").toString());
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryFormatterTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryFormatterTest.java
new file mode 100644
index 0000000000..bf9fba4dce
--- /dev/null
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryFormatterTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.jcr.query;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.jackrabbit.oak.query.QueryFormatter;
+import org.junit.Test;
+
+public class QueryFormatterTest {
+
+ @Test
+ public void detectLanguage() {
+ assertFalse(QueryFormatter.isXPath("SELECT * FROM [rep:Authorizable]", null));
+ assertFalse(QueryFormatter.isXPath(" select * from [nt:base]", null));
+ assertFalse(QueryFormatter.isXPath("EXPLAIN SELECT ...", null));
+ assertFalse(QueryFormatter.isXPath("explain measure SELECT ...", null));
+
+ // common xpath
+ assertTrue(QueryFormatter.isXPath("/jcr:root//*", null));
+ assertTrue(QueryFormatter.isXPath(" /jcr:root//*", null));
+ assertTrue(QueryFormatter.isXPath("\nexplain /jcr:root//element(*,rep:ACE)", null));
+
+ // xpath union
+ assertTrue(QueryFormatter.isXPath("( ( /jcr:root//a | /jcr:root//b ) )", null));
+
+ // language is set explicitly
+ assertTrue(QueryFormatter.isXPath("select", "xpath"));
+ }
+
+ @Test
+ public void format() {
+ assertEquals("/jcr:root//*[\n"
+ + " @a=1\n"
+ + " and @b=2]\n"
+ + " order by @c\n"
+ + " option(traversal ok)",
+ QueryFormatter.format(
+ "/jcr:root//*[@a=1 and @b=2] order by @c option(traversal ok)", null));
+ assertEquals(
+ "sElEct *\n"
+ + " FROM nt:base\n"
+ + " WHERE x=1\n"
+ + " and y=2",
+ QueryFormatter.format(
+ "sElEct * FROM nt:base WHERE x=1 and y=2",
+ null));
+ assertEquals(
+ "select ...\n"
+ + " union select ...",
+ QueryFormatter.format(
+ "select ... union select ...",
+ null));
+ // formatting is also done inside string literals
+ assertEquals(
+ "/jcr:root//*[\n"
+ + " @x='\n"
+ + " and ']",
+ QueryFormatter.format("/jcr:root//*[@x=' and ']", null));
+ }
+}
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
index 3beb7db00e..6a58164304 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
@@ -397,12 +397,12 @@ public class LuceneIndexAugmentTest extends AbstractQueryTest {
String query = "EXPLAIN SELECT [jcr:path] from [" + TestUtil.NT_TEST + "] WHERE [foo1]='bar1'";
List<String> paths = executeQuery(query, SQL2);
assertTrue("indexed prop name shouldn't decide query plan (" + paths.get(0) + ")",
- paths.get(0).contains("/* no-index "));
+ paths.get(0).contains("/* no-index"));
query = "EXPLAIN SELECT [jcr:path] from [" + TestUtil.NT_TEST + "] WHERE [subChild/foo2]='bar2'";
paths = executeQuery(query, SQL2);
assertTrue("indexed prop name shouldn't decide query plan (" + paths.get(0) + ")",
- paths.get(0).contains("/* no-index "));
+ paths.get(0).contains("/* no-index"));
}
//OAK-3576
@@ -461,7 +461,7 @@ public class LuceneIndexAugmentTest extends AbstractQueryTest {
query = "EXPLAIN " + query;
List<String> paths = executeQuery(query, SQL2, false);
assertTrue("property index should have made the index selected (" + paths.get(0) + ")",
- paths.get(0).contains("/* lucene:test-index("));
+ paths.get(0).contains("/oak:index/test-index"));
query = "SELECT [jcr:path] from [" + TestUtil.NT_TEST + "] WHERE [subChild/foo2]='bar2'";
executeQuery(query, SQL2);
@@ -469,7 +469,7 @@ public class LuceneIndexAugmentTest extends AbstractQueryTest {
query = "EXPLAIN " + query;
paths = executeQuery(query, SQL2);
assertTrue("property index should have made the index selected (" + paths.get(0) + ")",
- paths.get(0).contains("/* lucene:test-index("));
+ paths.get(0).contains("/oak:index/test-index"));
}
//OAK-3576
@@ -530,7 +530,7 @@ public class LuceneIndexAugmentTest extends AbstractQueryTest {
List<String> paths = executeQuery(query, SQL2, false);
assertEquals("Query augmentor should get called for full text constraints", 1, queryingCounter.get());
assertTrue("property index should have made the index selected (" + paths.get(0) + ")",
- paths.get(0).contains("/* lucene:test-index("));
+ paths.get(0).contains("/oak:index/test-index"));
queryingCounter.set(0);
query = "SELECT [jcr:path] from [" + TestUtil.NT_TEST + "] WHERE CONTAINS(*, 'bar2')";
@@ -541,7 +541,7 @@ public class LuceneIndexAugmentTest extends AbstractQueryTest {
paths = executeQuery(query, SQL2, false);
assertEquals("Query augmentor should get called for full text constraints", 1, queryingCounter.get());
assertTrue("property index should have made the index selected (" + paths.get(0) + ")",
- paths.get(0).contains("/* lucene:test-index("));
+ paths.get(0).contains("/oak:index/test-index"));
}
@Test
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryCommonTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryCommonTest.java
index 84d9419162..273deb0db2 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryCommonTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryCommonTest.java
@@ -79,7 +79,6 @@ public class LuceneIndexQueryCommonTest extends IndexQueryCommonTest {
@Override
public String getExplainValueForDescendantTestWithIndexTagExplain() {
- return "[nt:base] as [nt:base] /* lucene:test-index(/oak:index/test-index) :ancestors:/test" +
- " where isdescendantnode([nt:base], [/test]) */";
+ return ":ancestors:/test";
}
}
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexCommonTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexCommonTest.java
index af1064b898..d458987f8c 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexCommonTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexCommonTest.java
@@ -52,11 +52,11 @@ public class LucenePropertyIndexCommonTest extends PropertyIndexCommonTest {
@Override
protected String propertyExistenceQueryWithNullCheckExpectedExplain() {
- return "lucene:test1(/oak:index/test1) :notNullProps:propa";
+ return "/oak:index/test1";
}
@Override
protected String propertyNonExistenceQueryExpectedExplain() {
- return "lucene:test1(/oak:index/test1) :nullProps:propa";
+ return "/oak:index/test1";
}
}
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
index d6ac51ec77..a45fb2b210 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
@@ -469,7 +469,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String propabQuery = "select [jcr:path] from [nt:base] where LOCALNAME() = 'foo'";
- assertThat(explain(propabQuery), containsString("lucene:test1(/oak:index/test1) :nodeName:foo"));
+ assertThat(explain(propabQuery), containsString(":nodeName:foo"));
assertQuery(propabQuery, asList("/foo"));
assertQuery("select [jcr:path] from [nt:base] where LOCALNAME() = 'bar'", asList("/test/bar"));
assertQuery("select [jcr:path] from [nt:base] where LOCALNAME() LIKE 'foo'", asList("/foo"));
@@ -503,7 +503,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
//test
String propabQuery = "select [jcr:path] from [nt:base] where LOCALNAME() = 'foo'";
- assertThat(explain(propabQuery), containsString("lucene:test1(/oak:index/test1) :nodeName:foo"));
+ assertThat(explain(propabQuery), containsString(":nodeName:foo"));
assertQuery(propabQuery, asList("/foo"));
assertQuery("select [jcr:path] from [nt:base] where LOCALNAME() = 'bar'", asList("/test/bar"));
assertQuery("select [jcr:path] from [nt:base] where LOCALNAME() LIKE 'foo'", asList("/foo"));
@@ -573,12 +573,8 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
" or content.[hasRendition] = 'false'\n" +
")";
String explain = explain(q);
- System.out.println(explain);
- String luceneQuery = explain.substring(0, explain.indexOf('\n'));
- assertEquals("[nt:unstructured] as [content] /* lucene:test1(/oak:index/test1) " +
- "+(tags:Products:A tags:Products:A/B) " +
- "+(tags:DocTypes:A tags:DocTypes:B tags:DocTypes:C tags:ProblemType:A)",
- luceneQuery);
+ assertThat(explain, containsString("+(tags:Products:A tags:Products:A/B) " +
+ "+(tags:DocTypes:A tags:DocTypes:B tags:DocTypes:C tags:ProblemType:A)"));
}
@Test
@@ -593,10 +589,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
String q = "SELECT * FROM [nt:unstructured] as content WHERE references LIKE '/some/content/efjoiefjowfgj/%'";
String explain = explain(q);
- String luceneQuery = explain.substring(0, explain.indexOf('\n'));
- assertEquals("[nt:unstructured] as [content] /* lucene:test1(/oak:index/test1) " +
- "references:/some/content/efjoiefjowfgj/*",
- luceneQuery);
+ assertThat(explain, containsString("references:/some/content/efjoiefjowfgj/*"));
}
@Test
@@ -1946,7 +1939,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String propabQuery = "select [jcr:path] from [mix:title] where [jcr:title] = 'a'";
- assertThat(explain(propabQuery), containsString("lucene:test1(/oak:index/test1)"));
+ assertThat(explain(propabQuery), containsString("/oak:index/test1"));
assertQuery(propabQuery, asList("/test/a"));
}
@@ -1966,7 +1959,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String propabQuery = "select [jcr:path] from [mix:mimeType] where [jcr:mimeType] = 'a'";
- assertThat(explain(propabQuery), containsString("lucene:test1(/oak:index/test1)"));
+ assertThat(explain(propabQuery), containsString("/oak:index/test1"));
assertQuery(propabQuery, asList("/test/a"));
}
@@ -1997,14 +1990,14 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
String query;
query = "/jcr:root/test//*[jcr:contains(@jcr:mimeType, '1234')]";
- assertThat(explainXpath(query), containsString("lucene:test2(/oak:index/test2)"));
+ assertThat(explainXpath(query), containsString("/oak:index/test2"));
assertQuery(query, "xpath", asList("/test/a"));
query = "/jcr:root/test//*[jcr:contains(., '1234')]";
assertThat(explainXpath(query), containsString("no-index"));
query = "/jcr:root/test//*[@jcr:mimeType = '1234']";
- assertThat(explainXpath(query), containsString("lucene:test2(/oak:index/test2)"));
+ assertThat(explainXpath(query), containsString("/oak:index/test2"));
assertQuery(query, "xpath", asList("/test/a"));
}
@@ -2068,7 +2061,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String propabQuery = "select [jcr:path] from [mix:title] where [jcr:content/type] = 'foo-a'";
- assertThat(explain(propabQuery), containsString("lucene:test1(/oak:index/test1)"));
+ assertThat(explain(propabQuery), containsString("/oak:index/test1"));
assertQuery(propabQuery, asList("/test/a"));
}
@@ -2150,16 +2143,16 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
String propabQuery = "select * from [nt:base] where CONTAINS(tag, " +
"'stockphotography:business/business_abstract')";
- assertPlanAndQuery(propabQuery, "lucene:test1(/oak:index/test1)", asList("/test"));
+ assertPlanAndQuery(propabQuery, "/oak:index/test1", asList("/test"));
String query2 = "select * from [nt:base] where CONTAINS(tag, 'foo!')";
- assertPlanAndQuery(query2, "lucene:test1(/oak:index/test1)", asList("/test2"));
+ assertPlanAndQuery(query2, "/oak:index/test1", asList("/test2"));
String query3 = "select * from [nt:base] where CONTAINS(tag, 'a=b')";
- assertPlanAndQuery(query3, "lucene:test1(/oak:index/test1)", asList("/test3"));
+ assertPlanAndQuery(query3, "/oak:index/test1", asList("/test3"));
String query4 = "select * from [nt:base] where CONTAINS(tag, 'c=d=e')";
- assertPlanAndQuery(query4, "lucene:test1(/oak:index/test1)", asList("/test4"));
+ assertPlanAndQuery(query4, "/oak:index/test1", asList("/test4"));
}
@@ -2177,7 +2170,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String propabQuery = "select * from [nt:base] where CONTAINS([jcr:content/metadata/comment], 'december')";
- assertPlanAndQuery(propabQuery, "lucene:test1(/oak:index/test1)", asList("/test"));
+ assertPlanAndQuery(propabQuery, "/oak:index/test1", asList("/test"));
}
@Test
@@ -2256,7 +2249,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String query = "select * from [nt:base] where [tag] = 'foo'";
- assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", Collections.<String>emptyList());
+ assertPlanAndQuery(query, "/oak:index/test1", Collections.<String>emptyList());
}
@Test
@@ -2325,8 +2318,8 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
- assertPlanAndQuery("select * from [oak:TestSuperType]", "lucene:test1(/oak:index/test1)", asList("/a", "/b"));
- assertPlanAndQuery("select * from [oak:TestMixA]", "lucene:test1(/oak:index/test1)", asList("/b", "/c"));
+ assertPlanAndQuery("select * from [oak:TestSuperType]", "/oak:index/test1", asList("/a", "/b"));
+ assertPlanAndQuery("select * from [oak:TestMixA]", "/oak:index/test1", asList("/b", "/c"));
}
@Test
@@ -2369,8 +2362,8 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
- assertPlanAndQuery("select * from [oak:TestSuperType]", "lucene:test1(/oak:index/test1)", asList("/a", "/b"));
- assertPlanAndQuery("select * from [oak:TestMixA]", "lucene:test1(/oak:index/test1)", asList("/b", "/c"));
+ assertPlanAndQuery("select * from [oak:TestSuperType]", "/oak:index/test1", asList("/a", "/b"));
+ assertPlanAndQuery("select * from [oak:TestMixA]", "/oak:index/test1", asList("/b", "/c"));
}
@@ -2387,7 +2380,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String query = "select * from [nt:base] where [foo] = 'bar'";
- assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", asList("/a"));
+ assertPlanAndQuery(query, "/oak:index/test1", asList("/a"));
Tree barProp = root.getTree("/oak:index/test1/indexRules/nt:base/properties").addChild("bar");
barProp.setProperty("name", "bar");
@@ -2395,12 +2388,12 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
query = "select * from [nt:base] where [bar] = 'bar'";
- assertThat(explain(query), not(containsString("lucene:test1(/oak:index/test1)")));
+ assertThat(explain(query), not(containsString("/oak:index/test1")));
root.getTree("/oak:index/test1").setProperty(REINDEX_PROPERTY_NAME, true);
root.commit();
- assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", asList("/b"));
+ assertPlanAndQuery(query, "/oak:index/test1", asList("/b"));
}
@Test
@@ -2416,7 +2409,7 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
String query = "select * from [nt:base] where [foo] = 'bar'";
- assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", asList("/a"));
+ assertPlanAndQuery(query, "/oak:index/test1", asList("/a"));
Tree barProp = root.getTree("/oak:index/test1/indexRules/nt:base/properties").addChild("bar");
barProp.setProperty("name", "bar");
@@ -2424,18 +2417,18 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
query = "select * from [nt:base] where [bar] = 'bar'";
- assertThat(explain(query), not(containsString("lucene:test1(/oak:index/test1)")));
+ assertThat(explain(query), not(containsString("/oak:index/test1")));
//Instead of reindex just refresh the index definition so that new index definition gets picked up
root.getTree("/oak:index/test1").setProperty(FulltextIndexConstants.PROP_REFRESH_DEFN, true);
root.commit();
//Plan would reflect new defintion
- assertThat(explain(query), containsString("lucene:test1(/oak:index/test1)"));
+ assertThat(explain(query), containsString("/oak:index/test1"));
assertFalse(root.getTree("/oak:index/test1").hasProperty(FulltextIndexConstants.PROP_REFRESH_DEFN));
//However as reindex was not done query would result in empty set
- assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", Collections.<String>emptyList());
+ assertPlanAndQuery(query, "/oak:index/test1", Collections.<String>emptyList());
}
@Test
@@ -2530,10 +2523,10 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
root.commit();
assertPlanAndQuery("select * from [nt:base] where [jcr:content/foo] = 'bar'",
- "lucene:test1(/oak:index/test1)", asList("/a", "/b"));
+ "/oak:index/test1", asList("/a", "/b"));
assertPlanAndQuery("select * from [nt:base] where [jcr:content/metadata/sub/foo] = 'bar'",
- "lucene:test1(/oak:index/test1)", asList("/d"));
+ "/oak:index/test1", asList("/d"));
}
@Test
@@ -3082,49 +3075,49 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
// XPaths
assertPlanAndQueryXPath("//*[j:c/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQueryXPath("//*[e/j:c/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/d"));
+ "/oak:index/fooIndex", asList("/d"));
assertPlanAndQueryXPath("//*[*/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQueryXPath("//*[*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)",
+ "/oak:index/fooIndex",
asList("/a/j:c", "/b/j:c", "/c", "/d/e/j:c", "/j:c", "/"));
assertPlanAndQueryXPath("//*[j:c/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQueryXPath("//*[*/foo1/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a"));
+ "/oak:index/fooIndex", asList("/a"));
assertPlanAndQueryXPath("//*[*/*/foo3/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/d"));
+ "/oak:index/fooIndex", asList("/d"));
// SQL2s
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [j:c/*/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [e/j:c/*/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/d"));
+ "/oak:index/fooIndex", asList("/d"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [*/*/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [*/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)",
+ "/oak:index/fooIndex",
asList("/a/j:c", "/b/j:c", "/c", "/d/e/j:c", "/j:c", "/"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [j:c/*/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a", "/b", "/d/e", "/"));
+ "/oak:index/fooIndex", asList("/a", "/b", "/d/e", "/"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [*/foo1/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/a"));
+ "/oak:index/fooIndex", asList("/a"));
assertPlanAndQuery("SELECT * FROM [nt:base] WHERE [*/*/foo3/foo] = 'bar'",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/d"));
+ "/oak:index/fooIndex", asList("/d"));
}
@Test
@@ -3149,35 +3142,35 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
// no path restriction
assertPlanAndQueryXPath("//*[j:c/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a", "/test/c/d"));
+ "/oak:index/fooIndex", asList("/test/a", "/test/c/d"));
assertPlanAndQueryXPath("//*[*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a", "/test", "/test/c/d"));
+ "/oak:index/fooIndex", asList("/test/a", "/test", "/test/c/d"));
assertPlanAndQueryXPath("//*[d/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/c"));
+ "/oak:index/fooIndex", asList("/test/c"));
// any descendant
assertPlanAndQueryXPath("/jcr:root/test//*[j:c/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a", "/test/c/d"));
+ "/oak:index/fooIndex", asList("/test/a", "/test/c/d"));
assertPlanAndQueryXPath("/jcr:root/test//*[*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a", "/test/c/d"));
+ "/oak:index/fooIndex", asList("/test/a", "/test/c/d"));
assertPlanAndQueryXPath("/jcr:root/test//*[d/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/c"));
+ "/oak:index/fooIndex", asList("/test/c"));
// direct children
assertPlanAndQueryXPath("/jcr:root/test/*[j:c/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a"));
+ "/oak:index/fooIndex", asList("/test/a"));
assertPlanAndQueryXPath("/jcr:root/test/*[*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a"));
+ "/oak:index/fooIndex", asList("/test/a"));
assertPlanAndQueryXPath("/jcr:root/test/*[d/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/c"));
+ "/oak:index/fooIndex", asList("/test/c"));
// exact path
assertPlanAndQueryXPath("/jcr:root/test/a[j:c/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a"));
+ "/oak:index/fooIndex", asList("/test/a"));
assertPlanAndQueryXPath("/jcr:root/test/a[*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/a"));
+ "/oak:index/fooIndex", asList("/test/a"));
assertPlanAndQueryXPath("/jcr:root/test/c[d/*/@foo = 'bar']",
- "lucene:fooIndex(/oak:index/fooIndex)", asList("/test/c"));
+ "/oak:index/fooIndex", asList("/test/c"));
}
private void assertPlanAndQueryXPath(String query, String planExpectation, List<String> paths) throws ParseException {
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/dynamicBoost/LuceneDynamicBoostTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/dynamicBoost/LuceneDynamicBoostTest.java
index c81bfedeac..1a745bced6 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/dynamicBoost/LuceneDynamicBoostTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/dynamicBoost/LuceneDynamicBoostTest.java
@@ -88,9 +88,8 @@ public class LuceneDynamicBoostTest extends DynamicBoostCommonTest {
@Override
protected String getTestQueryDynamicBoostBasicExplained() {
- return "[dam:Asset] as [a] /* lucene:test-index(/oak:index/test-index) (full:title:plant :fulltext:plant) " +
- "((jcr:content/metadata/predictedTags/plant:1 jcr:content/metadata/predictedTags/plant:1)^1.0E-4) ft:(\"plant\")\n" +
- " where contains([a].[*], 'plant') */";
+ return "(full:title:plant :fulltext:plant) " +
+ "((jcr:content/metadata/predictedTags/plant:1 jcr:content/metadata/predictedTags/plant:1)^1.0E-4)";
}
@Override
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
index e1d418686d..9694d43925 100644
--- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
@@ -331,9 +331,9 @@ public class SynchronousPropertyIndexTest extends AbstractQueryTest {
runAsyncIndex();
assertThat(explain("select * from [nt:base] where [jcr:content/foo] = 'bar'"),
- containsString("sync:(foo[jcr:content/foo] bar)"));
+ containsString("synchronousPropertyCondition: foo[jcr:content/foo] bar"));
assertThat(explain("select * from [nt:base] where [foo] = 'bar'"),
- containsString("sync:(foo bar)"));
+ containsString("synchronousPropertyCondition: foo bar"));
}
@Test
diff --git a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticDynamicBoostTest.java b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticDynamicBoostTest.java
index d780ab9df9..9fb2172c96 100644
--- a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticDynamicBoostTest.java
+++ b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticDynamicBoostTest.java
@@ -48,14 +48,13 @@ public class ElasticDynamicBoostTest extends DynamicBoostCommonTest {
@Override
protected String getTestQueryDynamicBoostBasicExplained() {
- return "[dam:Asset] as [a] /* elasticsearch:test-index(/oak:index/test-index) {\"_source\":{\"includes\":[\":path\"]}," +
+ return "{\"_source\":{\"includes\":[\":path\"]}," +
"\"query\":{\"bool\":{\"must\":[{\"bool\":{\"must\":[{\"query_string\":{\"default_operator\":\"and\"," +
"\"fields\":[\"title^1.0\",\":dynamic-boost-ft^1.0E-4\",\":fulltext\"],\"query\":\"plant\",\"tie_breaker\":0.5,\"type\":\"cross_fields\"}}]," +
"\"should\":[{\"nested\":{\"path\":\"predictedTagsDynamicBoost\",\"query\":{\"function_score\":{\"boost\":9.999999747378752E-5," +
"\"functions\":[{\"field_value_factor\":{\"field\":\"predictedTagsDynamicBoost.boost\"}}]," +
"\"query\":{\"match\":{\"predictedTagsDynamicBoost.value\":{\"query\":\"plant\"}}}}},\"score_mode\":\"avg\"}}]}}]}}," +
- "\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"track_total_hits\":10000} ft:(\"plant\")\n" +
- " where contains([a].[*], 'plant') */";
+ "\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"track_total_hits\":10000}";
}
/**
diff --git a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexQueryCommonTest.java b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexQueryCommonTest.java
index f8530356f1..c787d1e9eb 100644
--- a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexQueryCommonTest.java
+++ b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexQueryCommonTest.java
@@ -52,8 +52,7 @@ public class ElasticIndexQueryCommonTest extends IndexQueryCommonTest {
String query = "explain select [jcr:path] from [nt:base] where " +
"native('lucene', 'mlt?stream.body=/test/a&mlt.fl=:path&mlt.mindf=0&mlt.mintf=0')";
- String explainWithoutSimilarityTags = "[nt:base] as [nt:base] /* elasticsearch:test-index(/oak:index/test-index) {\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"must\":[{\"more_like_this\":{\"fields\":[\":dynamic-boost-ft\",\"*\"],\"include\":true,\"like\":[{\"_id\":\"/test/a\",\"per_field_analyzer\":{\"_ignored\":\"keyword\"}}],\"min_doc_freq\":0,\"min_term_freq\":0}}]}},\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"tra [...]
- " where native([nt:base], [lucene], 'mlt?stream.body=/test/a&mlt.fl=:path&mlt.mindf=0&mlt.mintf=0') */";
+ String explainWithoutSimilarityTags = "{\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"must\":[{\"more_like_this\":{\"fields\":[\":dynamic-boost-ft\",\"*\"],\"include\":true,\"like\":[{\"_id\":\"/test/a\",\"per_field_analyzer\":{\"_ignored\":\"keyword\"}}],\"min_doc_freq\":0,\"min_term_freq\":0}}]}},\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"track_total_hits\":10000}";
Tree test = root.getTree("/").addChild("test");
test.addChild("a").setProperty("text", "Hello World");
@@ -64,22 +63,21 @@ public class ElasticIndexQueryCommonTest extends IndexQueryCommonTest {
root.commit();
// similarity tags disabled, should not be present in the explain output
- assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithoutSimilarityTags, true));
+ assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithoutSimilarityTags, false));
indexDefn.setProperty("similarityTagsEnabled", true);
root.commit();
// similarity tags enabled, but no similarity tags properties configured, should not be present in the explain output
- assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithoutSimilarityTags, true));
+ assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithoutSimilarityTags, false));
- String explainWithSimilarityTags = "[nt:base] as [nt:base] /* elasticsearch:test-index(/oak:index/test-index) {\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"must\":[{\"more_like_this\":{\"fields\":[\":dynamic-boost-ft\",\"*\"],\"include\":true,\"like\":[{\"_id\":\"/test/a\",\"per_field_analyzer\":{\"_ignored\":\"keyword\"}}],\"min_doc_freq\":0,\"min_term_freq\":0}}],\"should\":[{\"more_like_this\":{\"boost\":0.5,\"fields\":[\":simTags\"],\"like\":[{\"_id\":\"/test [...]
- " where native([nt:base], [lucene], 'mlt?stream.body=/test/a&mlt.fl=:path&mlt.mindf=0&mlt.mintf=0') */";
+ String explainWithSimilarityTags = "{\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"must\":[{\"more_like_this\":{\"fields\":[\":dynamic-boost-ft\",\"*\"],\"include\":true,\"like\":[{\"_id\":\"/test/a\",\"per_field_analyzer\":{\"_ignored\":\"keyword\"}}],\"min_doc_freq\":0,\"min_term_freq\":0}}],\"should\":[{\"more_like_this\":{\"boost\":0.5,\"fields\":[\":simTags\"],\"like\":[{\"_id\":\"/test/a\"}],\"min_doc_freq\":1,\"min_term_freq\":1}}]}},\"size\":10,\"sort\":[{ [...]
Tree properties = indexDefn.getChild(FulltextIndexConstants.INDEX_RULES).getChild("nt:base").getChild("properties");
Tree simProp = TestUtil.enableForFullText(properties, "simProp", false);
simProp.setProperty(FulltextIndexConstants.PROP_SIMILARITY_TAGS, true);
root.commit();
- assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithSimilarityTags, true));
+ assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, explainWithSimilarityTags, false));
}
@Override
@@ -112,9 +110,7 @@ public class ElasticIndexQueryCommonTest extends IndexQueryCommonTest {
@Override
public String getExplainValueForDescendantTestWithIndexTagExplain() {
- return "[nt:base] as [nt:base] /* elasticsearch:test-index(/oak:index/test-index) "
- + "{\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"filter\":[{\"term\":{\":ancestors\":{\"value\":\"/test\"}}}]}},\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"track_total_hits\":10000}"
- + " where isdescendantnode([nt:base], [/test]) */";
+ return "{\"_source\":{\"includes\":[\":path\"]},\"query\":{\"bool\":{\"filter\":[{\"term\":{\":ancestors\":{\"value\":\"/test\"}}}]}},\"size\":10,\"sort\":[{\"_score\":{\"order\":\"desc\"}},{\":path\":{\"order\":\"asc\"}}],\"track_total_hits\":10000}";
}
}
diff --git a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticPropertyIndexTest.java b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticPropertyIndexTest.java
index afa4dafd9f..cef7ae6c43 100644
--- a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticPropertyIndexTest.java
+++ b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticPropertyIndexTest.java
@@ -161,7 +161,7 @@ public class ElasticPropertyIndexTest extends ElasticAbstractQueryTest {
assertEventually(() -> {
String explanation = explain(propabQuery);
- assertThat(explanation, containsString("elasticsearch:test1(/oak:index/test1) "));
+ assertThat(explanation, containsString("/oak:index/test1"));
assertThat(explanation, containsString("{\"term\":{\":nodeName\":{\"value\":\"foo\""));
assertQuery(propabQuery, List.of("/test/foo"));
diff --git a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndex.java b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndex.java
index fe7d3f9727..38dd82d953 100644
--- a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndex.java
+++ b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndex.java
@@ -161,18 +161,18 @@ public abstract class FulltextIndex implements AdvancedQueryIndex, QueryIndex, N
checkState(index != null, "The fulltext index of type " + getType() + " index is not available");
try {
FullTextExpression ft = filter.getFullTextConstraint();
- StringBuilder sb = new StringBuilder(getType()).append(":");
+ StringBuilder sb = new StringBuilder();
+ sb.append(getType()).append(":").append(getIndexName(plan)).append("\n");
String path = getPlanResult(plan).indexPath;
- sb.append(getIndexName(plan))
- .append("(")
- .append(path)
- .append(") ");
- sb.append(getFulltextRequestString(plan, index, root));
+ sb.append(" indexDefinition: ").append(path).append("\n");
+ sb.append(" estimatedEntries: ").append(plan.getEstimatedEntryCount()).append("\n");
+ // luceneQuery / elasticQuery
+ sb.append(" ").append(getType()).append("Query: ").append(getFulltextRequestString(plan, index, root)).append("\n");
if (plan.getSortOrder() != null && !plan.getSortOrder().isEmpty()) {
- sb.append(" ordering:").append(plan.getSortOrder());
+ sb.append(" sortOrder: ").append(plan.getSortOrder()).append("\n");
}
if (ft != null) {
- sb.append(" ft:(").append(ft).append(")");
+ sb.append(" fulltextCondition: ").append(ft).append("\n");
}
addSyncIndexPlan(plan, sb);
return sb.toString();
@@ -185,22 +185,18 @@ public abstract class FulltextIndex implements AdvancedQueryIndex, QueryIndex, N
PlanResult pr = getPlanResult(plan);
if (pr.hasPropertyIndexResult()) {
FulltextIndexPlanner.PropertyIndexResult pres = pr.getPropertyIndexResult();
- sb.append(" sync:(")
- .append(pres.propertyName);
-
+ sb.append(" synchronousPropertyCondition: ").append(pres.propertyName);
if (!pres.propertyName.equals(pres.pr.propertyName)) {
sb.append("[").append(pres.pr.propertyName).append("]");
}
-
sb.append(" ").append(pres.pr);
- sb.append(")");
+ sb.append("\n");
}
-
if (pr.evaluateSyncNodeTypeRestriction()) {
- sb.append(" sync:(nodeType");
- sb.append(" primaryTypes : ").append(plan.getFilter().getPrimaryTypes());
- sb.append(" mixinTypes : ").append(plan.getFilter().getMixinTypes());
- sb.append(")");
+ sb.append(" synchronousNodeType: ");
+ sb.append("primaryTypes=").append(plan.getFilter().getPrimaryTypes());
+ sb.append(" mixinTypes=").append(plan.getFilter().getMixinTypes());
+ sb.append("\n");
}
}
diff --git a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndexPlanner.java b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndexPlanner.java
index 66d4130c5f..855d87c668 100644
--- a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndexPlanner.java
+++ b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/query/FulltextIndexPlanner.java
@@ -973,7 +973,7 @@ public class FulltextIndexPlanner {
matchingRule = rule;
}
if (matchingRule != null){
- log.debug("Applicable IndexingRule found {}", matchingRule);
+ log.trace("Applicable IndexingRule found {}", matchingRule);
return rule;
}
}
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/DynamicBoostCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/DynamicBoostCommonTest.java
index be3cfac7f9..75dcbee99d 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/DynamicBoostCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/DynamicBoostCommonTest.java
@@ -16,6 +16,14 @@
*/
package org.apache.jackrabbit.oak.plugins.index;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.UUID;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -28,12 +36,6 @@ import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
import org.apache.jackrabbit.oak.query.AbstractQueryTest;
import org.junit.Test;
-import java.io.ByteArrayInputStream;
-import java.util.List;
-import java.util.UUID;
-
-import static org.junit.Assert.assertEquals;
-
public abstract class DynamicBoostCommonTest extends AbstractQueryTest {
protected static final String ASSET_NODE_TYPE = "[dam:Asset]\n" + " - * (UNDEFINED) multiple\n" + " - * (UNDEFINED)\n" + " + * (nt:base) = oak:TestNode VERSION";
@@ -46,7 +48,8 @@ public abstract class DynamicBoostCommonTest extends AbstractQueryTest {
createAssetsIndexAndProperties(false, false);
prepareTestAssets();
- assertEquals(getTestQueryDynamicBoostBasicExplained(), explain("//element(*, dam:Asset)[jcr:contains(., 'plant')]", XPATH));
+ assertThat(explain("//element(*, dam:Asset)[jcr:contains(., 'plant')]", XPATH),
+ containsString(getTestQueryDynamicBoostBasicExplained()));
assertEventually(() -> {
assertQuery("//element(*, dam:Asset)[jcr:contains(., 'plant')]", XPATH,
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/FunctionIndexCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/FunctionIndexCommonTest.java
index b3d4e281e4..883ef4bdf5 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/FunctionIndexCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/FunctionIndexCommonTest.java
@@ -241,15 +241,15 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
postCommitHook();
String query = "select [jcr:path] from [nt:base] where path() = '/test/world'";
- assertThat(explain(query), containsString(getIndexProvider() + "pathIndex(/oak:index/pathIndex)"));
+ assertThat(explain(query), containsString("/oak:index/pathIndex"));
assertQuery(query, asList("/test/world"));
query = "select [jcr:path] from [nt:base] where path() like '%hell%'";
- assertThat(explain(query), containsString(getIndexProvider() + "pathIndex(/oak:index/pathIndex)"));
+ assertThat(explain(query), containsString("/oak:index/pathIndex"));
assertQuery(query, asList("/test/hello", "/test/hello world"));
query = "select [jcr:path] from [nt:base] where path() like '%ll_'";
- assertThat(explain(query), containsString(getIndexProvider() + "pathIndex(/oak:index/pathIndex)"));
+ assertThat(explain(query), containsString("/oak:index/pathIndex"));
assertQuery(query, asList("/test/hello"));
}
@@ -300,7 +300,7 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
root.commit();
postCommitHook();
- assertThat(explain(query), containsString(getIndexProvider() + "test-index(/oak:index/test-index)"));
+ assertThat(explain(query), containsString("/oak:index/test-index"));
List<String> result = executeQuery(query, SQL2);
assertEquals("Ordering doesn't match", asList("10 percent", "10%", "Hallo", "hello", "World!"), result);
@@ -931,11 +931,11 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
assertOrderedPlanAndQuery(
"select * from [nt:base] order by coalesce([jcr:content/foo2], [jcr:content/foo])",
- getIndexProvider() + "test1(/oak:index/test1)", asList("/a", "/c", "/b"));
+ "/oak:index/test1", asList("/a", "/c", "/b"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by coalesce([jcr:content/foo2], [jcr:content/foo]) DESC",
- getIndexProvider() + "test1(/oak:index/test1)", asList("/b", "/c", "/a"));
+ "/oak:index/test1", asList("/b", "/c", "/a"));
}
@Test
@@ -961,7 +961,7 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
assertPlanAndQuery(
"select * from [nt:base] where lower(coalesce([jcr:content/foo2], coalesce([jcr:content/foo], localname()))) = 'bar'",
- getIndexProvider() + "test1(/oak:index/test1)", asList("/a", "/b", "/bar"));
+ "/oak:index/test1", asList("/a", "/b", "/bar"));
}
/*
@@ -1018,19 +1018,19 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
// Check ordering works for func and non func properties
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo])",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [jcr:content/n/foo]",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo]) DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [jcr:content/n/foo] DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
// Now we change the value of foo on already indexed nodes and see if changes
// get indexed properly.
@@ -1052,19 +1052,19 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo])",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [jcr:content/n/foo]",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo]) DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [jcr:content/n/foo] DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
}
@@ -1127,19 +1127,19 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([foo])",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [foo]",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d", "/e", "/b", "/c", "/a"));
+ "/oak:index/upper", asList("/d", "/e", "/b", "/c", "/a"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([foo]) DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by [foo] DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a", "/c", "/b", "/e", "/d"));
+ "/oak:index/upper", asList("/a", "/c", "/b", "/e", "/d"));
} finally {
customLogs.finished();
@@ -1244,11 +1244,11 @@ public abstract class FunctionIndexCommonTest extends AbstractQueryTest {
// Check ordering works for func and non func properties
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo])",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/a","/c","/b","/e","/d"));
+ "/oak:index/upper", asList("/a","/c","/b","/e","/d"));
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo]) DESC",
- getIndexProvider() + "upper(/oak:index/upper)", asList("/d","/e","/b","/c","/a"));
+ "/oak:index/upper", asList("/d","/e","/b","/c","/a"));
}
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
index 21a29a4def..22a05eca4f 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
@@ -207,7 +207,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String query = "explain select [jcr:path] from [nt:base] where isdescendantnode('/test') option (index tag x)";
- assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, getExplainValueForDescendantTestWithIndexTagExplain(), true));
+ assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, getExplainValueForDescendantTestWithIndexTagExplain(), false));
}
// Check if this is a valid behaviour or not ?
@@ -216,7 +216,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
@Test
public void descendantTestWithIndexTagExplainWithNoData() {
String query = "explain select [jcr:path] from [nt:base] where isdescendantnode('/test') option (index tag x)";
- assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, getExplainValueForDescendantTestWithIndexTagExplain(), true));
+ assertEventually(getAssertionForExplain(query, Query.JCR_SQL2, getExplainValueForDescendantTestWithIndexTagExplain(), false));
}
@Test
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/OrderByCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/OrderByCommonTest.java
index 6eeb672333..7d600d6afe 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/OrderByCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/OrderByCommonTest.java
@@ -320,28 +320,28 @@ public abstract class OrderByCommonTest extends AbstractQueryTest {
root.commit();
String query = "/jcr:root/test/* order by fn:name() option(index tag fnName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnName(/oak:index/fnName)");
+ assertXpathPlan(query, "/oak:index/fnName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:name() ascending option(index tag fnName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnName(/oak:index/fnName)");
+ assertXpathPlan(query, "/oak:index/fnName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:name() descending option(index tag fnName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnName(/oak:index/fnName)");
+ assertXpathPlan(query, "/oak:index/fnName");
assertEquals(Lists.reverse(expected), executeQuery(query, XPATH));
// order by fn:name() although function index is on "name()"
query = "/jcr:root/test/* order by fn:name() option(index tag name)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":name(/oak:index/name)");
+ assertXpathPlan(query, "/oak:index/name");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:name() ascending option(index tag name)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":name(/oak:index/name)");
+ assertXpathPlan(query, "/oak:index/name");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:name() descending option(index tag name)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":name(/oak:index/name)");
+ assertXpathPlan(query, "/oak:index/name");
assertEquals(Lists.reverse(expected), executeQuery(query, XPATH));
}
@@ -392,28 +392,28 @@ public abstract class OrderByCommonTest extends AbstractQueryTest {
root.commit();
String query = "/jcr:root/test/* order by fn:local-name() option(index tag fnLocalName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnLocalName(/oak:index/fnLocalName)");
+ assertXpathPlan(query, "/oak:index/fnLocalName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:local-name() ascending option(index tag fnLocalName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnLocalName(/oak:index/fnLocalName)");
+ assertXpathPlan(query, "/oak:index/fnLocalName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:local-name() descending option(index tag fnLocalName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":fnLocalName(/oak:index/fnLocalName)");
+ assertXpathPlan(query, "/oak:index/fnLocalName");
assertEquals(Lists.reverse(expected), executeQuery(query, XPATH));
// order by fn:name() although function index is on "name()"
query = "/jcr:root/test/* order by fn:local-name() option(index tag localName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":localName(/oak:index/localName)");
+ assertXpathPlan(query, "/oak:index/localName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:local-name() ascending option(index tag localName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":localName(/oak:index/localName)");
+ assertXpathPlan(query, "/oak:index/localName");
assertEquals(expected, executeQuery(query, XPATH));
query = "/jcr:root/test/* order by fn:local-name() descending option(index tag localName)";
- assertXpathPlan(query, indexOptions.getIndexType() + ":localName(/oak:index/localName)");
+ assertXpathPlan(query, "/oak:index/localName");
assertEquals(Lists.reverse(expected), executeQuery(query, XPATH));
}
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/PropertyIndexCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/PropertyIndexCommonTest.java
index 08d54fde72..ca7493fe4e 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/PropertyIndexCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/PropertyIndexCommonTest.java
@@ -72,7 +72,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
// Make sure that the last entry is indexed correctly.
String propaQuery = "select [jcr:path] from [nt:base] where [propa] = 'foo248'";
assertEventually(() -> {
- assertThat(explain(propaQuery), containsString(indexOptions.getIndexType() + ":test1"));
+ assertThat(explain(propaQuery), containsString("/oak:index/test1"));
assertQuery(propaQuery, singletonList("/test/a248"));
});
@@ -85,7 +85,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
root.commit();
String propaQuery2 = "select [jcr:path] from [nt:base] where [propa] = 'foo299'";
assertEventually(() -> {
- assertThat(explain(propaQuery2), containsString(indexOptions.getIndexType() + ":test1"));
+ assertThat(explain(propaQuery2), containsString("/oak:index/test1"));
assertQuery(propaQuery2, singletonList("/test/a299"));
});
@@ -112,9 +112,9 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
.indexRule("nt:base")
.property("nodeName", PROPDEF_PROP_NODE_NAME);
indexOptions.setIndex(root, "test1", builder);
- assertThat(explain(propaQuery), containsString(indexOptions.getIndexType() + ":test1"));
+ assertThat(explain(propaQuery), containsString("/oak:index/test1"));
assertThat(explain("select [jcr:path] from [nt:base] where [propc] = 'foo'"),
- containsString(indexOptions.getIndexType() + ":test2"));
+ containsString("/oak:index/test2"));
assertQuery(propaQuery, Arrays.asList("/test/a", "/test/b"));
assertQuery("select [jcr:path] from [nt:base] where [propa] = 'foo2'", singletonList("/test/c"));
@@ -146,7 +146,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
assertEventually(() -> {
String explanation = explain(propabQuery);
- assertThat(explanation, containsString(indexOptions.getIndexType() + ":test1(/oak:index/test1) "));
+ assertThat(explanation, containsString("/oak:index/test1"));
//assertThat(explanation, containsString("{\"term\":{\":nodeName\":{\"value\":\"foo\","));
assertQuery(propabQuery, singletonList("/test/foo"));
@@ -170,7 +170,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
test.addChild("b");
root.commit();
assertEventually(() -> assertThat(explain("select [jcr:path] from [nt:base] where [propa] = 'foo'"),
- containsString(indexOptions.getIndexType() + ":test1")));
+ containsString("/oak:index/test1")));
}
@Test
@@ -214,7 +214,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
}
protected String propertyExistenceQueryWithNullCheckExpectedExplain() {
- return indexOptions.getIndexType() + ":test1(/oak:index/test1) ";
+ return "/oak:index/test1";
}
@Test
@@ -243,7 +243,7 @@ public abstract class PropertyIndexCommonTest extends AbstractQueryTest {
}
protected String propertyNonExistenceQueryExpectedExplain() {
- return indexOptions.getIndexType() + ":test1(/oak:index/test1) ";
+ return "/oak:index/test1";
}
@Test