Author: thomasm
Date: Fri Nov  4 10:04:22 2016
New Revision: 1767999

URL: http://svn.apache.org/viewvc?rev=1767999&view=rev
Log:
OAK-5064 XPath: chained conditions and union bugfix

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java?rev=1767999&r1=1767998&r2=1767999&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
 Fri Nov  4 10:04:22 2016
@@ -298,9 +298,11 @@ public class XPathToSQL2Converter {
                 throw getSyntaxError();
             }
             if (readIf("[")) {
-                Expression c = parseConstraint();
-                currentSelector.condition = 
Expression.and(currentSelector.condition, c);
-                read("]");
+                do {
+                    Expression c = parseConstraint();
+                    currentSelector.condition = 
Expression.and(currentSelector.condition, c);
+                    read("]");
+                } while (readIf("["));
             }
             startOfQuery = false;
             nextSelector(false);
@@ -1088,8 +1090,9 @@ public class XPathToSQL2Converter {
         converter.read("(");
         int level = 0;
         ArrayList<String> parts = new ArrayList<String>();
+        int parseIndex;
         while (true) {
-            int parseIndex = converter.parseIndex;
+            parseIndex = converter.parseIndex;
             if (converter.readIf("(")) {
                 level++;
             } else if (converter.readIf(")") && level-- <= 0) {
@@ -1098,8 +1101,8 @@ public class XPathToSQL2Converter {
                 String or = partList.substring(lastOrIndex, lastParseIndex);
                 parts.add(or);
                 lastOrIndex = parseIndex;
-            } else if (currentTokenType == END) {
-                throw getSyntaxError("the query may not be empty");
+            } else if (converter.currentTokenType == END) {
+                throw getSyntaxError("empty query or missing ')'");
             } else {
                 converter.read();
             }
@@ -1107,7 +1110,7 @@ public class XPathToSQL2Converter {
         }
         String or = partList.substring(lastOrIndex, lastParseIndex);
         parts.add(or);        
-        String end = partList.substring(lastParseIndex + 1);
+        String end = partList.substring(parseIndex);
         Statement result = null;
         for(String p : parts) {
             String q = begin + p + end;

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java?rev=1767999&r1=1767998&r2=1767999&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
 Fri Nov  4 10:04:22 2016
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.query;
 
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import java.text.ParseException;
 
@@ -71,9 +72,58 @@ public class XPathTest {
                 "order by [c] " + 
                 "option(traversal OK)");            
     }
+
+    @Test
+    public void chainedConditions() throws ParseException {
+        verify("/jcr:root/x[@a][@b][@c]",
+                "select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where [a] is not null " +
+                "and [b] is not null " +
+                "and [c] is not null " +
+                "and issamenode(a, '/x') " +
+                "/* xpath: /jcr:root/x[@a][@b][@c] */");
+    }
     
     @Test
-    public void test() throws ParseException {
+    public void union() throws ParseException {
+        try {
+            verify("(/jcr:root/x[@a][@b][@c]","");
+            fail();
+        } catch (ParseException e) {
+            // expected
+        }
+        verify("(/jcr:root/x[@a] | /jcr:root/y[@b])[@c]",
+                "select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where [a] is not null " +
+                "and [c] is not null " +
+                "and issamenode(a, '/x') " +
+                "/* xpath: /jcr:root/x[@a][@c] */ " +
+                "union select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where [b] is not null " +
+                "and [c] is not null " +
+                "and issamenode(a, '/y') " +
+                "/* xpath: /jcr:root/y[@b][@c] */");
+        verify("(/jcr:root/x | /jcr:root/y)",
+                "select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where issamenode(a, '/x') " +
+                "/* xpath: /jcr:root/x */ " +
+                "union select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where issamenode(a, '/y') " +
+                "/* xpath: /jcr:root/y */");
+        verify("(/jcr:root/x | /jcr:root/y )",
+                "select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where issamenode(a, '/x') " +
+                "/* xpath: /jcr:root/x */ " +
+                "union select [jcr:path], [jcr:score], * " +
+                "from [nt:base] as a " +
+                "where issamenode(a, '/y') " +
+                "/* xpath: /jcr:root/y */");
         verify("(/jcr:root/content//*[@a] | /jcr:root/lib//*[@b]) order by @c",
                 "select [jcr:path], [jcr:score], * " + 
                 "from [nt:base] as a " + 


Reply via email to