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);


Reply via email to