Author: thomasm Date: Fri Sep 14 10:07:31 2012 New Revision: 1384708 URL: http://svn.apache.org/viewvc?rev=1384708&view=rev Log: OAK-303 The query engine should use a stable root (not always the head)
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Tree.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.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/SessionQueryEngineImpl.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/AbstractLuceneQueryTest.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java Fri Sep 14 10:07:31 2012 @@ -67,11 +67,17 @@ public interface ContentSession extends String getWorkspaceName(); /** - * The current root as seen by this content session. Use - * {@link Root#commit(ConflictHandler)} to atomically apply the changes made in that - * subtree the underlying Microkernel. - * - * @return the current root + * The current head root as seen by this content session. Use + * {@link Root#commit(ConflictHandler)} to atomically apply the changes made + * in that subtree the underlying Microkernel. + * <p> + * The root instance gives you a stable view of the tree at the time the + * root is acquired. + * <p> + * Please note this method is possibly expensive because it internally reads + * from the backend to detect if there were any changes (from any session). + * + * @return the current head root */ @Nonnull Root getCurrentRoot(); Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java Fri Sep 14 10:07:31 2012 @@ -23,6 +23,9 @@ import javax.annotation.Nonnull; /** * The root of a {@link Tree}. + * <p> + * The data returned by this class filtered for the access rights that are set + * in the {@link ContentSession} that created this object. */ public interface Root { Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java Fri Sep 14 10:07:31 2012 @@ -54,6 +54,7 @@ public interface SessionQueryEngine { * @param limit the maximum result set size * @param offset the number of rows to skip * @param bindings the bind variable value bindings + * @param root the root to use * @param namePathMapper the name and path mapper to use * @return the result * @throws ParseException if the statement could not be parsed @@ -61,7 +62,7 @@ public interface SessionQueryEngine { */ Result executeQuery(String statement, String language, long limit, long offset, Map<String, ? extends CoreValue> bindings, - NamePathMapper namePathMapper) throws ParseException; + Root root, NamePathMapper namePathMapper) throws ParseException; // TODO pass namespace mapping // TODO pass node type information (select * from [xyz] is supposed to return at least the mandatory columns for xyz) Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Tree.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Tree.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Tree.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Tree.java Fri Sep 14 10:07:31 2012 @@ -42,6 +42,10 @@ import javax.annotation.Nonnull; * threads. Instances are however thread-safe for read access, so * implementations need to ensure that all reading clients see a * coherent state. + * <p> + * The data returned by this class and intermediary objects such as + * {@link PropertyState} is filtered for the access rights that are set in the + * {@link ContentSession} that created the {@link Root} of this object. */ public interface Tree { Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java Fri Sep 14 10:07:31 2012 @@ -192,7 +192,7 @@ public class IdentifierManager { Result result = queryEngine.executeQuery( "SELECT * FROM [nt:base] WHERE PROPERTY([" + pName + "], '" + reference + "') = $uuid", - Query.JCR_SQL2, Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default()); + Query.JCR_SQL2, Long.MAX_VALUE, 0, bindings, root, new NamePathMapper.Default()); Iterable<String> paths = Iterables.transform(result.getRows(), new Function<ResultRow, String>() { @@ -291,8 +291,9 @@ public class IdentifierManager { private String resolveUUID(CoreValue uuid) { try { Map<String, CoreValue> bindings = Collections.singletonMap("id", uuid); - Result result = queryEngine.executeQuery("SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2, - Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default()); + Result result = queryEngine.executeQuery( + "SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2, + Long.MAX_VALUE, 0, bindings, root, new NamePathMapper.Default()); String path = null; for (ResultRow rr : result.getRows()) { Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Fri Sep 14 10:07:31 2012 @@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.api.Con import org.apache.jackrabbit.oak.api.CoreValue; import org.apache.jackrabbit.oak.api.CoreValueFactory; import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.query.ast.AstVisitorBase; @@ -60,7 +61,8 @@ import org.apache.jackrabbit.oak.spi.sta /** * Represents a parsed query. Lifecycle: use the constructor to create a new - * object. Call init() to initialize the bind variable map. + * object. Call init() to initialize the bind variable map. If the query is + * re-executed, a new instance is created. */ public class Query { @@ -81,6 +83,7 @@ public class Query { private boolean prepared; private final CoreValueFactory valueFactory; private ContentSession session; + private Root root; private NamePathMapper namePathMapper; Query(SourceImpl source, ConstraintImpl constraint, OrderingImpl[] orderings, @@ -669,10 +672,6 @@ public class Query { return new ArrayList<String>(bindVariableMap.keySet()); } - public String getWorkspaceName() { - return session.getWorkspaceName(); - } - public void setQueryEngine(QueryEngineImpl queryEngine) { this.queryEngine = queryEngine; } @@ -684,6 +683,10 @@ public class Query { public void setSession(ContentSession session) { this.session = session; } + + public void setRoot(Root root) { + this.root = root; + } public void setNamePathMapper(NamePathMapper namePathMapper) { this.namePathMapper = namePathMapper; @@ -694,7 +697,7 @@ public class Query { } public Tree getTree(String path) { - return session.getCurrentRoot().getTree(path); + return root.getTree(path); } @Override 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=1384708&r1=1384707&r2=1384708&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 Fri Sep 14 10:07:31 2012 @@ -26,6 +26,7 @@ import org.apache.jackrabbit.mk.api.Micr import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.CoreValue; import org.apache.jackrabbit.oak.api.CoreValueFactory; +import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.query.index.FilterImpl; import org.apache.jackrabbit.oak.query.index.TraversingIndex; @@ -92,11 +93,13 @@ public class QueryEngineImpl { return q; } - public ResultImpl executeQuery(String statement, String language, ContentSession session, + public ResultImpl executeQuery(String statement, String language, long limit, long offset, Map<String, ? extends CoreValue> bindings, + ContentSession session, Root root, NamePathMapper namePathMapper) throws ParseException { Query q = parseQuery(statement, language); q.setSession(session); + q.setRoot(root); q.setNamePathMapper(namePathMapper); q.setLimit(limit); q.setOffset(offset); Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java Fri Sep 14 10:07:31 2012 @@ -23,6 +23,7 @@ import java.util.Map; import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.CoreValue; import org.apache.jackrabbit.oak.api.Result; +import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.SessionQueryEngine; import org.apache.jackrabbit.oak.namepath.NamePathMapper; @@ -53,9 +54,9 @@ public class SessionQueryEngineImpl impl @Override public Result executeQuery(String statement, String language, long limit, long offset, Map<String, ? extends CoreValue> bindings, - NamePathMapper namePathMapper) throws ParseException { - return queryEngine.executeQuery(statement, language, session, limit, - offset, bindings, namePathMapper); + Root root, NamePathMapper namePathMapper) throws ParseException { + return queryEngine.executeQuery(statement, language, limit, + offset, bindings, session, root, namePathMapper); } } Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java Fri Sep 14 10:07:31 2012 @@ -205,7 +205,7 @@ class UserProviderImpl extends Authoriza Result result = queryEngine.executeQuery(stmt, Query.JCR_SQL2, 1, 0, Collections.singletonMap("principalName", bindValue), - new NamePathMapper.Default()); + root, new NamePathMapper.Default()); Iterator<? extends ResultRow> rows = result.getRows().iterator(); if (rows.hasNext()) { Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/AbstractLuceneQueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/AbstractLuceneQueryTest.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/AbstractLuceneQueryTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/AbstractLuceneQueryTest.java Fri Sep 14 10:07:31 2012 @@ -96,6 +96,6 @@ public abstract class AbstractLuceneQuer } protected Result executeQuery(String statement) throws ParseException { - return qe.executeQuery(statement, SQL2, Long.MAX_VALUE, 0, null, null); + return qe.executeQuery(statement, SQL2, Long.MAX_VALUE, 0, null, session.getCurrentRoot(), null); } } \ No newline at end of file Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java Fri Sep 14 10:07:31 2012 @@ -231,7 +231,8 @@ public class QueryTest extends AbstractQ } private Result executeQuery(String statement, String language, HashMap<String, CoreValue> sv) throws ParseException { - return qe.executeQuery(statement, language, Long.MAX_VALUE, 0, sv, null); + return qe.executeQuery(statement, language, Long.MAX_VALUE, 0, sv, + session.getCurrentRoot(), null); } /** Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Fri Sep 14 10:07:31 2012 @@ -171,9 +171,14 @@ public class SessionDelegate { } @CheckForNull - public NodeDelegate getRoot() { + public NodeDelegate getRootNode() { return getNode("/"); } + + @CheckForNull + public Root getRoot() { + return root; + } /** * {@code NodeDelegate} at the given path Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Fri Sep 14 10:07:31 2012 @@ -130,7 +130,7 @@ public class SessionImpl extends Abstrac return dlg.perform(new SessionOperation<NodeImpl>() { @Override public NodeImpl perform() throws AccessDeniedException { - NodeDelegate nd = dlg.getRoot(); + NodeDelegate nd = dlg.getRootNode(); if (nd == null) { throw new AccessDeniedException("Root node is not accessible."); } else { Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java?rev=1384708&r1=1384707&r2=1384708&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java Fri Sep 14 10:07:31 2012 @@ -112,7 +112,8 @@ public class QueryManagerImpl implements try { HashMap<String, CoreValue> bindMap = convertMap(bindVariableMap); NamePathMapper namePathMapper = sessionDelegate.getNamePathMapper(); - Result r = queryEngine.executeQuery(statement, language, limit, offset, bindMap, namePathMapper); + Result r = queryEngine.executeQuery(statement, language, limit, offset, + bindMap, sessionDelegate.getRoot(), namePathMapper); return new QueryResultImpl(sessionDelegate, r); } catch (IllegalArgumentException e) { throw new InvalidQueryException(e);