Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6253DEB54 for ; Mon, 28 Jan 2013 15:52:56 +0000 (UTC) Received: (qmail 83684 invoked by uid 500); 28 Jan 2013 15:52:56 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 83646 invoked by uid 500); 28 Jan 2013 15:52:56 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 83630 invoked by uid 99); 28 Jan 2013 15:52:56 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Jan 2013 15:52:56 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Jan 2013 15:52:52 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 8514523888CD; Mon, 28 Jan 2013 15:52:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1439454 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/index/ main/java/org/apache/jackrabbit/oak/spi/query/ test/java/org/apache/jackrabbit/oak/plugins/index/p2/ test/java/org/apache/jackrabbit/oak/quer... Date: Mon, 28 Jan 2013 15:52:31 -0000 To: oak-commits@jackrabbit.apache.org From: thomasm@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130128155231.8514523888CD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: thomasm Date: Mon Jan 28 15:52:30 2013 New Revision: 1439454 URL: http://svn.apache.org/viewvc?rev=1439454&view=rev Log: OAK-359 QueryEngine joins lack nodeType information Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Cursors.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexQueryTest.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java Mon Jan 28 15:52:30 2013 @@ -56,7 +56,7 @@ public class FilterImpl implements Filte */ private String path = "/"; - private PathRestriction pathRestriction = PathRestriction.ALL_CHILDREN; + private PathRestriction pathRestriction = PathRestriction.NO_RESTRICTION; /** * The node type, or null if not set. @@ -141,6 +141,7 @@ public class FilterImpl implements Filte alwaysFalse = true; } + @Override public boolean isAlwaysFalse() { return alwaysFalse; } @@ -170,6 +171,8 @@ public class FilterImpl implements Filte return false; } switch (pathRestriction) { + case NO_RESTRICTION: + return true; case EXACT: return path.matches(this.path); case PARENT: @@ -292,8 +295,12 @@ public class FilterImpl implements Filte // calculating the intersection of path restrictions // this is ugly code, but I don't currently see a radically simpler method switch (addedPathRestriction) { + case NO_RESTRICTION: + break; case PARENT: switch (pathRestriction) { + case NO_RESTRICTION: + break; case PARENT: // ignore as it's fast anyway // (would need to loop to find a common ancestor) @@ -311,6 +318,8 @@ public class FilterImpl implements Filte break; case EXACT: switch (pathRestriction) { + case NO_RESTRICTION: + break; case PARENT: if (!PathUtils.isAncestor(addedPath, path)) { setAlwaysFalse(); @@ -337,6 +346,10 @@ public class FilterImpl implements Filte break; case ALL_CHILDREN: switch (pathRestriction) { + case NO_RESTRICTION: + path = addedPath; + pathRestriction = PathRestriction.ALL_CHILDREN; + break; case PARENT: case EXACT: if (!PathUtils.isAncestor(addedPath, path)) { @@ -359,6 +372,10 @@ public class FilterImpl implements Filte break; case DIRECT_CHILDREN: switch (pathRestriction) { + case NO_RESTRICTION: + path = addedPath; + pathRestriction = PathRestriction.DIRECT_CHILDREN; + break; case PARENT: if (!PathUtils.isAncestor(addedPath, path)) { setAlwaysFalse(); Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java Mon Jan 28 15:52:30 2013 @@ -37,6 +37,9 @@ public class TraversingIndex implements @Override public double getCost(Filter filter, NodeState rootState) { + if (filter.isAlwaysFalse()) { + return 0; + } String path = filter.getPath(); // TODO estimate or read the node count double nodeCount = 10000000; 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=1439454&r1=1439453&r2=1439454&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 Mon Jan 28 15:52:30 2013 @@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.commons 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; import org.apache.jackrabbit.oak.spi.state.NodeStateUtils; @@ -37,7 +38,6 @@ import com.google.common.collect.Iterato import com.google.common.collect.Queues; import static org.apache.jackrabbit.oak.commons.PathUtils.isAbsolute; -import static org.apache.jackrabbit.oak.spi.query.Filter.PathRestriction.ALL_CHILDREN; /** * This utility class provides factory methods to create commonly used types of @@ -165,6 +165,12 @@ public class Cursors { currentPath = "/"; NodeState parent = null; NodeState node = rootState; + + if (filter.isAlwaysFalse()) { + // nothing can match this filter, leave nodes empty + return; + } + if (!path.equals("/")) { for (String name : path.substring(1).split("/")) { parentPath = currentPath; @@ -181,6 +187,7 @@ public class Cursors { } Filter.PathRestriction restriction = filter.getPathRestriction(); switch (restriction) { + case NO_RESTRICTION: case EXACT: case ALL_CHILDREN: nodeIterators.add(Iterators.singletonIterator( @@ -245,7 +252,9 @@ public class Cursors { } currentPath = PathUtils.concat(parentPath, name); - if (filter.getPathRestriction() == ALL_CHILDREN) { + PathRestriction r = filter.getPathRestriction(); + if (r == PathRestriction.ALL_CHILDREN || + r == PathRestriction.NO_RESTRICTION) { nodeIterators.addLast(node.getChildNodeEntries().iterator()); parentPath = currentPath; } Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java Mon Jan 28 15:52:30 2013 @@ -91,6 +91,14 @@ public interface Filter { */ @Nullable String getQueryStatement(); + + /** + * If the filter condition can not possibly match any row, due to a + * contradiction in the query (for example "x=1 and x=2"). + * + * @return true if the filter condition can not match any row + */ + boolean isAlwaysFalse(); /** * A restriction for a property. @@ -146,9 +154,14 @@ public interface Filter { * The path restriction type. */ enum PathRestriction { + + /** + * All nodes. + */ + NO_RESTRICTION("*"), /** - * A parent of this node + * A parent of this node. */ PARENT("/.."), @@ -163,7 +176,8 @@ public interface Filter { DIRECT_CHILDREN("/*"), /** - * All direct and indirect child nodes. + * All direct and indirect child nodes (excluding the node with the + * given path). */ ALL_CHILDREN("//*"); Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexQueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexQueryTest.java?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexQueryTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexQueryTest.java Mon Jan 28 15:52:30 2013 @@ -20,6 +20,7 @@ import org.apache.jackrabbit.oak.Oak; import org.apache.jackrabbit.oak.api.ContentRepository; import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent; import org.apache.jackrabbit.oak.query.AbstractQueryTest; +import org.junit.Ignore; import org.junit.Test; /** @@ -41,4 +42,10 @@ public class Property2IndexQueryTest ext test("sql2_index.txt"); } + @Test + @Ignore("OAK-590") + public void sql2Explain() throws Exception { + test("sql2_explain.txt"); + } + } \ No newline at end of file Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java Mon Jan 28 15:52:30 2013 @@ -143,7 +143,7 @@ public class FilterTest { public void pathRestrictions() throws Exception { FilterImpl f = new FilterImpl(null, null); assertEquals("/", f.getPath()); - assertEquals(Filter.PathRestriction.ALL_CHILDREN, + assertEquals(Filter.PathRestriction.NO_RESTRICTION, f.getPathRestriction()); f.restrictPath("/test", Filter.PathRestriction.ALL_CHILDREN); Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt?rev=1439454&r1=1439453&r2=1439454&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt (original) +++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_explain.txt Mon Jan 28 15:52:30 2013 @@ -28,10 +28,10 @@ commit / + "test": { "a": { "id": "ref:123" }, "b": { "id" : "str:123" }} explain select * from [nt:base] where property([*], 'REFERENCE') = CAST('123' AS REFERENCE) -[nt:base] as [nt:base] /* traverse "//*" where property([nt:base].[*], 'reference') = cast('123' as reference) */ +[nt:base] as [nt:base] /* traverse "*" where property([nt:base].[*], 'reference') = cast('123' as reference) */ explain select * from [nt:base] where property(id, 'REFERENCE') = CAST('123' AS REFERENCE) -[nt:base] as [nt:base] /* traverse "//*" where property([nt:base].[id], 'reference') = cast('123' as reference) */ +[nt:base] as [nt:base] /* traverse "*" where property([nt:base].[id], 'reference') = cast('123' as reference) */ explain select b.[jcr:path] as [jcr:path], b.[jcr:score] as [jcr:score], b.* from [nt:base] as a inner join [nt:base] as b on ischildnode(a, b) where name(a) = 'yes' and isdescendantnode(a, '/test') and b.[x] is not null [nt:base] as [a] /* traverse "/test//*" where (name([a]) = cast('yes' as string)) and (isdescendantnode([a], [/test])) */ inner join [nt:base] as [b] /* traverse "/path/from/the/join" where [b].[x] is not null */ on ischildnode([a], [b]) @@ -81,7 +81,7 @@ select [jcr:path], * from [nt:base] wher /test/a, /test/a explain select * from [nt:base] where id > '10' -[nt:base] as [nt:base] /* traverse "//*" where [nt:base].[id] > cast('10' as string) */ +[nt:base] as [nt:base] /* traverse "*" where [nt:base].[id] > cast('10' as string) */ commit / - "test" commit /oak:index/indexes - "property@id,unique" @@ -102,16 +102,16 @@ commit / + "parents": { "p0": {"id": "0" commit / + "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": {"p": "2"}, "c4": {"p": "3"}} explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p -[nt:base] as [p] /* traverse "//*" where [p].[id] is not null */ inner join [nt:base] as [c] /* traverse "//*" where [c].[p] is not null */ on [p].[id] = [c].[p] +[nt:base] as [p] /* traverse "*" where [p].[id] is not null */ inner join [nt:base] as [c] /* traverse "*" where [c].[p] is not null */ on [p].[id] = [c].[p] explain select * from [nt:base] as p inner join [nt:base] as p2 on issamenode(p2, p) where p.[jcr:path] = '/parents' -[nt:base] as [p] /* traverse "//*" where [p].[jcr:path] = cast('/parents' as string) */ inner join [nt:base] as [p2] /* traverse "/path/from/the/join/selector" */ on issamenode([p2], [p], [.]) +[nt:base] as [p] /* traverse "*" where [p].[jcr:path] = cast('/parents' as string) */ inner join [nt:base] as [p2] /* traverse "/path/from/the/join/selector" */ on issamenode([p2], [p], [.]) explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p -[nt:base] as [p] /* traverse "//*" where [p].[id] is not null */ inner join [nt:base] as [c] /* traverse "//*" where [c].[p] is not null */ on [p].[id] = [c].[p] +[nt:base] as [p] /* traverse "*" where [p].[id] is not null */ inner join [nt:base] as [c] /* traverse "*" where [c].[p] is not null */ on [p].[id] = [c].[p] explain select * from [nt:base] where id = 1 order by id -[nt:base] as [nt:base] /* traverse "//*" where [nt:base].[id] = cast('1' as long) */ +[nt:base] as [nt:base] /* traverse "*" where [nt:base].[id] = cast('1' as long) */ commit / - "parents" commit / - "children"