You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2016/05/25 09:02:29 UTC

svn commit: r1745459 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java test/resources/org/apache/jackrabbit/oak/query/xpath.txt

Author: thomasm
Date: Wed May 25 09:02:29 2016
New Revision: 1745459

URL: http://svn.apache.org/viewvc?rev=1745459&view=rev
Log:
OAK-4387 XPath: querying for nodes named "text", "element", and "rep:excerpt" fails

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

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=1745459&r1=1745458&r2=1745459&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 Wed May 25 09:02:29 2016
@@ -192,46 +192,57 @@ public class XPathToSQL2Converter {
                         currentSelector.path = "/";
                     }
                 }
-            } else if (readIf("text")) {
-                // "...text()"
-                currentSelector.isChild = false;
-                pathPattern += "jcr:xmltext";
-                read("(");
-                read(")");
-                if (currentSelector.isDescendant) {
-                    currentSelector.nodeName = "jcr:xmltext";
-                } else {
-                    currentSelector.path = PathUtils.concat(currentSelector.path, "jcr:xmltext");
-                }
-            } else if (readIf("element")) {
-                // "...element(..."
-                read("(");
-                if (readIf(")")) {
-                    // any
-                    pathPattern += "%";
-                } else {
-                    if (readIf("*")) {
-                        // any
-                        pathPattern += "%";
+            } else if (currentTokenType == IDENTIFIER) {
+                // probably a path restriction
+                // String name = readPathSegment();
+                String identifier = readIdentifier();
+                if (readIf("(")) {
+                    if ("text".equals(identifier)) {
+                        // "...text()"
+                        currentSelector.isChild = false;
+                        pathPattern += "jcr:xmltext";
+                        read(")");
+                        if (currentSelector.isDescendant) {
+                            currentSelector.nodeName = "jcr:xmltext";
+                        } else {
+                            currentSelector.path = PathUtils.concat(currentSelector.path, "jcr:xmltext");
+                        }                        
+                    } else if ("element".equals(identifier)) {
+                        // "...element(..."
+                        if (readIf(")")) {
+                            // any
+                            pathPattern += "%";
+                        } else {
+                            if (readIf("*")) {
+                                // any
+                                pathPattern += "%";
+                            } else {
+                                String name = readPathSegment();
+                                pathPattern += name;
+                                appendNodeName(name);
+                            }
+                            if (readIf(",")) {
+                                currentSelector.nodeType = readIdentifier();
+                            }
+                            read(")");
+                        }
+                    } else if ("rep:excerpt".equals(identifier)) {
+                        readOpenDotClose(false);
+                        rewindSelector();
+                        Expression.Property p = new Expression.Property(currentSelector, "rep:excerpt", false);
+                        statement.addSelectColumn(p);
                     } else {
-                        String name = readPathSegment();
-                        pathPattern += name;
-                        appendNodeName(name);
-                    }
-                    if (readIf(",")) {
-                        currentSelector.nodeType = readIdentifier();
+                        throw getSyntaxError();
                     }
-                    read(")");
+                } else {
+                    String name = ISO9075.decode(identifier);
+                    pathPattern += name;
+                    appendNodeName(name);
                 }
             } else if (readIf("@")) {
                 rewindSelector();
                 Expression.Property p = readProperty();
                 statement.addSelectColumn(p);
-            } else if (readIf("rep:excerpt")) {
-                rewindSelector();
-                readExcerpt();
-                Expression.Property p = new Expression.Property(currentSelector, "rep:excerpt", false);
-                statement.addSelectColumn(p);
             } else if (readIf("(")) {
                 rewindSelector();
                 do {
@@ -239,7 +250,7 @@ public class XPathToSQL2Converter {
                         Expression.Property p = readProperty();
                         statement.addSelectColumn(p);
                     } else if (readIf("rep:excerpt")) {
-                        readExcerpt();
+                        readOpenDotClose(true);
                         Expression.Property p = new Expression.Property(currentSelector, "rep:excerpt", false);
                         statement.addSelectColumn(p);
                     } else if (readIf("rep:spellcheck")) {
@@ -249,7 +260,7 @@ public class XPathToSQL2Converter {
                         Expression.Property p = new Expression.Property(currentSelector, "rep:spellcheck()", false);
                         statement.addSelectColumn(p);
                     } else if (readIf("rep:suggest")) {
-                        readExcerpt();
+                        readOpenDotClose(true);
                         Expression.Property p = new Expression.Property(currentSelector, "rep:suggest()", false);
                         statement.addSelectColumn(p);
                     }
@@ -257,11 +268,6 @@ public class XPathToSQL2Converter {
                 if (!readIf(")")) {
                     return convertToUnion(query, statement, startParseIndex - 1);
                 }
-            } else if (currentTokenType == IDENTIFIER) {
-                // path restriction
-                String name = readPathSegment();
-                pathPattern += name;
-                appendNodeName(name);
             } else if (readIf(".")) {
                 // just "." this is simply ignored, so that
                 // "a/./b" is the same as "a/b"
@@ -717,13 +723,19 @@ public class XPathToSQL2Converter {
         return new Expression.Property(currentSelector, readPathSegment(), false);
     }
     
-    private void readExcerpt() throws ParseException {
-        read("(");
-        if (!readIf(")")) {
-            // only rep:excerpt(.) and rep:excerpt() are currently supported
-            read(".");
-            read(")");
+    /**
+     * Read open bracket (optional), and optional dot, and close bracket.
+     * 
+     * @param readOpenBracket whether to read the open bracket (false if this
+     *            was already read)
+     * @throws ParseException if close bracket or the dot were not read
+     */
+    private void readOpenDotClose(boolean readOpenBracket) throws ParseException {
+        if (readOpenBracket) {
+            read("(");
         }
+        readIf(".");
+        read(")");
     }
 
     private String readPathSegment() throws ParseException {

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt?rev=1745459&r1=1745458&r2=1745459&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt Wed May 25 09:02:29 2016
@@ -24,6 +24,13 @@
 # * new tests are typically be added on top, after the syntax docs
 # * use ascii character only
 
+# OAK-4387
+xpath2sql /jcr:root/content/text/element/rep:excerpt/jcr:content//element(*,nt:unstructured)
+select [jcr:path], [jcr:score], *
+  from [nt:unstructured] as a
+  where isdescendantnode(a, '/content/text/element/rep:excerpt/jcr:content')
+  /* xpath ... */
+
 # OAK-4376
 
 xpath2sql //element(*, oak:QueryIndexDefinition)/*
@@ -592,22 +599,22 @@ select [jcr:path], [jcr:score], *
   /* xpath ... */
 
 xpath2sql /
-invalid: Query: (*)/; expected: jcr:root, /, *, text, element, @, rep:excerpt, (, .
+invalid: Query: (*)/; expected: jcr:root, /, *, @, (, .
 
 xpath2sql /[@name='data']
-invalid: Query: /[(*)@name='data']; expected: jcr:root, /, *, text, element, @, rep:excerpt, (, .
+invalid: Query: /[(*)@name='data']; expected: jcr:root, /, *, @, (, .
 
 xpath2sql //[@name='data']
-invalid: Query: //[(*)@name='data']; expected: *, text, element, @, rep:excerpt, (, .
+invalid: Query: //[(*)@name='data']; expected: *, @, (, .
 
 xpath2sql //child/[@id='2.1']
-invalid: Query: //child/[(*)@id='2.1']; expected: jcr:root, /, *, text, element, @, rep:excerpt, (, .
+invalid: Query: //child/[(*)@id='2.1']; expected: jcr:root, /, *, @, (, .
 
 xpath2sql //
-invalid: Query: /(*)/; expected: *, text, element, @, rep:excerpt, (, .
+invalid: Query: /(*)/; expected: *, @, (, .
 
 xpath2sql [@name='data']
-invalid: Query: [(*)@name='data']; expected: /, *, text, element, @, rep:excerpt, (, .
+invalid: Query: [(*)@name='data']; expected: /, *, @, (, .
 
 xpath2sql test
 select [jcr:path], [jcr:score], *
@@ -930,7 +937,7 @@ select b.[jcr:path] as [jcr:path], b.[jc
   /* xpath ... */
 
 xpath2sql /jcr:root/testroot/people/jcr:deref(@worksfor, '*')
-invalid: Query: /jcr:root/testroot/people/jcr:deref((*)@worksfor, '*'); expected: <end>
+invalid: Query: /jcr:root/testroot/people/jcr:deref(@(*)worksfor, '*')
 
 xpath2sql //*[@jcr:primaryType='nt:unstructured' and jcr:like(@foo,"%ar'ba%")]
 select [jcr:path], [jcr:score], *
@@ -1494,7 +1501,7 @@ select [jcr:path], [jcr:score], *
   /* xpath ... */
 
 xpath2sql [invalid/query
-invalid: Query: [(*)invalid/query; expected: /, *, text, element, @, rep:excerpt, (, .
+invalid: Query: [(*)invalid/query; expected: /, *, @, (, .
 
 xpath2sql //element(*, my:type)[@my:value = -'x']
 invalid: Query: //element(*, my:type)[@my:value = -'x'(*)]