Author: thomasm
Date: Wed Feb 10 14:36:46 2016
New Revision: 1729608
URL: http://svn.apache.org/viewvc?rev=1729608&view=rev
Log:
OAK-3991 Incorrect resultset from XPATH, multiple ORs and Lucene full-text (WIP)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.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/Expression.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java?rev=1729608&r1=1729607&r2=1729608&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Expression.java
Wed Feb 10 14:36:46 2016
@@ -477,27 +477,41 @@ abstract class Expression {
return nt;
}
return right.getMostSpecificNodeType(selectorName);
- }
+ }
@Override
AndCondition pullOrRight() {
- if (right instanceof OrCondition) {
- return this;
- } else if (left instanceof OrCondition) {
- return new AndCondition(right, left);
+ ArrayList<Expression> list = getAllAndConditions();
+ OrCondition or = null;
+ Expression result = null;
+ for(Expression e : list) {
+ if (e instanceof OrCondition && or == null) {
+ or = (OrCondition) e;
+ } else if (result == null) {
+ result = e;
+ } else {
+ result = new AndCondition(result, e);
+ }
+ }
+ if (or != null) {
+ result = new AndCondition(result, or);
+ }
+ return (AndCondition) result;
+ }
+
+ private ArrayList<Expression> getAllAndConditions() {
+ ArrayList<Expression> list = new ArrayList<Expression>();
+ if (left instanceof AndCondition) {
+ list.addAll(((AndCondition) left).getAllAndConditions());
+ } else {
+ list.add(left);
}
if (right instanceof AndCondition) {
- // pull up x:
- // a and (b and (x)) -> (a and b) and (x)
- AndCondition r2 = (AndCondition) right;
- r2 = r2.pullOrRight();
- AndCondition l2 = new AndCondition(left, r2.left);
- l2 = l2.pullOrRight();
- return new AndCondition(l2, r2.right);
- } else if (left instanceof AndCondition) {
- return new AndCondition(right, left).pullOrRight();
+ list.addAll(((AndCondition) right).getAllAndConditions());
+ } else {
+ list.add(right);
}
- return this;
+ return list;
}
@Override
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=1729608&r1=1729607&r2=1729608&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 Feb 10 14:36:46 2016
@@ -24,17 +24,83 @@
# * new tests are typically be added on top, after the syntax docs
# * use ascii character only
+# nested conditions are converted to union
+
+xpath2sql /jcr:root/test//element(*, nt:unstructured)[
+ (
+ jcr:contains(., 'cinema') or @tags = 1
+ )
+ and (
+ ( not(@types)
+ or (
+ not(@types = 'a')
+ and not(@types = 'b')
+ and not(@types = 'c')
+ )
+ )
+ )]
+select [jcr:path], [jcr:score], *
+ from [nt:unstructured] as a
+ where isdescendantnode(a, '/test')
+ and contains(*, 'cinema')
+ and [types] is null
+ union select [jcr:path], [jcr:score], *
+ from [nt:unstructured] as a
+ where isdescendantnode(a, '/test')
+ and contains(*, 'cinema')
+ and not([types] = 'a')
+ and not([types] = 'b')
+ and not([types] = 'c')
+ union select [jcr:path], [jcr:score], *
+ from [nt:unstructured] as a
+ where isdescendantnode(a, '/test')
+ and [tags] = 1
+ and [types] is null
+ union select [jcr:path], [jcr:score], *
+ from [nt:unstructured] as a
+ where isdescendantnode(a, '/test')
+ and [tags] = 1
+ and not([types] = 'a')
+ and not([types] = 'b')
+ and not([types] = 'c')
+ /* xpath ... */
+
+xpath2sql /jcr:root//*[(@a=1 or @b=1) and (@c=2 or (@c=3 and @c=4))]
+select [jcr:path], [jcr:score], *
+ from [nt:base] as a
+ where isdescendantnode(a, '/')
+ and [a] = 1
+ and [c] = 2
+ union select [jcr:path], [jcr:score], *
+ from [nt:base] as a
+ where isdescendantnode(a, '/')
+ and [a] = 1
+ and [c] = 3
+ and [c] = 4
+ union select [jcr:path], [jcr:score], *
+ from [nt:base] as a
+ where isdescendantnode(a, '/')
+ and [b] = 1
+ and [c] = 2
+ union select [jcr:path], [jcr:score], *
+ from [nt:base] as a
+ where isdescendantnode(a, '/')
+ and [b] = 1
+ and [c] = 3
+ and [c] = 4
+ /* xpath ... */
+
# multiple primary types
xpath2sql /jcr:root/content//*[jcr:contains(., 'abc') and (((@jcr:primaryType
= 'page')) or ((@jcr:primaryType = 'asset'))) ]
select [jcr:path], [jcr:score], *
from [page] as a
- where isdescendantnode(a, '/content')
- and contains(*, 'abc')
+ where contains(*, 'abc')
+ and isdescendantnode(a, '/content')
and [jcr:primaryType] = 'page'
union select [jcr:path], [jcr:score], *
from [asset] as a
- where isdescendantnode(a, '/content')
- and contains(*, 'abc')
+ where contains(*, 'abc')
+ and isdescendantnode(a, '/content')
and [jcr:primaryType] = 'asset'
/* xpath ... */
@@ -87,26 +153,26 @@ select [jcr:path], [jcr:score], *
xpath2sql /jcr:root/content//*[((@i = '1' or @i = '2') or (@s = 'x')) and (@t
= 'a' or @t = 'b')]
select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] in('a', 'b')
+ where [t] in('a', 'b')
+ and isdescendantnode(a, '/content')
and [i] in('1', '2')
union select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] in('a', 'b')
+ where [t] in('a', 'b')
+ and isdescendantnode(a, '/content')
and [s] = 'x'
/* xpath ... */
xpath2sql /jcr:root/content//*[((@i = '1' or @i = '2') or (@s = 'x')) and (@t
= 'a')]
select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] = 'a'
+ where [t] = 'a'
+ and isdescendantnode(a, '/content')
and [i] in('1', '2')
union select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] = 'a'
+ where [t] = 'a'
+ and isdescendantnode(a, '/content')
and [s] = 'x'
/* xpath ... */
@@ -125,13 +191,13 @@ select [jcr:path], [jcr:score], *
xpath2sql /jcr:root/content//*[((@i = '1' or @i = '2') or (@s = 'x')) and (@t
= 'a' or @t = 'b')] order by @a
select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] in('a', 'b')
+ where [t] in('a', 'b')
+ and isdescendantnode(a, '/content')
and [i] in('1', '2')
union select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] in('a', 'b')
+ where [t] in('a', 'b')
+ and isdescendantnode(a, '/content')
and [s] = 'x'
order by [a]
/* xpath ... */
@@ -139,13 +205,13 @@ select [jcr:path], [jcr:score], *
xpath2sql /jcr:root/content//*[((@i = '1' or @i = '2') or (@s = 'x')) and (@t
= 'a')] order by @a
select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] = 'a'
+ where [t] = 'a'
+ and isdescendantnode(a, '/content')
and [i] in('1', '2')
union select [jcr:path], [jcr:score], *
from [nt:base] as a
- where isdescendantnode(a, '/content')
- and [t] = 'a'
+ where [t] = 'a'
+ and isdescendantnode(a, '/content')
and [s] = 'x'
order by [a]
/* xpath ... */
@@ -707,29 +773,29 @@ select b.[jcr:path] as [jcr:path], b.[jc
from [nt:base] as a
inner join [nt:base] as b
on ischildnode(b, a)
- where a.[a] = 1
- and name(b) = 'sub'
+ where name(b) = 'sub'
+ and a.[a] = 1
and b.[c] = 1
union 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(b, a)
- where a.[a] = 1
- and name(b) = 'sub'
+ where name(b) = 'sub'
+ and a.[a] = 1
and b.[d] = 1
union 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(b, a)
- where a.[b] = 1
- and name(b) = 'sub'
+ where name(b) = 'sub'
+ and a.[b] = 1
and b.[c] = 1
union 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(b, a)
- where a.[b] = 1
- and name(b) = 'sub'
+ where name(b) = 'sub'
+ and a.[b] = 1
and b.[d] = 1
/* xpath ... */
@@ -1111,52 +1177,52 @@ xpath2sql /jcr:root/content/campaigns//e
order by @onTime
select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
- and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
- and isdescendantnode(a, '/content/campaigns')
+ where isdescendantnode(a, '/content/campaigns')
and [sling:resourceType] in('teaser', 'newsletter')
- union select [jcr:path], [jcr:score], *
- from [PageContent] as a
- where [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
+ and [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
- and isdescendantnode(a, '/content/campaigns')
- and [teaserPageType] in('newsletter', 'tweet')
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] is null
- and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
- and isdescendantnode(a, '/content/campaigns')
+ where isdescendantnode(a, '/content/campaigns')
and [sling:resourceType] in('teaser', 'newsletter')
+ and [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
+ and [offTime] is null
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] is null
+ where isdescendantnode(a, '/content/campaigns')
+ and [sling:resourceType] in('teaser', 'newsletter')
+ and [onTime] is null
and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
- and isdescendantnode(a, '/content/campaigns')
- and [teaserPageType] in('newsletter', 'tweet')
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
- and [offTime] is null
- and isdescendantnode(a, '/content/campaigns')
+ where isdescendantnode(a, '/content/campaigns')
and [sling:resourceType] in('teaser', 'newsletter')
+ and [onTime] is null
+ and [offTime] is null
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
- and [offTime] is null
- and isdescendantnode(a, '/content/campaigns')
+ where isdescendantnode(a, '/content/campaigns')
and [teaserPageType] in('newsletter', 'tweet')
+ and [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
+ and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] is null
+ where isdescendantnode(a, '/content/campaigns')
+ and [teaserPageType] in('newsletter', 'tweet')
+ and [onTime] < cast('2012-04-01T00:00:00.000+02:00' as date)
and [offTime] is null
- and isdescendantnode(a, '/content/campaigns')
- and [sling:resourceType] in('teaser', 'newsletter')
union select [jcr:path], [jcr:score], *
from [PageContent] as a
- where [onTime] is null
- and [offTime] is null
- and isdescendantnode(a, '/content/campaigns')
+ where isdescendantnode(a, '/content/campaigns')
and [teaserPageType] in('newsletter', 'tweet')
+ and [onTime] is null
+ and [offTime] >= cast('2012-02-26T00:00:00.000+01:00' as date)
+ union select [jcr:path], [jcr:score], *
+ from [PageContent] as a
+ where isdescendantnode(a, '/content/campaigns')
+ and [teaserPageType] in('newsletter', 'tweet')
+ and [onTime] is null
+ and [offTime] is null
order by [onTime]
/* xpath ... */