Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (revision 1586378) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (working copy) @@ -533,12 +533,16 @@ readOakProperties(list, t, oakPropertyName, propertyType); if (list.size() == 0) { return null; + } else if (list.size() == 1) { + return list.get(0); } + // TODO under which conditions do we need to provide a properly + // typed version of this list? (not just a multi-valued string pv) ArrayList strings = new ArrayList(); for (PropertyValue p : list) { Iterables.addAll(strings, p.getValue(Type.STRINGS)); } - return PropertyValues.newString(strings); + return PropertyValues.newString(strings); } boolean relative = oakPropertyName.indexOf('/') >= 0; Tree t = currentTree(); @@ -590,6 +594,7 @@ } private void readOakProperties(ArrayList target, Tree t, String oakPropertyName, Integer propertyType) { + boolean skipCurrentNode = false; while (true) { if (t == null || !t.exists()) { return; @@ -608,10 +613,14 @@ 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 +628,12 @@ } 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 Index: oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java (revision 1586378) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingIndexQueryTest.java (working copy) @@ -13,6 +13,8 @@ */ package org.apache.jackrabbit.oak.query.index; +import java.util.ArrayList; + import org.apache.jackrabbit.oak.Oak; import org.apache.jackrabbit.oak.api.ContentRepository; import org.apache.jackrabbit.oak.api.Tree; @@ -204,4 +206,31 @@ .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()); + assertQuery("//*[(@prop > 1000)]", "xpath", new ArrayList()); + + 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()); + assertQuery("//*[(*/@prop > 1000)]", "xpath", new ArrayList()); + } } Index: oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt =================================================================== --- oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt (revision 1586378) +++ oak-core/src/test/resources/org/apache/jackrabbit/oak/query/sql2_measure.txt (working copy) @@ -42,7 +42,7 @@ 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')