Author: thomasm
Date: Thu Feb  6 15:17:01 2014
New Revision: 1565301

URL: http://svn.apache.org/r1565301
Log:
OAK-1389 Query: an index is used even where traversing is faster (test case)

Modified:
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java?rev=1565301&r1=1565300&r2=1565301&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
 Thu Feb  6 15:17:01 2014
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.jcr.query;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import javax.jcr.Node;
@@ -79,4 +80,141 @@ public class QueryPlanTest extends Abstr
         assertEquals("/testroot/node1", path);
         
     }
+    
+    @Test
+    public void uuidIndex() throws Exception {
+        Session session = getAdminSession();
+        QueryManager qm = session.getWorkspace().getQueryManager();
+        Node testRootNode = session.getRootNode().addNode("testroot");
+        Node n = testRootNode.addNode("node");
+        n.addMixin("mix:referenceable");
+        session.save();
+
+        // this matches just one node (exact path),
+        // so it should use the TraversintIndex
+        String xpath = "/jcr:root/testroot/node[@jcr:uuid]";
+
+        Query q;
+        QueryResult result;
+        RowIterator it;
+
+        q = qm.createQuery("explain " + xpath, "xpath");
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        String plan = it.nextRow().getValue("plan").getString();
+        assertEquals("[nt:base] as [a] /* traverse \"/testroot/node\" where " 
+ 
+                "([a].[jcr:uuid] is not null) " + 
+                "and (issamenode([a], [/testroot/node])) */", plan);
+
+        // verify the result
+        q = qm.createQuery(xpath, "xpath");
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        String path = it.nextRow().getPath();
+        assertEquals("/testroot/node", path);
+        assertFalse(it.hasNext());
+
+        // this potentially matches many nodes,
+        // so it should use the index on the UUID property
+        xpath = "/jcr:root/testroot/*[@jcr:uuid]";
+        
+        q = qm.createQuery("explain " + xpath, "xpath");
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        plan = it.nextRow().getValue("plan").getString();
+        assertEquals("[nt:base] as [a] /* property jcr:uuid " + 
+                "where ([a].[jcr:uuid] is not null) " + 
+                "and (ischildnode([a], [/testroot])) */", plan);
+        
+    }
+    
+    @Test
+    @Ignore("OAK-1372")
+    public void pathAndPropertyRestrictions() throws Exception {
+        ; // TODO work in progress
+        Session session = getAdminSession();
+        QueryManager qm = session.getWorkspace().getQueryManager();
+        Node testRootNode = session.getRootNode().addNode("testroot");
+        Node b = testRootNode.addNode("b");
+        Node c = b.addNode("c");
+        Node d = c.addNode("d");
+        Node e1 = d.addNode("e1");
+        e1.setProperty("type", "1");
+        Node e2 = d.addNode("e2");
+        e2.setProperty("type", "2");
+        Node e3 = d.addNode("e3");
+        e3.setProperty("type", "3");
+        session.save();
+       
+        String xpath = "/jcr:root/testroot//b/c/d/*[@jcr:uuid='1' or 
@jcr:uuid='2'] ";
+        String 
+        sql2 = 
+                "select d.[jcr:path] as [jcr:path], d.[jcr:score] as 
[jcr:score], d.* " + 
+                "from [nt:base] as a inner join [nt:base] as b on 
ischildnode(b, a) " + 
+                "inner join [nt:base] as c on ischildnode(c, b) " + 
+                "inner join [nt:base] as d on ischildnode(d, c) " + 
+                "where name(a) = 'b' " + 
+                "and isdescendantnode(a, '/testroot') " + 
+                "and name(b) = 'c' " + 
+                "and name(c) = 'd' " + 
+                "and (d.[jcr:uuid] = '1' or d.[jcr:uuid] = '2')";
+
+        sql2 = 
+                "select d.[jcr:path] as [jcr:path], d.[jcr:score] as 
[jcr:score], d.* " + 
+                "from [nt:base] as d " + 
+                "where (d.[jcr:uuid] = '1' or d.[jcr:uuid] = '2')";
+
+        sql2 = 
+                "select d.[jcr:path] as [jcr:path], d.[jcr:score] as 
[jcr:score], d.* " + 
+                "from [nt:base] as d " + 
+                "inner join [nt:base] as c on ischildnode(d, c) " + 
+                "inner join [nt:base] as b on ischildnode(c, b) " + 
+                "inner join [nt:base] as a on ischildnode(b, a) " + 
+                "where name(a) = 'b' " + 
+                "and isdescendantnode(a, '/testroot') " + 
+                "and name(b) = 'c' " + 
+                "and name(c) = 'd' " + 
+                "and (d.[jcr:uuid] = '1' or d.[jcr:uuid] = '2')";
+
+        Query q;
+        QueryResult result;
+        RowIterator it;
+        
+        q = qm.createQuery("explain " + sql2, Query.JCR_SQL2);
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        String plan = it.nextRow().getValue("plan").getString();
+        assertEquals("", plan);
+        
+        // [nt:base] as [a] /* traverse "/testroot//*" 
+        // where (name([a]) = cast('b' as string)) 
+        // and (isdescendantnode([a], [/testroot])) */ 
+        // inner join [nt:base] as [b] /* traverse 
+        // "/path/from/the/join/selector/*" where name([b]) = cast('c' as 
string) */ 
+        // on ischildnode([b], [a]) inner join [nt:base] as [c] 
+        // /* traverse "/path/from/the/join/selector/*"
+        // where name([c]) = cast('d' as string) */ on ischildnode([c], [b]) 
+        // inner join [nt:base] as [d] /* traverse 
"/path/from/the/join/selector/*" 
+        // where ([d].[type] is not null) and ([d].[type] in(cast('1' as 
string), cast('2' as string))) */ 
+        // on ischildnode([d], [c])
+        
+//        assertEquals("[nt:base] as [nt:base] /* traverse \"*\" " + 
+//                "where [nt:base].[node2/node3/jcr:primaryType] is not null 
*/", 
+//                plan);
+        
+        // verify the result
+        q = qm.createQuery(xpath, "xpath");
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        String path = it.nextRow().getValue("path").getString();
+        assertEquals("/testroot/b/c/d/e1", path);
+        path = it.nextRow().getValue("path").getString();
+        assertEquals("/testroot/b/c/d/e2", path);
+        assertFalse(it.hasNext());
+    }
 }


Reply via email to