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 2012/04/13 18:53:29 UTC

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

Author: thomasm
Date: Fri Apr 13 16:53:28 2012
New Revision: 1325841

URL: http://svn.apache.org/viewvc?rev=1325841&view=rev
Log:
OAK-36 Implement a query parser (XPath to SQL-2 converter)

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

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java?rev=1325841&r1=1325840&r2=1325841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java Fri Apr 13 16:53:28 2012
@@ -56,6 +56,10 @@ public class XPathToSQL2Converter {
      * @throws ParseException if parsing fails
      */
     public String convert(String query) throws ParseException {
+        // TODO verify this is correct
+        if (!query.startsWith("/")) {
+            query = "/jcr:root/" + query;
+        }
         initialize(query);
         expected = new ArrayList<String>();
         read();
@@ -126,15 +130,10 @@ public class XPathToSQL2Converter {
         }
         if (path.isEmpty()) {
             // no condition
-        } else if (path.equals("%")) {
-            // ignore
         } else {
             if (descendants) {
-                Function f1 = new Function("issamenode");
-                f1.params.add(Literal.newString(path));
-                Function f2 = new Function("isdescendantnode");
-                f2.params.add(Literal.newString(path));
-                Condition c = new Condition(f1, "or", f2);
+                Function c = new Function("isdescendantnode");
+                c.params.add(Literal.newString(path));
                 condition = add(condition, c);
             } else if (children) {
                 Function f = new Function("ischildnode");

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt?rev=1325841&r1=1325840&r2=1325841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt Fri Apr 13 16:53:28 2012
@@ -3,53 +3,71 @@
 # * lines starting with "xpath" are xpath queries, followed by expected sql2 query
 # * use ascii character only
 
-xpath /jcr:root//*[jcr:contains(., 'test')] order by @jcr:score
-select * from [nt:base] where contains(*, 'test') and (issamenode('/') or isdescendantnode('/')) order by [jcr:score]
+xpath //*[@name='Hello']
+select * from [nt:base] where [name] = 'Hello'
 
-xpath /jcr:root//element(*, test)
-select * from [test] where issamenode('/') or isdescendantnode('/')
+xpath /jcr:root//*[@name='Hello']
+select * from [nt:base] where ([name] = 'Hello') and isdescendantnode('/')
+
+xpath content/*
+select * from [nt:base] where ischildnode('/content')
+
+xpath content//*
+select * from [nt:base] where isdescendantnode('/content')
+
+xpath content//*[@name='Hello']
+select * from [nt:base] where ([name] = 'Hello') and isdescendantnode('/content')
+
+xpath /jcr:root/content//*[@name='Hello']
+select * from [nt:base] where ([name] = 'Hello') and isdescendantnode('/content')
+
+xpath //*[jcr:contains(., 'test')] order by @jcr:score
+select * from [nt:base] where contains(*, 'test') order by [jcr:score]
+
+xpath /jcr:root//*[jcr:contains(., 'test')] order by @jcr:score
+select * from [nt:base] where contains(*, 'test') and isdescendantnode('/') order by [jcr:score]
 
 xpath /jcr:root//element(*, test)
-select * from [test] where issamenode('/') or isdescendantnode('/')
+select * from [test] where isdescendantnode('/')
 
 xpath /jcr:root//element(*, user)[test/@jcr:primaryType]
-select * from [user] where ([test/jcr:primaryType] is not null) and (issamenode('/') or isdescendantnode('/'))
+select * from [user] where ([test/jcr:primaryType] is not null) and isdescendantnode('/')
 
 xpath /jcr:root/content//*[(@sling:resourceType = 'start')]
-select * from [nt:base] where ([sling:resourceType] = 'start') and (issamenode('/content') or isdescendantnode('/content'))
+select * from [nt:base] where ([sling:resourceType] = 'start') and isdescendantnode('/content')
 
 xpath /jcr:root/content//*[(@sling:resourceType = 'page')]
-select * from [nt:base] where ([sling:resourceType] = 'page') and (issamenode('/content') or isdescendantnode('/content'))
+select * from [nt:base] where ([sling:resourceType] = 'page') and isdescendantnode('/content')
 
 xpath /jcr:root/content//*[@offTime > xs:dateTime('2012-03-28T15:56:18.327+02:00') or @onTime > xs:dateTime('2012-03-28T15:56:18.327+02:00')]
-select * from [nt:base] where (([offTime] > cast('2012-03-28T15:56:18.327+02:00' as date)) or ([onTime] > cast('2012-03-28T15:56:18.327+02:00' as date))) and (issamenode('/content') or isdescendantnode('/content'))
+select * from [nt:base] where (([offTime] > cast('2012-03-28T15:56:18.327+02:00' as date)) or ([onTime] > cast('2012-03-28T15:56:18.327+02:00' as date))) and isdescendantnode('/content')
 
 xpath /jcr:root/content/campaigns//*[@jcr:primaryType='Page'] order by jcr:content/@lastModified descending
-select * from [nt:base] where ([jcr:primaryType] = 'Page') and (issamenode('/content/campaigns') or isdescendantnode('/content/campaigns')) order by [jcr:content/lastModified] desc
+select * from [nt:base] where ([jcr:primaryType] = 'Page') and isdescendantnode('/content/campaigns') order by [jcr:content/lastModified] desc
 
 xpath /jcr:root/content/campaigns//element(*, PageContent)[(@sling:resourceType = 'teaser' or @sling:resourceType = 'newsletter' or @teaserPageType = 'newsletter' or @teaserPageType = 'tweet') and ((@onTime < xs:dateTime('2012-04-01T00:00:00.000+02:00')) or not(@onTime)) and ((@offTime >= xs:dateTime('2012-02-26T00:00:00.000+01:00')) or not(@offTime))] order by @onTime
-select * from [PageContent] where (((((([sling:resourceType] = 'teaser') or ([sling:resourceType] = 'newsletter')) or ([teaserPageType] = 'newsletter')) or ([teaserPageType] = 'tweet')) and (([onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)) or ([onTime] is null))) and (([offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)) or ([offTime] is null))) and (issamenode('/content/campaigns') or isdescendantnode('/content/campaigns')) order by [onTime]
+select * from [PageContent] where (((((([sling:resourceType] = 'teaser') or ([sling:resourceType] = 'newsletter')) or ([teaserPageType] = 'newsletter')) or ([teaserPageType] = 'tweet')) and (([onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)) or ([onTime] is null))) and (([offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)) or ([offTime] is null))) and isdescendantnode('/content/campaigns') order by [onTime]
 
 xpath /jcr:root/content/dam//element(*, asset)[jcr:content/metadata/@dam:scene]
-select * from [asset] where ([jcr:content/metadata/dam:scene] is not null) and (issamenode('/content/dam') or isdescendantnode('/content/dam'))
+select * from [asset] where ([jcr:content/metadata/dam:scene] is not null) and isdescendantnode('/content/dam')
 
 xpath /jcr:root/etc/cloud//*[(@sling:resourceType = 'framework')]
-select * from [nt:base] where ([sling:resourceType] = 'framework') and (issamenode('/etc/cloud') or isdescendantnode('/etc/cloud'))
+select * from [nt:base] where ([sling:resourceType] = 'framework') and isdescendantnode('/etc/cloud')
 
 xpath /jcr:root/etc/cloud//*[(@sling:resourceType = 'analytics')]
-select * from [nt:base] where ([sling:resourceType] = 'analytics') and (issamenode('/etc/cloud') or isdescendantnode('/etc/cloud'))
+select * from [nt:base] where ([sling:resourceType] = 'analytics') and isdescendantnode('/etc/cloud')
 
 xpath /jcr:root/etc/reports//*[@jcr:primaryType='Page'] order by jcr:content/@lastModified descending
-select * from [nt:base] where ([jcr:primaryType] = 'Page') and (issamenode('/etc/reports') or isdescendantnode('/etc/reports')) order by [jcr:content/lastModified] desc
+select * from [nt:base] where ([jcr:primaryType] = 'Page') and isdescendantnode('/etc/reports') order by [jcr:content/lastModified] desc
 
 xpath /jcr:root/etc/segment//*[@jcr:primaryType='Page'] order by jcr:content/@lastModified descending
-select * from [nt:base] where ([jcr:primaryType] = 'Page') and (issamenode('/etc/segment') or isdescendantnode('/etc/segment')) order by [jcr:content/lastModified] desc
+select * from [nt:base] where ([jcr:primaryType] = 'Page') and isdescendantnode('/etc/segment') order by [jcr:content/lastModified] desc
 
 xpath /jcr:root/etc/workflow//element(*,Item)[not(meta/@archived) and not(meta/@archived = true)]
-select * from [Item] where (([meta/archived] is null) and not([meta/archived] = true)) and (issamenode('/etc/workflow') or isdescendantnode('/etc/workflow'))
+select * from [Item] where (([meta/archived] is null) and not([meta/archived] = true)) and isdescendantnode('/etc/workflow')
 
 xpath /jcr:root/home//element(*)
-select * from [nt:base] where issamenode('/home') or isdescendantnode('/home')
+select * from [nt:base] where isdescendantnode('/home')
 
 # other queries
 
@@ -66,7 +84,7 @@ xpath //element(*, my:type)/(@my:title |
 select [my:title], [my:text] from [my:type]
 
 xpath /jcr:root/nodes//element(*, my:type)
-select * from [my:type] where issamenode('/nodes') or isdescendantnode('/nodes')
+select * from [my:type] where isdescendantnode('/nodes')
 
 xpath /jcr:root/some/element(nodes, my:type)
 select * from [my:type] where [jcr:path] = '/some/nodes'
@@ -75,7 +93,7 @@ xpath /jcr:root/some/nodes/element(*, my
 select * from [my:type] where ischildnode('/some/nodes')
 
 xpath /jcr:root/some/nodes//element(*, my:type)
-select * from [my:type] where issamenode('/some/nodes') or isdescendantnode('/some/nodes')
+select * from [my:type] where isdescendantnode('/some/nodes')
 
 xpath //element(*, my:type)[@my:title = 'JSR 170']
 select * from [my:type] where [my:title] = 'JSR 170'
@@ -128,8 +146,8 @@ select * from [my:type] where contains(*
 xpath //element(*, my:type)[jcr:contains(@my:title, 'jcr')] order by jcr:score() descending
 select * from [my:type] where contains([my:title], 'jcr') order by score() desc
 
-xpath invalid/query
-invalid: Query: invalid(*)/query; expected: <end>
+xpath [invalid/query
+invalid: Query: /jcr:root/[(*)invalid/query; expected: identifier
 
 xpath //element(*, my:type)[@my:value = -'x']
 invalid: Query: //element(*, my:type)[@my:value = -'x'(*)]