Index: oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -38,9 +38,9 @@ import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.commons.PathUtils; import org.apache.jackrabbit.oak.plugins.index.diffindex.UUIDDiffIndexProviderWrapper; +import org.apache.jackrabbit.oak.query.ExecutionContext; import org.apache.jackrabbit.oak.query.QueryEngineImpl; import org.apache.jackrabbit.oak.spi.commit.CommitHook; import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider; @@ -304,18 +304,19 @@ @Override public QueryEngine getQueryEngine() { checkLive(); - return new QueryEngineImpl(getIndexProvider()) { - + return new QueryEngineImpl() { @Override - protected NodeState getRootState() { - return AbstractRoot.this.getRootState(); + protected ExecutionContext getExecutionContext() { + NodeState rootState = AbstractRoot.this.getRootState(); + return new ExecutionContext(rootState, rootTree, getIndexProvider(rootState)); } - @Override - protected Tree getRootTree() { - return rootTree; + private QueryIndexProvider getIndexProvider(NodeState rootState) { + if (hasPendingChanges()) { + return new UUIDDiffIndexProviderWrapper(indexProvider, getBaseState(), rootState); - } + } - + return indexProvider; + } }; } @@ -331,15 +332,6 @@ return store.createBlob(inputStream); } }; - } - - @Nonnull - private QueryIndexProvider getIndexProvider() { - if (hasPendingChanges()) { - return new UUIDDiffIndexProviderWrapper(indexProvider, - getBaseState(), getRootState()); - } - return indexProvider; } //-----------------------------------------------------------< internal >--- Index: oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableRoot.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableRoot.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableRoot.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -27,9 +27,9 @@ import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.commons.PathUtils; import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexProvider; +import org.apache.jackrabbit.oak.query.ExecutionContext; import org.apache.jackrabbit.oak.query.QueryEngineImpl; import org.apache.jackrabbit.oak.spi.commit.CommitHook; import org.apache.jackrabbit.oak.spi.state.NodeState; @@ -104,15 +104,10 @@ @Nonnull @Override public QueryEngine getQueryEngine() { - return new QueryEngineImpl(new PropertyIndexProvider()) { + return new QueryEngineImpl() { @Override - protected NodeState getRootState() { - return rootTree.state; - } - - @Override - protected Tree getRootTree() { - return rootTree; + protected ExecutionContext getExecutionContext() { + return new ExecutionContext(rootTree.state, rootTree, new PropertyIndexProvider()); } }; } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/ExecutionContext.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/ExecutionContext.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ExecutionContext.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -0,0 +1,58 @@ +/* + * 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 javax.annotation.Nonnull; + +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; +import org.apache.jackrabbit.oak.spi.state.NodeState; + +/** + * TODO document + */ +public class ExecutionContext { + private final NodeState rootState; + private final Tree rootTree; + private final QueryIndexProvider indexProvider; + + public ExecutionContext(NodeState rootState, Tree rootTree, + QueryIndexProvider indexProvider) { + + this.rootState = rootState; + this.rootTree = rootTree; + this.indexProvider = indexProvider; + } + + @Nonnull + public NodeState getRootState() { + return rootState; + } + + @Nonnull + public Tree getRootTree() { + return rootTree; + } + + @Nonnull + public QueryIndexProvider getIndexProvider() { + return indexProvider; + } +} Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -22,6 +22,7 @@ import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.query.ast.ColumnImpl; import org.apache.jackrabbit.oak.query.ast.OrderingImpl; +import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; import org.apache.jackrabbit.oak.spi.state.NodeState; /** @@ -45,7 +46,7 @@ void bindValue(String key, PropertyValue value); - void setQueryEngine(QueryEngineImpl queryEngineImpl); + void setIndexProvider(QueryIndexProvider indexProvider); void prepare(); Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -24,13 +24,14 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.Map.Entry; +import java.util.Set; +import javax.annotation.Nonnull; + import org.apache.jackrabbit.oak.api.PropertyValue; import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Result; -import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.query.index.TraversingIndex; import org.apache.jackrabbit.oak.spi.query.Filter; @@ -60,8 +61,6 @@ XPATH, XPATH + NO_LITERALS, JQOM); - private final QueryIndexProvider indexProvider; - /** * Whether fallback to the traversing index is supported if no other index * is available. This is enabled by default and can be disabled for testing @@ -69,24 +68,12 @@ */ private boolean traversalFallback = true; - public QueryEngineImpl(QueryIndexProvider indexProvider) { - this.indexProvider = indexProvider; - } - /** - * Get the current root node state, to run the query against. - * - * @return the node state + * TODO document + * @return */ - protected abstract NodeState getRootState(); + protected abstract ExecutionContext getExecutionContext(); - /** - * Get the current root tree, to run the query against. - * - * @return the node state - */ - protected abstract Tree getRootTree(); - @Override public Set getSupportedQueryLanguages() { return SUPPORTED_LANGUAGES; @@ -102,13 +89,13 @@ */ @Override public List getBindVariableNames(String statement, String language) throws ParseException { - Query q = parseQuery(statement, language); + Query q = parseQuery(statement, language, getExecutionContext()); return q.getBindVariableNames(); } - private Query parseQuery(String statement, String language) throws ParseException { + private static Query parseQuery(String statement, String language, ExecutionContext context) throws ParseException { LOG.debug("Parsing {} statement: {}", language, statement); - NodeState root = getRootState(); + NodeState root = context.getRootState(); NodeState system = root.getChildNode(JCR_SYSTEM); NodeState types = system.getChildNode(JCR_NODE_TYPES); SQL2Parser parser = new SQL2Parser(types); @@ -146,9 +133,11 @@ if (offset < 0) { throw new IllegalArgumentException("Offset may not be negative, is: " + offset); } - Query q = parseQuery(statement, language); - q.setRootTree(getRootTree()); - q.setRootState(getRootState()); + + ExecutionContext context = getExecutionContext(); + Query q = parseQuery(statement, language, context); + q.setRootTree(context.getRootTree()); + q.setRootState(context.getRootState()); q.setNamePathMapper(namePathMapper); q.setLimit(limit); q.setOffset(offset); @@ -157,28 +146,41 @@ q.bindValue(e.getKey(), e.getValue()); } } - q.setQueryEngine(this); + q.setIndexProvider(getIndexProvider(context.getIndexProvider(), traversalFallback)); q.prepare(); return q.executeQuery(); } - protected void setTravesalFallback(boolean traversal) { + private static QueryIndexProvider getIndexProvider(final QueryIndexProvider indexProvider, + boolean traversalFallback) { + if (traversalFallback) { + return new QueryIndexProvider() { + @Nonnull + @Override + public List getQueryIndexes(NodeState nodeState) { + List indexes = new ArrayList(indexProvider.getQueryIndexes(nodeState)); + indexes.add(new TraversingIndex()); + return indexes; + } + }; + } else { + return indexProvider; + } + } + + protected void setTraversalFallback(boolean traversal) { this.traversalFallback = traversal; } - public QueryIndex getBestIndex(QueryImpl query, NodeState rootState, Filter filter) { + public static QueryIndex getBestIndex(QueryImpl query, NodeState rootState, Filter filter, + QueryIndexProvider indexProvider) { QueryIndex best = null; if (LOG.isDebugEnabled()) { LOG.debug("cost using filter " + filter); } - List indexes = new ArrayList( - indexProvider.getQueryIndexes(rootState)); - if (traversalFallback) { - indexes.add(new TraversingIndex()); - } double bestCost = Double.POSITIVE_INFINITY; - for (QueryIndex index : indexes) { + for (QueryIndex index : indexProvider.getQueryIndexes(rootState)) { double cost = index.getCost(filter, rootState); if (LOG.isDebugEnabled()) { LOG.debug("cost for " + index.getIndexName() + " is " + cost); Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -57,6 +57,7 @@ import org.apache.jackrabbit.oak.spi.query.Filter; import org.apache.jackrabbit.oak.spi.query.PropertyValues; import org.apache.jackrabbit.oak.spi.query.QueryIndex; +import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.util.TreeUtil; import org.slf4j.Logger; @@ -92,7 +93,7 @@ final ArrayList selectors = new ArrayList(); ConstraintImpl constraint; - private QueryEngineImpl queryEngine; + private QueryIndexProvider indexProvider; private OrderingImpl[] orderings; private ColumnImpl[] columns; private boolean explain, measure; @@ -563,12 +564,12 @@ } @Override - public void setQueryEngine(QueryEngineImpl queryEngine) { - this.queryEngine = queryEngine; + public void setIndexProvider(QueryIndexProvider indexProvider) { + this.indexProvider = indexProvider; } public QueryIndex getBestIndex(Filter filter) { - return queryEngine.getBestIndex(this, rootState, filter); + return QueryEngineImpl.getBestIndex(this, rootState, filter, indexProvider); } @Override Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java (revision 818d635) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.List; +import com.google.common.collect.Iterators; import org.apache.jackrabbit.oak.api.PropertyValue; import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.Tree; @@ -27,12 +28,11 @@ import org.apache.jackrabbit.oak.query.ast.ColumnImpl; import org.apache.jackrabbit.oak.query.ast.OrderingImpl; import org.apache.jackrabbit.oak.spi.query.PropertyValues; +import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Iterators; - /** * Represents a union query. */ @@ -110,9 +110,9 @@ } @Override - public void setQueryEngine(QueryEngineImpl queryEngineImpl) { - left.setQueryEngine(queryEngineImpl); - right.setQueryEngine(queryEngineImpl); + public void setIndexProvider(QueryIndexProvider indexProvider) { + left.setIndexProvider(indexProvider); + right.setIndexProvider(indexProvider); } @Override Index: oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (revision 818d635) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (revision 0ca34417fb6b138c27efce462cd841c7fb82a21d) @@ -16,6 +16,15 @@ */ package org.apache.jackrabbit.oak.query; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME; +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.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; @@ -31,6 +40,7 @@ import javax.jcr.PropertyType; +import com.google.common.collect.Lists; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.mk.json.JsopReader; import org.apache.jackrabbit.mk.json.JsopTokenizer; @@ -38,10 +48,10 @@ import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.PropertyValue; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.ResultRow; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.PathUtils; @@ -51,17 +61,6 @@ import org.apache.jackrabbit.oak.plugins.value.Conversions; import org.junit.Before; -import com.google.common.collect.Lists; - -import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME; -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.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * AbstractQueryTest... */ @@ -262,7 +261,7 @@ } protected void setTravesalFallback(boolean traversal) { - ((QueryEngineImpl) qe).setTravesalFallback(traversal); + ((QueryEngineImpl) qe).setTraversalFallback(traversal); } protected static String readRow(ResultRow row, boolean pathOnly) {