You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by al...@apache.org on 2013/05/07 15:51:59 UTC
svn commit: r1479909 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/index/property/
main/java/org/apache/jackrabbit/oak/query/
main/java/org/apache/jackrabbit/oak/query/ast/
main/java/org/apache/jackrabbit/oak/spi/...
Author: alexparvulescu
Date: Tue May 7 13:51:58 2013
New Revision: 1479909
URL: http://svn.apache.org/r1479909
Log:
OAK-812 QueryEngine support for multiple indices (tests)
- found a small bug in the property index editor
- added a protected flag to prevent the query engine to fallback to node traversal during the tests
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java Tue May 7 13:51:58 2013
@@ -154,7 +154,7 @@ class PropertyIndexEditor implements Ind
}
List<PropertyIndexUpdate> filtered = new ArrayList<PropertyIndexUpdate>();
for (PropertyIndexUpdate pi : indexes) {
- if (node == null || pi.matchesNodeType(node)) {
+ if (node == null || pi.matchesNodeType(node, getPath())) {
filtered.add(pi);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java Tue May 7 13:51:58 2013
@@ -173,7 +173,10 @@ class PropertyIndexUpdate {
}
}
- public boolean matchesNodeType(NodeBuilder node) {
+ public boolean matchesNodeType(NodeBuilder node, String path) {
+ if (!path.startsWith(this.path)) {
+ return false;
+ }
if (primaryTypes == null
|| primaryTypes.contains(node.getName(JCR_PRIMARYTYPE))) {
return true;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java Tue May 7 13:51:58 2013
@@ -21,6 +21,7 @@ import static org.apache.jackrabbit.JcrC
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
import java.text.ParseException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -154,13 +155,28 @@ public abstract class QueryEngineImpl im
return q.executeQuery();
}
+ /**
+ * testing purposes only
+ */
+ private boolean traversalFallback = true;
+
+ protected void setTravesalFallback(boolean traversal) {
+ this.traversalFallback = traversal;
+ }
+
public QueryIndex getBestIndex(Query query, NodeState rootState, Filter filter) {
QueryIndex best = null;
if (LOG.isDebugEnabled()) {
LOG.debug("cost using filter " + filter);
}
+ List<QueryIndex> indexes = new ArrayList<QueryIndex>(
+ indexProvider.getQueryIndexes(rootState));
+ if (traversalFallback) {
+ indexes.add(new TraversingIndex());
+ }
+
double bestCost = Double.POSITIVE_INFINITY;
- for (QueryIndex index : getIndexes(rootState)) {
+ for (QueryIndex index : indexes) {
double cost = index.getCost(filter, rootState);
if (LOG.isDebugEnabled()) {
LOG.debug("cost for " + index.getIndexName() + " is " + cost);
@@ -170,20 +186,7 @@ public abstract class QueryEngineImpl im
best = index;
}
}
- QueryIndex index = new TraversingIndex();
- double cost = index.getCost(filter, rootState);
- if (LOG.isDebugEnabled()) {
- LOG.debug("cost for " + index.getIndexName() + " is " + cost);
- }
- if (cost < bestCost) {
- bestCost = cost;
- best = index;
- }
return best;
}
- private List<? extends QueryIndex> getIndexes(NodeState rootState) {
- return indexProvider.getQueryIndexes(rootState);
- }
-
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Tue May 7 13:51:58 2013
@@ -32,6 +32,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_PRIMARY_SUBTYPES;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_SUPERTYPES;
+import java.util.ArrayList;
import java.util.Set;
import javax.annotation.Nonnull;
@@ -43,6 +44,7 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.query.Query;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Cursors;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.IndexRow;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
@@ -160,14 +162,23 @@ public class SelectorImpl extends Source
@Override
public void execute(NodeState rootState) {
- cursor = index.query(createFilter(false), rootState);
+ if (index != null) {
+ cursor = index.query(createFilter(false), rootState);
+ } else {
+ cursor = Cursors.newPathCursor(new ArrayList<String>());
+ }
}
@Override
public String getPlan(NodeState rootState) {
StringBuilder buff = new StringBuilder();
buff.append(toString());
- buff.append(" /* ").append(index.getPlan(createFilter(true), rootState));
+ buff.append(" /* ");
+ if (index != null) {
+ buff.append(index.getPlan(createFilter(true), rootState));
+ } else {
+ buff.append("no-index");
+ }
if (selectorCondition != null) {
buff.append(" where ").append(selectorCondition);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java Tue May 7 13:51:58 2013
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
import org.apache.jackrabbit.oak.query.index.IndexRowImpl;
-import org.apache.jackrabbit.oak.query.index.TraversingIndex;
import org.apache.jackrabbit.oak.spi.query.Filter.PathRestriction;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -190,7 +189,7 @@ public class Cursors {
*/
private static class TraversingCursor extends AbstractCursor {
- private static final Logger LOG = LoggerFactory.getLogger(TraversingIndex.class);
+ private static final Logger LOG = LoggerFactory.getLogger(TraversingCursor.class);
private final Filter filter;
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java?rev=1479909&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java Tue May 7 13:51:58 2013
@@ -0,0 +1,96 @@
+/*
+ * 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.plugins.index.property;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getOrCreateOakIndex;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.query.Query;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.query.QueryEngineImpl;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+public class MultipleIndicesTest extends AbstractQueryTest {
+
+ @Override
+ protected ContentRepository createRepository() {
+ return new Oak()
+ .with(new InitialContent())
+ .with(new RepositoryInitializer() {
+ @Override
+ public NodeState initialize(NodeState state) {
+ NodeBuilder root = state.builder();
+ createIndexDefinition(getOrCreateOakIndex(root), "pid",
+ true, false, ImmutableList.of("pid"), null);
+ createIndexDefinition(
+ getOrCreateOakIndex(root.child("content")),
+ "pid", true, false, ImmutableList.of("pid"),
+ null);
+ return root.getNodeState();
+ }
+ }).with(new OpenSecurityProvider())
+ .with(new PropertyIndexProvider())
+ .with(new PropertyIndexEditorProvider())
+ .createContentRepository();
+ }
+
+ @Test
+ public void query() throws Exception {
+
+ Tree t = root.getTree("/");
+ t.setProperty("pid", "foo");
+ t.addChild("a").setProperty("pid", "foo");
+ t.addChild("b").setProperty("pid", "bar");
+ t.addChild("c").setProperty("pid", "foo");
+ t.addChild("d").setProperty("cid", "foo");
+
+ Tree content = t.addChild("content");
+ content.addChild("x").setProperty("pid", "foo");
+ content.addChild("y").setProperty("pid", "baz");
+ content.addChild("z").setProperty("pid", "bar");
+ root.commit();
+
+ setTravesalFallback(false);
+ assertQuery("select [jcr:path] from [nt:base] where [cid] = 'foo'",
+ new ArrayList<String>());
+
+ assertQuery("select [jcr:path] from [nt:base] where [pid] = 'foo'",
+ ImmutableList.of("/", "/a", "/c", "/content/x"));
+
+ assertQuery("select [jcr:path] from [nt:base] where [pid] = 'bar'",
+ ImmutableList.of("/b", "/content/z"));
+
+ assertQuery("select [jcr:path] from [nt:base] where [pid] = 'baz'",
+ ImmutableList.of("/content/y"));
+ setTravesalFallback(true);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java Tue May 7 13:51:58 2013
@@ -68,12 +68,9 @@ public class RelativePathTest extends Ab
t.addChild("c").addChild("x").setProperty("myProp", "foo");
t.setProperty("myProp", "foo");
root.commit();
- List<String> paths = executeQuery(
- "select [jcr:path] from [nt:base] where [n/myProp] is not null",
- Query.JCR_SQL2);
- assertEquals(2, paths.size());
- assertTrue(paths.contains("/a"));
- assertTrue(paths.contains("/b"));
+ setTravesalFallback(false);
+ assertQuery("select [jcr:path] from [nt:base] where [n/myProp] is not null",
+ ImmutableList.of("/a", "/b"));
List<String> lines = executeQuery(
"explain select [jcr:path] from [nt:base] where [n/myProp] is not null",
@@ -82,10 +79,9 @@ public class RelativePathTest extends Ab
// make sure it used the property index
assertTrue(lines.get(0).contains("property myProp"));
- paths = executeQuery(
+ assertQuery(
"select [jcr:path] from [nt:base] where [n/myProp] = 'foo'",
- Query.JCR_SQL2);
- assertEquals(1, paths.size());
- assertTrue(paths.contains("/a"));
+ ImmutableList.of("/a"));
+ setTravesalFallback(false);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1479909&r1=1479908&r2=1479909&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java Tue May 7 13:51:58 2013
@@ -45,6 +45,8 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@@ -225,6 +227,19 @@ public abstract class AbstractQueryTest
return lines;
}
+ protected List<String> assertQuery(String sql, List<String> expected) {
+ List<String> paths = executeQuery(sql, SQL2);
+ assertEquals(expected.size(), paths.size());
+ for (String p : expected) {
+ assertTrue(paths.contains(p));
+ }
+ return paths;
+ }
+
+ protected void setTravesalFallback(boolean traversal) {
+ ((QueryEngineImpl) qe).setTravesalFallback(traversal);
+ }
+
protected static String readRow(ResultRow row) {
StringBuilder buff = new StringBuilder();
PropertyValue[] values = row.getValues();