Author: thomasm
Date: Thu Feb 19 14:17:05 2015
New Revision: 1660893

URL: http://svn.apache.org/r1660893
Log:
OAK-2530 Support IS NULL based property restrictions in the query engine

Modified:
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
    
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
    
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
    
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
    
jackrabbit/oak/branches/1.0/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
 Thu Feb 19 14:17:05 2015
@@ -130,7 +130,7 @@ public class OrderedPropertyIndex extend
                 if (lookup.isIndexed(propertyName, "/", filter)) {
                     PropertyValue value = null;
                     boolean createPlan = false;
-                    if (pr.first == null && pr.last == null) {
+                    if (pr.isNotNullRestriction()) {
                         // open query: [property] is not null
                         value = null;
                         createPlan = true;
@@ -189,7 +189,7 @@ public class OrderedPropertyIndex extend
             String operation = null;
             PropertyValue value = null;       
             // TODO support pr.list
-            if (pr.first == null && pr.last == null) {
+            if (pr.isNotNullRestriction()) {
                 // open query: [property] is not null
                 operation = "is not null";
             } else if (pr.first != null && pr.first.equals(pr.last) && 
pr.firstIncluding

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
 Thu Feb 19 14:17:05 2015
@@ -125,7 +125,9 @@ class PropertyIndex implements QueryInde
             // TODO support indexes on a path
             // currently, only indexes on the root node are supported
             if (lookup.isIndexed(propertyName, "/", filter)) {
-                if (pr.firstIncluding && pr.lastIncluding
+                if (pr.isNullRestriction()) {
+                    // covering indexes are not currently supported
+                } else if (pr.firstIncluding && pr.lastIncluding
                     && pr.first != null && pr.first.equals(pr.last)) {
                     // "[property] = $value"
                     propertyCost = lookup.getCost(filter, propertyName, 
pr.first);
@@ -136,6 +138,7 @@ class PropertyIndex implements QueryInde
                     }
                 } else {
                     // processed as "[property] is not null"
+                    // even if it is a range query
                     propertyCost = lookup.getCost(filter, propertyName, null);
                 }
             }
@@ -198,9 +201,11 @@ class PropertyIndex implements QueryInde
             // TODO support indexes on a path
             // currently, only indexes on the root node are supported
             if (lookup.isIndexed(propertyName, "/", filter)) {
-                // equality
-                if (pr.firstIncluding && pr.lastIncluding
+                if (pr.isNullRestriction()) {
+                    // covering indexes are not currently supported
+                } else if (pr.firstIncluding && pr.lastIncluding
                     && pr.first != null && pr.first.equals(pr.last)) {
+                    // equality
                     // "[property] = $value"
                     paths = lookup.query(filter, propertyName, pr.first);
                 } else if (pr.list != null) {
@@ -214,6 +219,7 @@ class PropertyIndex implements QueryInde
                     }
                 } else {
                     // processed as "[property] is not null"
+                    // even if it is a range query
                     paths = lookup.query(filter, propertyName, null);
                 }
             }
@@ -241,22 +247,24 @@ class PropertyIndex implements QueryInde
             // TODO support indexes on a path
             // currently, only indexes on the root node are supported
             if (lookup.isIndexed(propertyName, "/", filter)) {
-                if (pr.firstIncluding && pr.lastIncluding
+                if (pr.isNullRestriction()) {
+                    // covering indexes are not currently supported
+                } else if (pr.firstIncluding && pr.lastIncluding
                     && pr.first != null && pr.first.equals(pr.last)) {
                     buff.append(' 
').append(propertyName).append('=').append(pr.first);
+                } else if (pr.list != null) {
+                    buff.append(' ').append(propertyName).append(" IN(");
+                    int i = 0;
+                    for (PropertyValue pv : pr.list) {
+                        if (i++ > 0) {
+                            buff.append(", ");
+                        }
+                        buff.append(pv);
+                    }
+                    buff.append(')');
                 } else {
                     buff.append(' ').append(propertyName);
                 }
-            } else if (pr.list != null) {
-                buff.append(' ').append(propertyName).append(" IN(");
-                int i = 0;
-                for (PropertyValue pv : pr.list) {
-                    if (i++ > 0) {
-                        buff.append(", ");
-                    }
-                    buff.append(pv);
-                }
-                buff.append(')');
             } else {
                 notIndexed.append(' ').append(propertyName);
                 if (!pr.toString().isEmpty()) {

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java
 Thu Feb 19 14:17:05 2015
@@ -501,7 +501,7 @@ public class OrderedContentMirrorStoreSt
                     v.visit(n);
                     count = v.getEstimatedCount();
                 }
-            } else if (lpr.first == null && lpr.last == null) {
+            } else if (lpr.isNotNullRestriction()) {
                 // property not null case
                 PropertyState ec = 
indexMeta.getProperty(ENTRY_COUNT_PROPERTY_NAME);
                 if (ec != null) {

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
 Thu Feb 19 14:17:05 2015
@@ -106,9 +106,14 @@ public class EquiJoinConditionImpl exten
                     p2 = null;
                 }
             }
-            // always set the condition, even if unkown ( -> is not null)
             String p1n = normalizePropertyName(property1Name);
-            f.restrictProperty(p1n, Operator.EQUAL, p2);
+            if (p2 == null) {
+                // always set the condition, 
+                // even if unknown (in which case it is converted to "is not 
null")
+                f.restrictProperty(p1n, Operator.NOT_EQUAL, null);
+            } else {
+                f.restrictProperty(p1n, Operator.EQUAL, p2);
+            }
         }
         if (f.getSelector().equals(selector2)) {
             PropertyValue p1 = selector1.currentProperty(property1Name);

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyInexistenceImpl.java
 Thu Feb 19 14:17:05 2015
@@ -108,8 +108,6 @@ public class PropertyInexistenceImpl ext
 
     @Override
     public void restrict(FilterImpl f) {
-        // we don't support covering indexes, 
-        // so there is no optimization anyway, and
         // we need to be careful with "property IS NULL"
         // because this might cause an index
         // to ignore the join condition "property = x"
@@ -119,6 +117,13 @@ public class PropertyInexistenceImpl ext
         // must not result in the index to check for
         // "b.y is null", because that would alter the
         // result
+        if (selector.isOuterJoinRightHandSide()) {
+            return;
+        }
+        if (f.getSelector().equals(selector)) {
+            String pn = normalizePropertyName(propertyName);
+            f.restrictProperty(pn, Operator.EQUAL, null);
+        }        
     }
 
     @Override

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
 Thu Feb 19 14:17:05 2015
@@ -210,6 +210,14 @@ public interface Filter {
          * If not restricted, this field is set to PropertyType.UNDEFINED.
          */
         public int propertyType = PropertyType.UNDEFINED;
+        
+        public boolean isNullRestriction() {
+            return first == null && last == null && lastIncluding && 
firstIncluding;
+        }
+        
+        public boolean isNotNullRestriction() {
+            return first == null && last == null && !lastIncluding && 
!firstIncluding;
+        }
 
         @Override
         public String toString() {
@@ -233,6 +241,11 @@ public interface Filter {
         }
         
         private String toStringFromTo() {
+            if (isNullRestriction()) {
+                return "is null";
+            } else if (isNotNullRestriction()) {
+                return "is not null";
+            }
             String f = first == null ? "" : first.toString();
             String l = last == null ? "" : last.toString();
             if (f.equals(l)) {

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
 Thu Feb 19 14:17:05 2015
@@ -21,6 +21,7 @@ import static junit.framework.Assert.ass
 import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
+import static org.junit.Assert.assertEquals;
 
 import java.text.ParseException;
 
@@ -52,5 +53,19 @@ public class FilterTest {
         Filter f = createFilter("//*[(@prop = 'aaa' and @prop = 'bbb' and 
@prop = 'ccc')]");
         assertFalse(f.isAlwaysFalse());
     }
+    
+    @Test
+    public void isNull() throws Exception {
+        // this can refer to a multi-valued property
+        Filter f = createFilter("//*[not(@c)]");
+        assertEquals("[is null]", f.getPropertyRestrictions("c").toString());
+    }
+     
+    @Test
+    public void isNotNull() throws Exception {
+        // this can refer to a multi-valued property
+        Filter f = createFilter("//*[@c]");
+        assertEquals("[is not null]", 
f.getPropertyRestrictions("c").toString());
+    }
 
 }

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/FilterTest.java
 Thu Feb 19 14:17:05 2015
@@ -123,18 +123,18 @@ public class FilterTest {
         f = new FilterImpl();
         f.restrictProperty("x", Operator.NOT_EQUAL, null);
         assertEquals(
-                "Filter(, path=*, property=[x=[]])", 
+                "Filter(, path=*, property=[x=[is not null]])", 
                 f.toString());
         f.restrictProperty("x", Operator.LESS_THAN, one);
         assertEquals(
-                "Filter(, path=*, property=[x=[, ..1)]])", 
+                "Filter(, path=*, property=[x=[is not null, ..1)]])", 
                 f.toString());
         
         // this should replace the range with an equality
         // (which is faster, and correct even when using multi-valued 
properties)
         f.restrictProperty("x", Operator.EQUAL, two);
         assertEquals(
-                "Filter(, path=*, property=[x=[, ..1), 2]])", 
+                "Filter(, path=*, property=[x=[is not null, ..1), 2]])", 
                 f.toString());
 
     }

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_index.txt
 Thu Feb 19 14:17:05 2015
@@ -24,6 +24,21 @@
 # * new tests are typically be added on top, after the syntax docs
 # * use ascii character only
 
+explain select * from [nt:base] as a
+    left outer join [nt:base] as b on a.x=b.y
+    where a.y is null and b.z = 1
+[nt:base] as [a] /* traverse "*"
+  where [a].[y] is null */ left outer join [nt:base] as [b] /* traverse "*"
+  where [b].[z] = cast('1' as long) */
+  on [a].[x] = [b].[y]
+
+explain select * from [nt:base] as a
+    right outer join [nt:base] as b on a.x=b.y
+    where a.y is null and b.z = 1
+[nt:base] as [b] /* traverse "*"
+  where [b].[z] = cast('1' as long) */ left outer join [nt:base] as [a] /* 
traverse "*" */
+  on [a].[x] = [b].[y]
+
 explain select * from [nt:base] where (p=1 or p=2) and (p=3 or p=4)
 [nt:base] as [nt:base] /* traverse "*"
   where ((([nt:base].[p] is not null)
@@ -43,7 +58,7 @@ explain select e.[jcr:path]
   and name(c) = 'd'
   and name(d) = 'e'
   and (e.[jcr:uuid] = '1' or e.[jcr:uuid] = '2' or e.[jcr:uuid] = '3' or 
e.[jcr:uuid] = '4')
-[nt:base] as [e] /* property jcr:uuid
+[nt:base] as [e] /* property jcr:uuid IN(1, 2, 3, 4)
   where ([e].[jcr:uuid] is not null)
   and ([e].[jcr:uuid] in(cast('1' as string), cast('2' as string), cast('3' as 
string), cast('4' as string))) */
   inner join [nt:base] as [d] /* traverse "* && //parent/of/join"
@@ -72,7 +87,7 @@ explain select e.[jcr:path]
   and name(c) = 'd'
   and name(d) = 'e'
   and (e.[jcr:uuid] = '1' or e.[jcr:uuid] = '2' or e.[jcr:uuid] = '3' or 
e.[jcr:uuid] = '4')
-[nt:base] as [e] /* property jcr:uuid
+[nt:base] as [e] /* property jcr:uuid IN(1, 2, 3, 4)
   where ([e].[jcr:uuid] is not null)
   and ([e].[jcr:uuid] in(cast('1' as string), cast('2' as string), cast('3' as 
string), cast('4' as string))) */
   inner join [nt:base] as [d] /* traverse "* && //parent/of/join"
@@ -118,7 +133,7 @@ explain select b.[jcr:uuid]
   from [nt:base] as a
   inner join [nt:base] as b on isdescendantnode(b, a)
   where (a.[jcr:uuid] = '1' or a.[jcr:uuid] = '2')
-[nt:base] as [a] /* property jcr:uuid
+[nt:base] as [a] /* property jcr:uuid IN(1, 2)
   where ([a].[jcr:uuid] is not null)
   and ([a].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
   inner join [nt:base] as [b] /* traverse "* && //path/from/join//*" */
@@ -129,7 +144,7 @@ explain select b.[jcr:uuid]
   inner join [nt:base] as b on isdescendantnode(b, a)
   where (a.[jcr:uuid] = '1' or a.[jcr:uuid] = '2')
   and b.[jcr:uuid] is not null
-[nt:base] as [a] /* property jcr:uuid
+[nt:base] as [a] /* property jcr:uuid IN(1, 2)
   where ([a].[jcr:uuid] is not null)
   and ([a].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
   inner join [nt:base] as [b] /* property jcr:uuid
@@ -146,20 +161,20 @@ explain select *
   from [nt:base]
   where [jcr:uuid] = '1' or ([jcr:uuid] = '2'
   and [b] = '3')
-[nt:base] as [nt:base] /* property jcr:uuid
+[nt:base] as [nt:base] /* property jcr:uuid IN(1, 2)
   where ([nt:base].[jcr:uuid] is not null)
   and ([nt:base].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
 
 explain select *
   from [nt:base]
   where [jcr:uuid] in('1', '2')
-[nt:base] as [nt:base] /* property jcr:uuid
+[nt:base] as [nt:base] /* property jcr:uuid IN(1, 2)
   where [nt:base].[jcr:uuid] in(cast('1' as string), cast('2' as string)) */
 
 explain select *
   from [nt:base]
   where [jcr:uuid] = '1' or [jcr:uuid] = '2'
-[nt:base] as [nt:base] /* property jcr:uuid
+[nt:base] as [nt:base] /* property jcr:uuid IN(1, 2)
   where ([nt:base].[jcr:uuid] is not null)
   and ([nt:base].[jcr:uuid] in(cast('1' as string), cast('2' as string))) */
 
@@ -191,10 +206,10 @@ explain select *
   inner join [nt:base] as b on isdescendantnode(b, a)
   where (a.[jcr:uuid]=1 or a.[jcr:uuid]=2)
   and (b.[jcr:uuid]=3 or b.[jcr:uuid]=4)
-[nt:base] as [a] /* property jcr:uuid
+[nt:base] as [a] /* property jcr:uuid IN(1, 2)
   where ([a].[jcr:uuid] is not null)
   and ([a].[jcr:uuid] in(cast('1' as long), cast('2' as long))) */
-  inner join [nt:base] as [b] /* property jcr:uuid
+  inner join [nt:base] as [b] /* property jcr:uuid IN(3, 4)
   where ([b].[jcr:uuid] is not null)
   and ([b].[jcr:uuid] in(cast('3' as long), cast('4' as long))) */
   on isdescendantnode([b], [a])

Modified: 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
 Thu Feb 19 14:17:05 2015
@@ -139,6 +139,10 @@ class IndexPlanner {
         //for property index
         if (indexingRule.propertyIndexEnabled) {
             for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
+                if (pr.isNullRestriction()) {
+                    // ignore for planning
+                    continue;
+                }
                 PropertyDefinition pd = 
indexingRule.getConfig(pr.propertyName);
                 if (pd != null && pd.propertyIndexEnabled()) {
                     indexedProps.add(pr.propertyName);

Modified: 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
 Thu Feb 19 14:17:05 2015
@@ -532,7 +532,7 @@ public class LuceneIndex implements Adva
         IndexingRule rule = 
indexDefinition.getApplicableIndexingRule(JcrConstants.NT_BASE);
         for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
 
-            if (pr.first == null && pr.last == null) {
+            if (pr.isNullRestriction() || pr.isNotNullRestriction()) {
                 // ignore property existence checks, Lucene can't to 'property
                 // is not null' queries (OAK-1208)
                 continue;

Modified: 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
 Thu Feb 19 14:17:05 2015
@@ -676,7 +676,7 @@ public class LucenePropertyIndex impleme
                         in.add(NumericRangeQuery.newLongRange(pr.propertyName, 
dateVal, dateVal, true, true), BooleanClause.Occur.SHOULD);
                     }
                     return in;
-                } else if (pr.first == null && pr.last == null ) {
+                } else if (pr.isNotNullRestriction()) {
                     // not null. For date lower bound of zero can be used
                     return NumericRangeQuery.newLongRange(pr.propertyName, 0L, 
Long.MAX_VALUE, true, true);
                 }

Modified: 
jackrabbit/oak/branches/1.0/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1660893&r1=1660892&r2=1660893&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
 Thu Feb 19 14:17:05 2015
@@ -163,6 +163,10 @@ public class SolrQueryIndex implements F
         Collection<Filter.PropertyRestriction> propertyRestrictions = 
filter.getPropertyRestrictions();
         if (propertyRestrictions != null && !propertyRestrictions.isEmpty()) {
             for (Filter.PropertyRestriction pr : propertyRestrictions) {
+                if (pr.isNullRestriction()) {
+                    // can not use full "x is null"
+                    continue;
+                }
                 // native query support
                 if (NATIVE_SOLR_QUERY.equals(pr.propertyName) || 
NATIVE_LUCENE_QUERY.equals(pr.propertyName)) {
                     String nativeQueryString = 
String.valueOf(pr.first.getValue(pr.first.getType()));


Reply via email to