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 2014/04/16 14:25:57 UTC

svn commit: r1587890 - in /jackrabbit/oak/branches/1.0/oak-core/src: main/java/org/apache/jackrabbit/oak/query/ast/ test/java/org/apache/jackrabbit/oak/query/index/ test/resources/org/apache/jackrabbit/oak/query/

Author: thomasm
Date: Wed Apr 16 12:25:57 2014
New Revision: 1587890

URL: http://svn.apache.org/r1587890
Log:
OAK-1076 XPath failures for typed properties

Modified:
    jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
    jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java
    jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt

Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1587890&r1=1587889&r2=1587890&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Wed Apr 16 12:25:57 2014
@@ -42,6 +42,7 @@ import org.apache.jackrabbit.oak.api.Pro
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyBuilder;
 import org.apache.jackrabbit.oak.query.QueryImpl;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -533,12 +534,33 @@ public class SelectorImpl extends Source
             readOakProperties(list, t, oakPropertyName, propertyType);
             if (list.size() == 0) {
                 return null;
+            } else if (list.size() == 1) {
+                return list.get(0);
             }
-            ArrayList<String> strings = new ArrayList<String>();
-            for (PropertyValue p : list) {
-                Iterables.addAll(strings, p.getValue(Type.STRINGS));
+            Type<?> type = list.get(0).getType();
+            for (int i = 1; i < list.size(); i++) {
+                Type<?> t2 = list.get(i).getType();
+                if (t2 != type) {
+                    // types don't match
+                    type = Type.STRING;
+                    break;
+                }
+            }
+            if (type == Type.STRING) {
+                ArrayList<String> strings = new ArrayList<String>();
+                for (PropertyValue p : list) {
+                    Iterables.addAll(strings, p.getValue(Type.STRINGS));
+                }
+                return PropertyValues.newString(strings);
+            }
+            @SuppressWarnings("unchecked")
+            PropertyBuilder<Object> builder = (PropertyBuilder<Object>) PropertyBuilder.array(type);
+            builder.setName("");
+            for (PropertyValue v : list) {
+                builder.addValue(v.getValue(type));
             }
-            return PropertyValues.newString(strings);                    
+            PropertyState s = builder.getPropertyState();
+            return PropertyValues.create(s);
         }
         boolean relative = oakPropertyName.indexOf('/') >= 0;
         Tree t = currentTree();
@@ -590,6 +612,7 @@ public class SelectorImpl extends Source
     }
     
     private void readOakProperties(ArrayList<PropertyValue> target, Tree t, String oakPropertyName, Integer propertyType) {
+        boolean skipCurrentNode = false;
         while (true) {
             if (t == null || !t.exists()) {
                 return;
@@ -608,10 +631,14 @@ public class SelectorImpl extends Source
                 for (Tree child : t.getChildren()) {
                     readOakProperties(target, child, oakPropertyName, propertyType);
                 }
+                skipCurrentNode = true;
             } else {
                 t = t.getChild(parent);
             }
         }
+        if (skipCurrentNode) {
+            return;
+        }
         if (!"*".equals(oakPropertyName)) {
             PropertyValue value = currentOakProperty(t, oakPropertyName, propertyType);
             if (value != null) {
@@ -619,12 +646,12 @@ public class SelectorImpl extends Source
             }
             return;
         }
-          for (PropertyState p : t.getProperties()) {
-              if (propertyType == null || p.getType().tag() == propertyType) {
-                  PropertyValue v = PropertyValues.create(p);
-                  target.add(v);
-              }
-          }
+        for (PropertyState p : t.getProperties()) {
+            if (propertyType == null || p.getType().tag() == propertyType) {
+                PropertyValue v = PropertyValues.create(p);
+                target.add(v);
+            }
+        }
     }
 
     @Override

Modified: jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java?rev=1587890&r1=1587889&r2=1587890&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java Wed Apr 16 12:25:57 2014
@@ -13,6 +13,9 @@
  */
 package org.apache.jackrabbit.oak.query.index;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -204,4 +207,82 @@ public class TraversingIndexQueryTest ex
                         .of("/home/users/testing/socialgraph_test_user_4/social/relationships/friend/socialgraph_test_group"));
 
     }
+
+    @Test
+    public void testRelativeProperties() throws Exception {
+        root.getTree("/").addChild("content").addChild("node1")
+                .setProperty("prop", 128);
+        root.commit();
+
+        assertQuery("//*[(@prop > 1)]", "xpath",
+                ImmutableList.of("/content/node1"));
+        assertQuery("//*[(@prop > 2)]", "xpath",
+                ImmutableList.of("/content/node1"));
+        assertQuery("//*[(@prop > 20)]", "xpath",
+                ImmutableList.of("/content/node1"));
+        assertQuery("//*[(@prop > 100)]", "xpath",
+                ImmutableList.of("/content/node1"));
+        assertQuery("//*[(@prop > 200)]", "xpath", new ArrayList<String>());
+        assertQuery("//*[(@prop > 1000)]", "xpath", new ArrayList<String>());
+
+        assertQuery("//*[(*/@prop > 1)]", "xpath", ImmutableList.of("/content"));
+        assertQuery("//*[(*/@prop > 2)]", "xpath", ImmutableList.of("/content"));
+        assertQuery("//*[(*/@prop > 20)]", "xpath",
+                ImmutableList.of("/content"));
+        assertQuery("//*[(*/@prop > 100)]", "xpath",
+                ImmutableList.of("/content"));
+        assertQuery("//*[(*/@prop > 200)]", "xpath", new ArrayList<String>());
+        assertQuery("//*[(*/@prop > 1000)]", "xpath", new ArrayList<String>());
+    }
+    
+    @Test
+    public void testMultipleRelativeProperties() throws Exception {
+        Tree content = root.getTree("/").addChild("content");
+        
+        content.addChild("node1").setProperty("a", 128);
+        content.addChild("node2").setProperty("a", "abc");
+        content.addChild("node3").setProperty("a", "1280");
+        
+        content.addChild("node1").setProperty("b", 128);
+        content.addChild("node2").setProperty("b", 1024);
+        content.addChild("node3").setProperty("b", 2048);
+
+        content.addChild("node1").setProperty("c", 10.3);
+        content.addChild("node2").setProperty("c", -10.3);
+        content.addChild("node3").setProperty("c", 9.8);
+
+        content.addChild("node1").setProperty("d", Arrays.asList("x", "y"), Type.STRINGS);
+        content.addChild("node2").setProperty("d", 10);
+        content.addChild("node3").setProperty("d", Arrays.asList(1L, 2L), Type.LONGS);
+
+
+        root.commit();
+
+        assertQuery("//*[*/@a > 2]", "xpath", Arrays.<String>asList());
+        assertQuery("//*[*/@a > '1']", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@a > 'abb']", "xpath", Arrays.<String>asList());
+        assertQuery("//*[*/@a = 'abc']", "xpath", Arrays.asList("/content"));
+        // this may be unexpected: it is evalucated as
+        // ['128', 'abc', '1280'] >= 'abc'
+        assertQuery("//*[*/@a >= 'abc']", "xpath", Arrays.<String>asList());
+
+        assertQuery("//*[*/@b > 2]", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@b > 2048]", "xpath", Arrays.<String>asList());
+        assertQuery("//*[*/@b > '1']", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@b = 128]", "xpath", Arrays.asList("/content"));
+
+        assertQuery("//*[*/@c > 10]", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@c > 11]", "xpath", Arrays.<String>asList());
+        assertQuery("//*[*/@c > '1']", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@c = 9.8]", "xpath", Arrays.asList("/content"));
+
+        assertQuery("//*[*/@d > 10]", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@d > 11]", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@d > '1']", "xpath", Arrays.asList("/content"));
+        assertQuery("//*[*/@d = 10]", "xpath", Arrays.asList("/content"));
+        // this may be unexpected: it is evalucated as
+        // ['x', 'y', '10', '1', '2'] < '3'     
+        assertQuery("//*[*/@d < 3]", "xpath", Arrays.<String>asList());
+}
+    
 }

Modified: jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt?rev=1587890&r1=1587889&r2=1587890&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt Wed Apr 16 12:25:57 2014
@@ -42,7 +42,7 @@ select [jcr:path] from [nt:base] as p
 
 select [jcr:path], p.[children/c1/*] from [nt:base] as p
   where p.[children/c1/*] is not null
-/testRoot, [1]
+/testRoot, 1
 
 select [jcr:path], [jcr:score], * from [nt:base] as a
   where ([id] = '0' or [p0/id] = '0')