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 2015/08/19 15:38:29 UTC

svn commit: r1696587 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/ oak-core/src/test/java/org/apache/jackrabbit/oak/query/ oak-lucene/src/main/java/or...

Author: thomasm
Date: Wed Aug 19 13:38:29 2015
New Revision: 1696587

URL: http://svn.apache.org/r1696587
Log:
OAK-2634 QueryEngine should expose name query as property restriction

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeLocalNameImpl.java Wed Aug 19 13:38:29 2015
@@ -28,6 +28,7 @@ import org.apache.jackrabbit.oak.api.Pro
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
 
 /**
  * The function "localname(..)".
@@ -68,24 +69,42 @@ public class NodeLocalNameImpl extends D
     @Override
     public PropertyValue currentProperty() {
         String name = PathUtils.getName(selector.currentPath());
-        int colon = name.indexOf(':');
-        // TODO LOCALNAME: evaluation of local name might not be correct
-        String localName = colon < 0 ? name : name.substring(colon + 1);
+        String localName = getLocalName(name);
         // TODO reverse namespace remapping?
         return PropertyValues.newString(localName);
     }
+    
+    static String getLocalName(String name) {
+        int colon = name.indexOf(':');
+        // TODO LOCALNAME: evaluation of local name might not be correct
+        return colon < 0 ? name : name.substring(colon + 1);
+    }
 
     @Override
     public void restrict(FilterImpl f, Operator operator, PropertyValue v) {
-        // TODO support LOCALNAME index conditions
+        if (v == null) {
+            return;
+        }
+
+        String name = NodeNameImpl.getName(query, v);
+        if (name != null && f.getSelector().equals(selector)
+                && NodeNameImpl.supportedOperator(operator)) {
+            f.restrictProperty(QueryConstants.RESTRICTION_LOCAL_NAME,
+                    operator, PropertyValues.newString(name));
+        }
     }
-    
+
     @Override
     public void restrictList(FilterImpl f, List<PropertyValue> list) {
         // optimizations of type "LOCALNAME(..) IN(A, B)" are not supported
     }
 
     @Override
+    public boolean supportsRangeConditions() {
+        return false;
+    }
+
+    @Override
     public boolean canRestrictSelector(SelectorImpl s) {
         return s.equals(selector);
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NodeNameImpl.java Wed Aug 19 13:38:29 2015
@@ -28,8 +28,10 @@ import org.apache.jackrabbit.oak.api.Pro
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.namepath.JcrNameParser;
+import org.apache.jackrabbit.oak.query.QueryImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
 import org.apache.jackrabbit.util.ISO9075;
 
 /**
@@ -86,11 +88,13 @@ public class NodeNameImpl extends Dynami
         if (v == null) {
             return;
         }
-        String name = getName(v);
-        if (name == null) {
-            throw new IllegalArgumentException("Invalid name value: " + v.toString());
+        String name = getName(query, v);
+        if (name != null && f.getSelector().equals(selector)
+                && NodeNameImpl.supportedOperator(operator)) {
+            String localName = NodeLocalNameImpl.getLocalName(name);
+            f.restrictProperty(QueryConstants.RESTRICTION_LOCAL_NAME,
+                    operator, PropertyValues.newString(localName));
         }
-        // TODO support NAME(..) index conditions
     }
     
     @Override
@@ -110,7 +114,7 @@ public class NodeNameImpl extends Dynami
      * @param v the value
      * @return name value, or {@code null} if the value can not be converted
      */
-    private String getName(PropertyValue v) {
+    static String getName(QueryImpl query, PropertyValue v) {
         // TODO correctly validate JCR names - see JCR 2.0 spec 3.2.4 Naming Restrictions
         switch (v.getType().tag()) {
         case PropertyType.DATE:
@@ -133,7 +137,11 @@ public class NodeNameImpl extends Dynami
         }
         return name;
     }
-    
+
+    static boolean supportedOperator(Operator o) {
+        return o == Operator.EQUAL || o == Operator.LIKE;
+    }
+
     @Override
     int getPropertyType() {
         return PropertyType.NAME;

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java?rev=1696587&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryConstants.java Wed Aug 19 13:38:29 2015
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.query;
+
+public abstract class QueryConstants {
+
+    /**
+     * Name of the property restriction used to express query performed
+     * via NAME and LOCALNAME functions
+     */
+    public static final String RESTRICTION_LOCAL_NAME = ":localname";
+
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java Wed Aug 19 13:38:29 2015
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.1.0")
+@Version("2.2.0")
 @Export(optional = "provide:=true")
 package org.apache.jackrabbit.oak.spi.query;
 

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java Wed Aug 19 13:38:29 2015
@@ -46,6 +46,23 @@ public class FilterTest {
         QueryImpl q = (QueryImpl) p.parse(sql);
         return q.createFilter(true);
     }
+    
+    private Filter createFilterSQL(String sql) throws ParseException {
+        QueryImpl q = (QueryImpl) p.parse(sql);
+        return q.createFilter(true);
+    }
+    
+    @Test
+    public void localName() throws Exception {
+        Filter f = createFilterSQL("select * from [nt:base] where localname() = 'resource'");
+        assertEquals("[resource]", f.getPropertyRestrictions(":localname").toString());
+    }
+    
+    @Test
+    public void name() throws Exception {
+        Filter f = createFilter("//*[fn:name() = 'nt:resource']");
+        assertEquals("[resource]", f.getPropertyRestrictions(":localname").toString());
+    }
 
     @Test
     public void mvp() throws Exception {

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Wed Aug 19 13:38:29 2015
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.query.f
 import org.apache.jackrabbit.oak.query.fulltext.FullTextTerm;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor;
 import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
 import org.apache.lucene.index.IndexReader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -145,13 +146,17 @@ class IndexPlanner {
         //for property index
         if (indexingRule.propertyIndexEnabled) {
             for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
+                String name = pr.propertyName;
+                if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
+                    continue;
+                }                
                 PropertyDefinition pd = indexingRule.getConfig(pr.propertyName);
                 if (pd != null && pd.propertyIndexEnabled()) {
                     if (pr.isNullRestriction() && !pd.nullCheckEnabled){
                         continue;
                     }
-                    indexedProps.add(pr.propertyName);
-                    result.propDefns.put(pr.propertyName, pd);
+                    indexedProps.add(name);
+                    result.propDefns.put(name, pd);
                 }
             }
         }
@@ -433,12 +438,23 @@ class IndexPlanner {
     private boolean notSupportedFeature() {
         if(filter.getPathRestriction() == Filter.PathRestriction.NO_RESTRICTION
                 && filter.matchesAllTypes()
-                && filter.getPropertyRestrictions().isEmpty()){
+                && filter.getPropertyRestrictions().isEmpty()) { 
             //This mode includes name(), localname() queries
             //OrImpl [a/name] = 'Hello' or [b/name] = 'World'
             //Relative parent properties where [../foo1] is not null
             return true;
         }
+        int usablePropertRestrictionCount = 0;
+        for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
+            String name = pr.propertyName;
+            if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
+                continue;
+            }
+            usablePropertRestrictionCount++;
+        }
+        if (usablePropertRestrictionCount == 0) {
+            return true;
+        }
         return false;
     }
 

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Wed Aug 19 13:38:29 2015
@@ -69,6 +69,7 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import org.apache.jackrabbit.oak.spi.query.IndexRow;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
 import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -665,6 +666,9 @@ public class LuceneIndex implements Adva
             if (JCR_PRIMARYTYPE.equals(name)) {
                 continue;
             }
+            if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
+                continue;
+            }              
 
             if (skipTokenization(name)) {
                 qs.add(new TermQuery(new Term(name, pr.first

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1696587&r1=1696586&r2=1696587&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Wed Aug 19 13:38:29 2015
@@ -62,6 +62,7 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import org.apache.jackrabbit.oak.spi.query.IndexRow;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryConstants;
 import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -724,6 +725,9 @@ public class LucenePropertyIndex impleme
             if ("rep:excerpt".equals(name)) {
                 continue;
             }
+            if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
+                continue;
+            }
 
             if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
                     && pr.lastIncluding) {
@@ -739,7 +743,7 @@ public class LucenePropertyIndex impleme
                     continue;
                 }
             }
-
+            
             PropertyDefinition pd = planResult.getPropDefn(pr);
             if (pd == null) {
                 continue;