[
https://issues.apache.org/jira/browse/OAK-4313?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15260238#comment-15260238
]
Thomas Mueller commented on OAK-4313:
-------------------------------------
Sorry it took a bit longer than expected... here the patch. The idea is to use
the traversal index, but ensure that we don't traverse the whole repository.
Just one row at most. Scanning one row is needed for the rep:similar() case:
for this case, we still expect that an exception is thrown (OAK-2548 is just
for spellcheck and suggest, not for similarity search). Well if that's not
correct, then this patch could be simplified a bit. But I would keep the idea
to use traversal, but not traverse too much.
{noformat}
--- src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
(revision 1741187)
+++ src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
(working copy)
@@ -218,7 +218,9 @@
private final Deque<Iterator<? extends ChildNodeEntry>> nodeIterators =
Queues.newArrayDeque();
-
+
+ private boolean justOneRow;
+
private String parentPath;
private String currentPath;
@@ -241,6 +243,16 @@
NodeState parent = null;
NodeState node = rootState;
+ if (filter.containsNativeConstraint()) {
+ // OAK-4313: if no other index was found,
+ // then we ensure that only one row is returned
+ nodeIterators.add(Iterators.singletonIterator(
+ new MemoryChildNodeEntry(currentPath, node)));
+ parentPath = "";
+ justOneRow = true;
+ return;
+ }
+
if (filter.isAlwaysFalse()) {
// nothing can match this filter, leave nodes empty
return;
@@ -326,6 +338,9 @@
continue;
}
currentPath = PathUtils.concat(parentPath, name);
+ if (justOneRow) {
+ return;
+ }
PathRestriction r = filter.getPathRestriction();
if (r == PathRestriction.ALL_CHILDREN ||
Index: src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java
(revision 0)
+++ src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java
(working copy)
@@ -0,0 +1,92 @@
+/*
+ * 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 static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
+import static
org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
+import static
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.text.ParseException;
+import java.util.Iterator;
+
+import org.apache.jackrabbit.oak.api.Result;
+import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.core.ImmutableRoot;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+public class NativeQueryTest {
+
+ private final NodeState types = INITIAL_CONTENT.getChildNode(JCR_SYSTEM)
+ .getChildNode(JCR_NODE_TYPES);
+
+ private final ImmutableRoot ROOT = new ImmutableRoot(INITIAL_CONTENT);
+ private final QueryEngineImpl QUERY_ENGINE =
(QueryEngineImpl)ROOT.getQueryEngine();
+
+ private final SQL2Parser p = new SQL2Parser(NamePathMapper.DEFAULT, types,
new QueryEngineSettings());
+
+ @Test
+ public void dontTraverseForSuggest() throws Exception {
+ String sql = "select [rep:suggest()] from [nt:base] where
suggest('test')";
+ assertDontTraverseFor(sql, "Suggest");
+ }
+
+ @Test
+ public void dontTraverseForSpellcheck() throws Exception {
+ String sql = "select [rep:spellcheck()] from [nt:base] where
spellcheck('test')";
+ assertDontTraverseFor(sql, "Spellcheck");
+ }
+
+ @Test
+ public void dontTraverseForSimilar() throws Exception {
+ String sql = "select [rep:similar()] from [nt:base] where similar(.,
'/test/a')";
+ try {
+ assertDontTraverseFor(sql, "Similar");
+ fail();
+ } catch(IllegalArgumentException e) {
+ // OAK-2548 if about 2spellcheck" and "suggest", but not about for
"similar".
+ }
+ }
+
+ private void assertDontTraverseFor(String sql, String queryType) throws
ParseException {
+ QueryImpl query = (QueryImpl)p.parse(sql);
+ query.setExecutionContext(QUERY_ENGINE.getExecutionContext());
+ Result result = query.executeQuery();
+ Iterator<? extends ResultRow> it = result.getRows().iterator();
+ assertFalse(it.hasNext());
+
+ query = (QueryImpl)p.parse("measure " + sql);
+ query.setExecutionContext(QUERY_ENGINE.getExecutionContext());
+ result = query.executeQuery();
+ it = result.getRows().iterator();
+ while(it.hasNext()) {
+ ResultRow row = it.next();
+ String selector = row.getValue("selector").getValue(Type.STRING);
+ if ("nt:base".equals(selector)) {
+ long scanCount = row.getValue("scanCount").getValue(Type.LONG);
+ // we expect that exactly one node was scanned, but that's it
+ // - no traversal of the whole respository
+ assertEquals(1, scanCount);
+ }
+ }
+ }
+}
\ No newline at end of file
{noformat}
> QueryImpl should avoid traversal with queries containing native constraints
> ---------------------------------------------------------------------------
>
> Key: OAK-4313
> URL: https://issues.apache.org/jira/browse/OAK-4313
> Project: Jackrabbit Oak
> Issue Type: Bug
> Components: query
> Reporter: Vikas Saurabh
> Assignee: Vikas Saurabh
> Priority: Blocker
> Labels: candidate_oak_1_2, candidate_oak_1_4
> Fix For: 1.6, 1.4.2
>
> Attachments: OAK-4313.patch
>
>
> If no index supports suggestion (or spellcheck or similar) query, then a
> query like
> {noformat}
> SELECT * from [nt:base] where SUGGEST('test')
> {noformat}
> shouldn't get traversing index
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)