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 <[email protected]>
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

Reply via email to