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 2012/07/06 14:49:12 UTC

svn commit: r1358170 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/mk/index/ main/java/org/apache/jackrabbit/oak/query/ main/java/org/apache/jackrabbit/oak/query/ast/ main/java/org/apache/jackrabbit/oak/query/index/ main/java...

Author: thomasm
Date: Fri Jul  6 12:49:10 2012
New Revision: 1358170

URL: http://svn.apache.org/viewvc?rev=1358170&view=rev
Log:
OAK-155 Query: limited support for the deprecated JCR 1.0 query language Query.SQL

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ColumnImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinType.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LiteralImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
    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/query/ast/NotImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Order.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrderingImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FullTextTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/LikePatternTest.java
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
    jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java Fri Jul  6 12:49:10 2012
@@ -507,6 +507,12 @@ public class Indexer implements QueryInd
 
     private void addOrRemoveIndex(String path, boolean remove, boolean add) {
         // check the depth first for speed
+
+        // TODO allow creating multiple indexes in one step
+        // (buffer indexes to be created; traverse the repository only once)
+        // TODO re-organize the index structure
+        // TODO allow filters (only index a certain path; exclude a list of paths)
+
         if (PathUtils.getDepth(path) == indexRootNodeDepth + 1) {
             // actually not required, just to make sure
             if (PathUtils.getParentPath(path).equals(indexRootNode)) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Fri Jul  6 12:49:10 2012
@@ -23,6 +23,7 @@ import org.apache.jackrabbit.mk.api.Micr
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.query.ast.AstVisitorBase;
@@ -434,7 +435,8 @@ public class Query {
         CoreValue[] values = new CoreValue[columnCount];
         for (int i = 0; i < columnCount; i++) {
             ColumnImpl c = columns[i];
-            values[i] = c.currentValue();
+            PropertyState p = c.currentProperty();
+            values[i] = p == null ? null : p.getValue();
         }
         CoreValue[] orderValues;
         if (orderings == null) {
@@ -443,7 +445,10 @@ public class Query {
             int size = orderings.length;
             orderValues = new CoreValue[size];
             for (int i = 0; i < size; i++) {
-                orderValues[i] = orderings[i].getOperand().currentValue();
+                PropertyState p = orderings[i].getOperand().currentProperty();
+                // TODO how is order by multi-values properties defined?
+                // currently throws an exception
+                orderValues[i] = p == null ? null : p.getValue();
             }
         }
         return new ResultRowImpl(this, paths, values, orderValues);
@@ -511,4 +516,32 @@ public class Query {
         return session.getCurrentRoot().getTree(path);
     }
 
+    @Override
+    public String toString() {
+        StringBuilder buff = new StringBuilder();
+        buff.append("select ");
+        int i = 0;
+        for (ColumnImpl c : columns) {
+            if (i++ > 0) {
+                buff.append(", ");
+            }
+            buff.append(c);
+        }
+        buff.append(" from ").append(source);
+        if (constraint != null) {
+            buff.append(constraint);
+        }
+        if (orderings != null) {
+            buff.append(" order by ");
+            i = 0;
+            for (OrderingImpl o : orderings) {
+                if (i++ > 0) {
+                    buff.append(", ");
+                }
+                buff.append(o);
+            }
+        }
+        return buff.toString();
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java Fri Jul  6 12:49:10 2012
@@ -36,24 +36,23 @@ import org.apache.jackrabbit.oak.spi.sta
 public class QueryEngineImpl implements QueryEngine {
 
     static final String SQL2 = "JCR-SQL2";
-    private static final String XPATH = "xpath";
-    private static final String JQOM = "JCR-JQOM";
+    static final String SQL = "sql";
+    static final String XPATH = "xpath";
+    static final String JQOM = "JCR-JQOM";
 
     private final MicroKernel mk;
     private final CoreValueFactory vf;
-    private final SQL2Parser parserSQL2;
     private final QueryIndexProvider indexProvider;
 
     public QueryEngineImpl(NodeStore store, MicroKernel mk, QueryIndexProvider indexProvider) {
         this.mk = mk;
         this.vf = store.getValueFactory();
         this.indexProvider = indexProvider;
-        parserSQL2 = new SQL2Parser(vf);
     }
 
     @Override
     public List<String> getSupportedQueryLanguages() {
-        return Arrays.asList(SQL2, XPATH, JQOM);
+        return Arrays.asList(SQL2, SQL, XPATH, JQOM);
     }
 
     /**
@@ -73,11 +72,17 @@ public class QueryEngineImpl implements 
     private Query parseQuery(String statement, String language) throws ParseException {
         Query q;
         if (SQL2.equals(language) || JQOM.equals(language)) {
-            q = parserSQL2.parse(statement);
+            SQL2Parser parser = new SQL2Parser(vf);
+            q = parser.parse(statement);
+        } else if (SQL.equals(language)) {
+            SQL2Parser parser = new SQL2Parser(vf);
+            parser.setSupportSQL1(true);
+            q = parser.parse(statement);
         } else if (XPATH.equals(language)) {
             XPathToSQL2Converter converter = new XPathToSQL2Converter();
             String sql2 = converter.convert(statement);
-            q = parserSQL2.parse(sql2);
+            SQL2Parser parser = new SQL2Parser(vf);
+            q = parser.parse(sql2);
         } else {
             throw new ParseException("Unsupported language: " + language, 0);
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java Fri Jul  6 12:49:10 2012
@@ -81,6 +81,8 @@ public class SQL2Parser {
     private final AstElementFactory factory = new AstElementFactory();
     private final CoreValueFactory valueFactory;
 
+    private boolean supportSQL1;
+
     /**
      * Create a new parser. A parser can be re-used, but it is not thread safe.
      *
@@ -98,6 +100,9 @@ public class SQL2Parser {
      * @throws ParseException if parsing fails
      */
     public Query parse(String query) throws ParseException {
+        // TODO possibly support union,... as available at
+        // http://docs.jboss.org/modeshape/latest/manuals/reference/html/jcr-query-and-search.html
+
         initialize(query);
         selectors = new ArrayList<SelectorImpl>();
         expected = new ArrayList<String>();
@@ -106,6 +111,10 @@ public class SQL2Parser {
         boolean explain = readIf("EXPLAIN");
         read("SELECT");
         ArrayList<ColumnOrWildcard> list = parseColumns();
+        if (supportSQL1) {
+            addColumnIfNecessary(list, "jcr:path", "jcr:path");
+            addColumnIfNecessary(list, "jcr:score", "jcr:score");
+        }
         read("FROM");
         SourceImpl source = parseSource();
         ColumnImpl[] columnArray = resolveColumns(list);
@@ -127,6 +136,25 @@ public class SQL2Parser {
         return q;
     }
 
+    private static void addColumnIfNecessary(ArrayList<ColumnOrWildcard> list,
+            String columnName, String propertyName) {
+        for (ColumnOrWildcard c : list) {
+            String col = c.columnName;
+            if (columnName.equals(col)) {
+                // it already exists
+                return;
+            }
+        }
+        ColumnOrWildcard column = new ColumnOrWildcard();
+        column.columnName = columnName;
+        column.propertyName = propertyName;
+        list.add(column);
+    }
+
+    void setSupportSQL1(boolean sql1) {
+        this.supportSQL1 = sql1;
+    }
+
     private SelectorImpl parseSelector() throws ParseException {
         String nodeTypeName = readName();
         if (readIf("AS")) {
@@ -249,7 +277,7 @@ public class SQL2Parser {
     private ConstraintImpl parseCondition() throws ParseException {
         ConstraintImpl a;
         if (readIf("NOT")) {
-            a = factory.not(parseConstraint());
+            a = factory.not(parseCondition());
         } else if (readIf("(")) {
             a = parseConstraint();
             read(")");
@@ -273,6 +301,15 @@ public class SQL2Parser {
             } else {
                 a = parseCondition(factory.propertyValue(getOnlySelectorName(), name));
             }
+        } else if (supportSQL1) {
+            StaticOperandImpl left = parseStaticOperand();
+            if (readIf("IN")) {
+                DynamicOperandImpl right = parseDynamicOperand();
+                ConstraintImpl c = factory.comparison(right, Operator.EQUAL, left);
+                return c;
+            } else {
+                throw getSyntaxError();
+            }
         } else {
             throw getSyntaxError();
         }
@@ -344,6 +381,13 @@ public class SQL2Parser {
                 read(",");
                 c = factory.fullTextSearch(
                         getOnlySelectorName(), null, parseStaticOperand());
+            } else if (readIf(".")) {
+                if (!supportSQL1) {
+                    throw getSyntaxError("selector name, property name, or *");
+                }
+                read(",");
+                c = factory.fullTextSearch(
+                        getOnlySelectorName(), null, parseStaticOperand());
             } else {
                 String name = readName();
                 if (readIf(".")) {
@@ -612,16 +656,6 @@ public class SQL2Parser {
 
     private ColumnImpl[] resolveColumns(ArrayList<ColumnOrWildcard> list) throws ParseException {
         ArrayList<ColumnImpl> columns = new ArrayList<ColumnImpl>();
-//        for (SelectorImpl selector : selectors) {
-//            String selectorName = selector.getSelectorName();
-//            String columnName;
-//            if (selectors.size() > 1) {
-//                columnName = selectorName + "." + "jcr:path";
-//            } else {
-//                columnName = "jcr:path";
-//            }
-//            columns.add(factory.column(selectorName, "jcr:path", columnName));
-//        }
         for (ColumnOrWildcard c : list) {
             if (c.propertyName == null) {
                 for (SelectorImpl selector : selectors) {
@@ -820,6 +854,10 @@ public class SQL2Parser {
                 type = types[i];
                 if (type != CHAR_NAME && type != CHAR_VALUE) {
                     c = chars[i];
+                    if (supportSQL1 && c == ':') {
+                        i++;
+                        continue;
+                    }
                     break;
                 }
                 i++;
@@ -1001,7 +1039,7 @@ public class SQL2Parser {
         if (expected != null) {
             query += "; expected: " + expected;
         }
-        return new ParseException("Query:\n" + query, index);
+        return new ParseException("Query: " + query, index);
     }
 
     /**

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java Fri Jul  6 12:49:10 2012
@@ -49,7 +49,7 @@ public class AndImpl extends ConstraintI
 
     @Override
     public String toString() {
-        return protect(constraint1) + " AND " + protect(constraint2);
+        return protect(constraint1) + " and " + protect(constraint2);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java Fri Jul  6 12:49:10 2012
@@ -48,7 +48,7 @@ public class ChildNodeImpl extends Const
 
     @Override
     public String toString() {
-        return "ISCHILDNODE(" + selectorName + ", " + quotePath(parentPath) + ')';
+        return "ischildnode(" + selectorName + ", " + quotePath(parentPath) + ')';
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeJoinConditionImpl.java Fri Jul  6 12:49:10 2012
@@ -51,7 +51,7 @@ public class ChildNodeJoinConditionImpl 
     public String toString() {
         String child = getChildSelectorName();
         String parent = getParentSelectorName();
-        return "ISCHILDNODE(" + child + ", " + parent + ')';
+        return "ischildnode(" + child + ", " + parent + ')';
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ColumnImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ColumnImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ColumnImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ColumnImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,8 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 
 public class ColumnImpl extends AstElement {
 
@@ -52,17 +54,21 @@ public class ColumnImpl extends AstEleme
     public String toString() {
         if (propertyName != null) {
             return getSelectorName() + '.' + getPropertyName()
-                    + " AS [" + columnName + "]";
+                    + " as [" + columnName + "]";
         } else {
             return getSelectorName() + ".*";
         }
     }
 
-    public CoreValue currentValue() {
+    public PropertyState currentProperty() {
         if (propertyName == null) {
             // TODO for SELECT * FROM queries, currently return the path (for testing only)
             String p = selector.currentPath();
-            return p == null ? null : query.getValueFactory().createValue(p);
+            if (p == null) {
+                return null;
+            }
+            CoreValue v = query.getValueFactory().createValue(p);
+            return new PropertyStateImpl(SelectorImpl.PATH, v);
         }
         return selector.currentProperty(propertyName);
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java Fri Jul  6 12:49:10 2012
@@ -20,9 +20,11 @@ package org.apache.jackrabbit.oak.query.
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.Iterator;
 import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class ComparisonImpl extends ConstraintImpl {
@@ -53,19 +55,48 @@ public class ComparisonImpl extends Cons
     public boolean evaluate() {
         // JCR 2.0 spec, 6.7.16 Comparison:
         // "operand1 may evaluate to an array of values"
-        // TODO support arrays
-        CoreValue v1 = operand1.currentValue();
+        PropertyState p1 = operand1.currentProperty();
+        if (p1 == null) {
+            return false;
+        }
         // "operand2 always evaluates to a scalar value"
         CoreValue v2 = operand2.currentValue();
-        if (v1 == null || v2 == null) {
+        if (v2 == null) {
             // TODO comparison: what about (null <> x) ?
             return false;
         }
-        if (v1.getType() != v2.getType()) {
+        boolean isArray = p1.isArray();
+        int v1Type;
+        if (isArray) {
+            Iterator<CoreValue> it = p1.getValues().iterator();
+            if (it.hasNext()) {
+                v1Type = it.next().getType();
+            } else {
+                // workaround for OAK-140: PropertyState: data type of empty array property
+                v1Type = v2.getType();
+            }
+        } else {
+            v1Type = p1.getValue().getType();
+        }
+        if (v1Type != v2.getType()) {
             // "the value of operand2 is converted to the
             // property type of the value of operand1"
-            v2 = convert(v2, v1.getType());
+            v2 = convert(v2, v1Type);
         }
+        if (!isArray) {
+            return evaluate(p1.getValue(), v2);
+        }
+        // for multi-valued properties: if any of the value matches,
+        // then return true
+        for (CoreValue v1 : p1.getValues()) {
+            if (evaluate(v1, v2)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean evaluate(CoreValue v1, CoreValue v2) {
         switch (operator) {
         case EQUAL:
             return v1.equals(v2);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java Fri Jul  6 12:49:10 2012
@@ -55,7 +55,7 @@ public class DescendantNodeImpl extends 
 
     @Override
     public String toString() {
-        return "ISDESCENDANTNODE(" + getSelectorName() + ", " + quotePath(ancestorPath) + ')';
+        return "isdescendantnode(" + getSelectorName() + ", " + quotePath(ancestorPath) + ')';
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeJoinConditionImpl.java Fri Jul  6 12:49:10 2012
@@ -52,7 +52,7 @@ public class DescendantNodeJoinCondition
     public String toString() {
         String descendant = getDescendantSelectorName();
         String ancestor = getAncestorSelectorName();
-        return "ISDESCENDANTNODE(" + descendant + ", " + ancestor + ')';
+        return "isdescendantnode(" + descendant + ", " + ancestor + ')';
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DynamicOperandImpl.java Fri Jul  6 12:49:10 2012
@@ -17,11 +17,12 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public abstract class DynamicOperandImpl extends AstElement {
 
-    public abstract CoreValue currentValue();
+    public abstract PropertyState currentProperty();
 
     public abstract void apply(FilterImpl f, Operator operator, CoreValue v);
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java Fri Jul  6 12:49:10 2012
@@ -18,7 +18,7 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
-import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class EquiJoinConditionImpl extends JoinConditionImpl {
@@ -79,23 +79,40 @@ public class EquiJoinConditionImpl exten
 
     @Override
     public boolean evaluate() {
-        CoreValue v1 = selector1.currentProperty(property1Name);
-        if (v1 == null) {
+        PropertyState p1 = selector1.currentProperty(property1Name);
+        if (p1 == null) {
             return false;
         }
-        CoreValue v2 = selector2.currentProperty(property2Name);
-        return v2 != null && v1.equals(v2);
+        PropertyState p2 = selector2.currentProperty(property2Name);
+        if (p2 == null) {
+            return false;
+        }
+        if (!p1.isArray() && !p2.isArray()) {
+            // both are single valued
+            return p1.getValue().equals(p2.getValue());
+        }
+        // TODO what is the expected result of an equi join for multi-valued properties?
+        throw new IllegalArgumentException("Join on multi-valued properties is currently not supported");
     }
 
     @Override
     public void apply(FilterImpl f) {
-        CoreValue v1 = selector1.currentProperty(property1Name);
-        CoreValue v2 = selector2.currentProperty(property2Name);
-        if (f.getSelector() == selector1 && v2 != null) {
-            f.restrictProperty(property1Name, Operator.EQUAL, v2);
+        // TODO what is the expected result of an equi join for multi-valued properties?
+        PropertyState p1 = selector1.currentProperty(property1Name);
+        PropertyState p2 = selector2.currentProperty(property2Name);
+        if (f.getSelector() == selector1 && p2 != null) {
+            if (p2.isArray()) {
+                // TODO what is the expected result of an equi join for multi-valued properties?
+                throw new IllegalArgumentException("Join on multi-valued properties is currently not supported");
+            }
+            f.restrictProperty(property1Name, Operator.EQUAL, p2.getValue());
         }
-        if (f.getSelector() == selector2 && v1 != null) {
-            f.restrictProperty(property2Name, Operator.EQUAL, v1);
+        if (f.getSelector() == selector2 && p1 != null) {
+            if (p1.isArray()) {
+                // TODO what is the expected result of an equi join for multi-valued properties?
+                throw new IllegalArgumentException("Join on multi-valued properties is currently not supported");
+            }
+            f.restrictProperty(property2Name, Operator.EQUAL, p1.getValue());
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java Fri Jul  6 12:49:10 2012
@@ -59,9 +59,8 @@ public class FullTextSearchImpl extends 
 
     @Override
     public String toString() {
-        // TODO quote property names?
         StringBuilder builder = new StringBuilder();
-        builder.append("CONTAINS(");
+        builder.append("contains(");
         builder.append(getSelectorName());
         if (propertyName != null) {
             builder.append('.');
@@ -75,6 +74,18 @@ public class FullTextSearchImpl extends 
         return builder.toString();
     }
 
+    private boolean evaluateContains(PropertyState p) {
+        if (!p.isArray()) {
+            return evaluateContains(p.getValue());
+        }
+        for (CoreValue v : p.getValues()) {
+            if (evaluateContains(v)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private boolean evaluateContains(CoreValue value) {
         String v = value.getString();
         return expr.evaluate(v);
@@ -83,16 +94,15 @@ public class FullTextSearchImpl extends 
     @Override
     public boolean evaluate() {
         if (propertyName != null) {
-            CoreValue v = selector.currentProperty(propertyName);
-            if (v == null) {
+            PropertyState p = selector.currentProperty(propertyName);
+            if (p == null) {
                 return false;
             }
-            return evaluateContains(v);
+            return evaluateContains(p);
         }
         Tree tree = getTree(selector.currentPath());
         for (PropertyState p : tree.getProperties()) {
-            CoreValue v = selector.currentProperty(p.getName());
-            if (evaluateContains(v)) {
+            if (evaluateContains(p)) {
                 return true;
             }
         }
@@ -119,7 +129,7 @@ public class FullTextSearchImpl extends 
                 f.restrictProperty(propertyName, Operator.NOT_EQUAL, (CoreValue) null);
             }
         }
-        // TODO support fulltext index conditions
+        f.restrictFulltextCondition(fullTextSearchExpression.currentValue().getString());
     }
 
     public static class FullTextParser {
@@ -255,6 +265,19 @@ public class FullTextSearchImpl extends 
             return list.size() == 1 ? list.get(0) : this;
         }
 
+        @Override
+        public String toString() {
+            StringBuilder buff = new StringBuilder();
+            int i = 0;
+            for (FullTextExpression e : list) {
+                if (i++ > 0) {
+                    buff.append(' ');
+                }
+                buff.append(e.toString());
+            }
+            return buff.toString();
+        }
+
     }
 
     static class FullTextOr extends FullTextExpression {
@@ -275,6 +298,19 @@ public class FullTextSearchImpl extends 
             return list.size() == 1 ? list.get(0).simplify() : this;
         }
 
+        @Override
+        public String toString() {
+            StringBuilder buff = new StringBuilder();
+            int i = 0;
+            for (FullTextExpression e : list) {
+                if (i++ > 0) {
+                    buff.append(" OR ");
+                }
+                buff.append(e.toString());
+            }
+            return buff.toString();
+        }
+
     }
 
     static class FullTextTerm extends FullTextExpression {
@@ -294,6 +330,11 @@ public class FullTextSearchImpl extends 
             return this;
         }
 
+        @Override
+        public String toString() {
+            return (not ? "-" : "") + "\"" + text.replaceAll("\"", "\\\"") + "\"";
+        }
+
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class FullTextSearchScoreImpl extends DynamicOperandImpl {
@@ -41,11 +42,11 @@ public class FullTextSearchScoreImpl ext
 
     @Override
     public String toString() {
-        return "SCORE(" + getSelectorName() + ')';
+        return "score(" + getSelectorName() + ')';
     }
 
     @Override
-    public CoreValue currentValue() {
+    public PropertyState currentProperty() {
         // TODO support evaluating fulltext conditions (score)
         return null;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java Fri Jul  6 12:49:10 2012
@@ -60,12 +60,12 @@ public class JoinImpl extends SourceImpl
 
     @Override
     public String getPlan() {
-        return left.getPlan() + ' ' + joinType.name() + " JOIN " + right.getPlan();
+        return left.getPlan() + ' ' + joinType.name() + " join " + right.getPlan();
     }
 
     @Override
     public String toString() {
-        return left + " " + joinType.name() + " JOIN " + right;
+        return left + " " + joinType.name() + " join " + right;
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinType.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinType.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinType.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinType.java Fri Jul  6 12:49:10 2012
@@ -21,11 +21,11 @@ package org.apache.jackrabbit.oak.query.
  */
 public enum JoinType {
 
-    INNER("INNER JOIN"),
+    INNER("inner join"),
 
-    LEFT_OUTER("LEFT OUTER JOIN"),
+    LEFT_OUTER("left outer join"),
 
-    RIGHT_OUTER("RIGHT OUTER JOIN");
+    RIGHT_OUTER("right outer join");
 
     /**
      * The name of this join type.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java Fri Jul  6 12:49:10 2012
@@ -20,6 +20,8 @@ package org.apache.jackrabbit.oak.query.
 
 import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class LengthImpl extends DynamicOperandImpl {
@@ -41,16 +43,22 @@ public class LengthImpl extends DynamicO
 
     @Override
     public String toString() {
-        return "LENGTH(" + getPropertyValue() + ')';
+        return "length(" + getPropertyValue() + ')';
     }
 
     @Override
-    public CoreValue currentValue() {
-        CoreValue v = propertyValue.currentValue();
-        if (v == null) {
+    public PropertyState currentProperty() {
+        PropertyState p = propertyValue.currentProperty();
+        if (p == null) {
             return null;
         }
-        return query.getValueFactory().createValue(v.length());
+        if (!p.isArray()) {
+            long length = p.getValue().length();
+            CoreValue v = query.getValueFactory().createValue(length);
+            return new PropertyStateImpl("LENGTH", v);
+        }
+        // TODO what is the expected result for LENGTH(multiValueProperty)?
+        throw new IllegalArgumentException("LENGTH(x) on multi-valued property is not supported");
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LiteralImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LiteralImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LiteralImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LiteralImpl.java Fri Jul  6 12:49:10 2012
@@ -43,7 +43,7 @@ public class LiteralImpl extends StaticO
     @Override
     public String toString() {
         String type = PropertyType.nameFromValue(value.getType()).toUpperCase();
-        return "CAST(" + escape() + " AS " + type + ')';
+        return "cast(" + escape() + " as " + type + ')';
     }
 
     private String escape() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LowerCaseImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,8 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class LowerCaseImpl extends DynamicOperandImpl {
@@ -40,17 +42,20 @@ public class LowerCaseImpl extends Dynam
 
     @Override
     public String toString() {
-        return "LOWER(" + operand + ')';
+        return "lower(" + operand + ')';
     }
 
     @Override
-    public CoreValue currentValue() {
-        CoreValue v = operand.currentValue();
-        if (v == null) {
+    public PropertyState currentProperty() {
+        PropertyState p = operand.currentProperty();
+        if (p == null) {
             return null;
         }
-        String value = v.getString();
-        return query.getValueFactory().createValue(value.toLowerCase());
+        // TODO what is the expected result of LOWER(x) for an array property?
+        // currently throws an exception
+        String value = p.getValue().getString();
+        CoreValue v = query.getValueFactory().createValue(value.toLowerCase());
+        return new PropertyStateImpl(p.getName(), v);
     }
 
     @Override

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=1358170&r1=1358169&r2=1358170&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 Fri Jul  6 12:49:10 2012
@@ -20,6 +20,8 @@ package org.apache.jackrabbit.oak.query.
 
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class NodeLocalNameImpl extends DynamicOperandImpl {
@@ -42,7 +44,7 @@ public class NodeLocalNameImpl extends D
 
     @Override
     public String toString() {
-        return "LOCALNAME(" + getSelectorName() + ')';
+        return "localname(" + getSelectorName() + ')';
     }
 
     public void bindSelector(SourceImpl source) {
@@ -53,12 +55,13 @@ public class NodeLocalNameImpl extends D
     }
 
     @Override
-    public CoreValue currentValue() {
+    public PropertyState 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);
-        return query.getValueFactory().createValue(localName);
+        CoreValue v = query.getValueFactory().createValue(localName);
+        return new PropertyStateImpl("LOCALNAME", v);
     }
 
     @Override

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=1358170&r1=1358169&r2=1358170&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 Fri Jul  6 12:49:10 2012
@@ -20,7 +20,9 @@ package org.apache.jackrabbit.oak.query.
 
 import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class NodeNameImpl extends DynamicOperandImpl {
@@ -43,7 +45,7 @@ public class NodeNameImpl extends Dynami
 
     @Override
     public String toString() {
-        return "NAME(" + getSelectorName() + ')';
+        return "name(" + getSelectorName() + ')';
     }
 
     public void bindSelector(SourceImpl source) {
@@ -54,13 +56,14 @@ public class NodeNameImpl extends Dynami
     }
 
     @Override
-    public CoreValue currentValue() {
+    public PropertyState currentProperty() {
         String name = PathUtils.getName(selector.currentPath());
         CoreValue v = query.getValueFactory().createValue(name);
         String path = v.getString();
         // normalize paths (./name > name)
         path = getOakPath(path);
-        return query.getValueFactory().createValue(path, PropertyType.NAME);
+        CoreValue v2 = query.getValueFactory().createValue(path, PropertyType.NAME);
+        return new PropertyStateImpl("NAME", v2);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java Fri Jul  6 12:49:10 2012
@@ -44,7 +44,7 @@ public class NotImpl extends ConstraintI
 
     @Override
     public String toString() {
-        return "NOT " + protect(constraint);
+        return "not " + protect(constraint);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java Fri Jul  6 12:49:10 2012
@@ -50,7 +50,7 @@ public class OrImpl extends ConstraintIm
 
     @Override
     public String toString() {
-        return protect(constraint1) + " OR " + protect(constraint2);
+        return protect(constraint1) + " or " + protect(constraint2);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Order.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Order.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Order.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/Order.java Fri Jul  6 12:49:10 2012
@@ -21,9 +21,9 @@ package org.apache.jackrabbit.oak.query.
  */
 public enum Order {
 
-    ASCENDING("ASC"),
+    ASCENDING("asc"),
 
-    DESCENDING("DESC");
+    DESCENDING("desc");
 
     /**
      * The name of this order.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrderingImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrderingImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrderingImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrderingImpl.java Fri Jul  6 12:49:10 2012
@@ -43,11 +43,7 @@ public class OrderingImpl extends AstEle
 
     @Override
     public String toString() {
-        if (order == Order.ASCENDING) {
-            return operand + " ASC";
-        } else {
-            return operand + " DESC";
-        }
+        return operand + " " + order.name();
     }
 
     public boolean isDescending() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyExistenceImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class PropertyExistenceImpl extends ConstraintImpl {
@@ -42,8 +43,8 @@ public class PropertyExistenceImpl exten
 
     @Override
     public boolean evaluate() {
-        CoreValue v = selector.currentProperty(propertyName);
-        return v != null;
+        PropertyState p = selector.currentProperty(propertyName);
+        return p != null;
     }
 
     @Override
@@ -54,7 +55,7 @@ public class PropertyExistenceImpl exten
     @Override
     public String toString() {
         // TODO quote property names?
-        return getSelectorName() + '.' + propertyName + " IS NOT NULL";
+        return getSelectorName() + '.' + propertyName + " is not null";
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -54,7 +55,7 @@ public class PropertyValueImpl extends D
     }
 
     @Override
-    public CoreValue currentValue() {
+    public PropertyState currentProperty() {
         if (propertyName.indexOf('/') < 0) {
             return selector.currentProperty(propertyName);
         }
@@ -76,7 +77,7 @@ public class PropertyValueImpl extends D
         if (!tree.hasProperty(name)) {
             return null;
         }
-        return tree.getProperty(name).getValue();
+        return tree.getProperty(name);
     }
 
     public void bindSelector(SourceImpl source) {
@@ -89,6 +90,10 @@ public class PropertyValueImpl extends D
     @Override
     public void apply(FilterImpl f, Operator operator, CoreValue v) {
         if (f.getSelector() == selector) {
+        		if (operator == Operator.NOT_EQUAL && v != null) {
+        			// not supported
+        			return;
+        		}
             f.restrictProperty(propertyName, operator, v);
         }
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeImpl.java Fri Jul  6 12:49:10 2012
@@ -54,7 +54,7 @@ public class SameNodeImpl extends Constr
 
     @Override
     public String toString() {
-        return "ISSAMENODE(" + getSelectorName() + ", " + quotePath(path) + ')';
+        return "issamenode(" + getSelectorName() + ", " + quotePath(path) + ')';
     }
 
     public void bindSelector(SourceImpl source) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SameNodeJoinConditionImpl.java Fri Jul  6 12:49:10 2012
@@ -56,7 +56,7 @@ public class SameNodeJoinConditionImpl e
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder();
-        builder.append("ISSAMENODE(");
+        builder.append("issamenode(");
         builder.append(getSelector1Name());
         builder.append(", ");
         builder.append(getSelector2Name());

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Fri Jul  6 12:49:10 2012
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.mk.api.Micr
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.Query;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.Cursor;
@@ -30,7 +31,7 @@ import org.apache.jackrabbit.oak.spi.Que
 public class SelectorImpl extends SourceImpl {
 
     // TODO jcr:path isn't an official feature, support it?
-    private static final String PATH = "jcr:path";
+    public static final String PATH = "jcr:path";
 
     private static final String JCR_PRIMARY_TYPE = "jcr:primaryType";
 
@@ -62,7 +63,7 @@ public class SelectorImpl extends Source
     @Override
     public String toString() {
         // TODO quote nodeTypeName?
-        return nodeTypeName + " AS " + getSelectorName();
+        return nodeTypeName + " as " + getSelectorName();
     }
 
 
@@ -78,7 +79,7 @@ public class SelectorImpl extends Source
 
     @Override
     public String getPlan() {
-        return  nodeTypeName + " AS " + getSelectorName() + " /* " + index.getPlan(createFilter()) + " */";
+        return  nodeTypeName + " as " + getSelectorName() + " /* " + index.getPlan(createFilter()) + " */";
     }
 
     private FilterImpl createFilter() {
@@ -128,7 +129,7 @@ public class SelectorImpl extends Source
         return cursor == null ? null : cursor.currentPath();
     }
 
-    public CoreValue currentProperty(String propertyName) {
+    public PropertyState currentProperty(String propertyName) {
         if (propertyName.equals(PATH)) {
             String p = currentPath();
             if (p == null) {
@@ -139,17 +140,14 @@ public class SelectorImpl extends Source
                 // not a local path
                 return null;
             }
-            return query.getValueFactory().createValue(local);
+            CoreValue v = query.getValueFactory().createValue(local);
+            return new PropertyStateImpl(PATH, v);
         }
         String path = currentPath();
         if (path == null) {
             return null;
         }
-        PropertyState p = getTree(path).getProperty(propertyName);
-        if (p == null) {
-            return null;
-        }
-        return p.getValue();
+        return getTree(path).getProperty(propertyName);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/UpperCaseImpl.java Fri Jul  6 12:49:10 2012
@@ -19,6 +19,8 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.kernel.PropertyStateImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class UpperCaseImpl extends DynamicOperandImpl {
@@ -40,17 +42,20 @@ public class UpperCaseImpl extends Dynam
 
     @Override
     public String toString() {
-        return "UPPER(" + operand + ')';
+        return "upper(" + operand + ')';
     }
 
     @Override
-    public CoreValue currentValue() {
-        CoreValue v = operand.currentValue();
-        if (v == null) {
+    public PropertyState currentProperty() {
+        PropertyState p = operand.currentProperty();
+        if (p == null) {
             return null;
         }
-        String value = v.getString();
-        return query.getValueFactory().createValue(value.toUpperCase());
+        // TODO what is the expected result of UPPER(x) for an array property?
+        // currently throws an exception
+        String value = p.getValue().getString();
+        CoreValue v = query.getValueFactory().createValue(value.toUpperCase());
+        return new PropertyStateImpl(p.getName(), v);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java Fri Jul  6 12:49:10 2012
@@ -60,6 +60,8 @@ public class FilterImpl implements Filte
      */
     private String valuePrefix;
 
+    private String fulltextCondition;
+
     private final HashMap<String, PropertyRestriction> propertyRestrictions =
             new HashMap<String, PropertyRestriction>();
 
@@ -346,4 +348,15 @@ public class FilterImpl implements Filte
         }
     }
 
+    @Override
+    public String getFulltextCondition() {
+        return fulltextCondition;
+    }
+
+    public void restrictFulltextCondition(String fulltextCondition) {
+        // TODO support combining multiple conditions as in
+        // contains('x') and contains('y')
+        this.fulltextCondition = fulltextCondition;
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.java Fri Jul  6 12:49:10 2012
@@ -30,6 +30,13 @@ public interface Filter {
     Collection<PropertyRestriction> getPropertyRestrictions();
 
     /**
+     * Get the fulltext search condition.
+     *
+     * @return the condition, or null if not used
+     */
+    String getFulltextCondition();
+
+    /**
      * Get the property restriction for the given property, if any.
      *
      * @param propertyName the property name

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FullTextTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FullTextTest.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FullTextTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FullTextTest.java Fri Jul  6 12:49:10 2012
@@ -79,7 +79,7 @@ public class FullTextTest {
         testInvalid("\"x\"y", "\"x\"(*)y; expected: space");
     }
 
-    private void testInvalid(String pattern, String expectedMessage) {
+    private static void testInvalid(String pattern, String expectedMessage) {
         try {
             test(pattern, "");
             fail("Expected exception " + expectedMessage);
@@ -91,7 +91,7 @@ public class FullTextTest {
         }
     }
 
-    private boolean test(String pattern, String value) throws ParseException {
+    private static boolean test(String pattern, String value) throws ParseException {
         FullTextSearchImpl.FullTextExpression e = FullTextSearchImpl.FullTextParser.parse(pattern);
         return e.evaluate(value);
     }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java Fri Jul  6 12:49:10 2012
@@ -55,20 +55,20 @@ public class QueryTest extends AbstractQ
         sv.put("id", vf.createValue("1"));
         Iterator<? extends ResultRow> result;
         result = executeQuery("select * from [nt:base] where id = $id",
-                sv).getRows().iterator();
+                QueryEngineImpl.SQL2, sv).getRows().iterator();
         assertTrue(result.hasNext());
         assertEquals("/test/hello", result.next().getPath());
 
         sv.put("id", vf.createValue("2"));
         result = executeQuery("select * from [nt:base] where id = $id",
-                sv).getRows().iterator();
+                QueryEngineImpl.SQL2, sv).getRows().iterator();
         assertTrue(result.hasNext());
         assertEquals("/test/world", result.next().getPath());
 
         result = executeQuery("explain select * from [nt:base] where id = 1 order by id",
-                null).getRows().iterator();
+                QueryEngineImpl.SQL2, null).getRows().iterator();
         assertTrue(result.hasNext());
-        assertEquals("nt:base AS nt:base /* traverse \"//*\" */",
+        assertEquals("nt:base as nt:base /* traverse \"//*\" */",
                 result.next().getValue("plan").getString());
 
     }
@@ -103,10 +103,15 @@ public class QueryTest extends AbstractQ
                     if (!line.equals(got)) {
                         errors = true;
                     }
-                } else if (line.startsWith("select") || line.startsWith("explain")) {
+                } else if (line.startsWith("select") || line.startsWith("explain") || line.startsWith("sql1")) {
                     w.println(line);
+                    String language = QueryEngineImpl.SQL2;
+                    if (line.startsWith("sql1")) {
+                        language = QueryEngineImpl.SQL;
+                        line = line.substring("sql1 ".length());
+                    }
                     boolean readEnd = true;
-                    for (String resultLine : executeQuery(line)) {
+                    for (String resultLine : executeQuery(line, language)) {
                         w.println(resultLine);
                         if (readEnd) {
                             line = r.readLine();
@@ -159,10 +164,10 @@ public class QueryTest extends AbstractQ
         }
     }
 
-    private List<String> executeQuery(String query) {
+    private List<String> executeQuery(String query, String language) {
         List<String> lines = new ArrayList<String>();
         try {
-            Result result = executeQuery(query, null);
+            Result result = executeQuery(query, language, null);
             for (ResultRow row : result.getRows()) {
                 lines.add(readRow(row));
             }
@@ -177,7 +182,7 @@ public class QueryTest extends AbstractQ
         return lines;
     }
 
-    private String readRow(ResultRow row) {
+    private static String readRow(ResultRow row) {
         StringBuilder buff = new StringBuilder();
         CoreValue[] values = row.getValues();
         for (int i = 0; i < values.length; i++) {
@@ -190,8 +195,8 @@ public class QueryTest extends AbstractQ
         return buff.toString();
     }
 
-    private Result executeQuery(String statement, HashMap<String, CoreValue> sv) throws ParseException {
-        return qe.executeQuery(statement, QueryEngineImpl.SQL2, session, Long.MAX_VALUE, 0, sv, null);
+    private Result executeQuery(String statement, String language, HashMap<String, CoreValue> sv) throws ParseException {
+        return qe.executeQuery(statement, language, session, Long.MAX_VALUE, 0, sv, null);
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/LikePatternTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/LikePatternTest.java?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/LikePatternTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/LikePatternTest.java Fri Jul  6 12:49:10 2012
@@ -34,7 +34,7 @@ public class LikePatternTest {
         pattern("%\\_%", "A_A", "AAA", null, null);
     }
 
-    private void pattern(String pattern, String match, String noMatch, String lower, String upper) {
+    private static void pattern(String pattern, String match, String noMatch, String lower, String upper) {
         ComparisonImpl.LikePattern p = new ComparisonImpl.LikePattern(pattern);
         if (match != null) {
             assertTrue(p.matches(match));

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt Fri Jul  6 12:49:10 2012
@@ -21,6 +21,23 @@
 # * new tests are typically be added on top, after the syntax docs
 # * use ascii character only
 
+# sql-1 query (nt:unstructured needs to be escaped in sql-2)
+
+sql1 select prop1 from nt:unstructured where prop1 is not null order by prop1 asc
+
+# test multi-valued properties
+
+commit / + "test": { "a": { "name": ["Hello", "World" ] }, "b": { "name" : "Hello" }}
+
+select * from [nt:base] where name = 'Hello'
+/test/a
+/test/b
+
+select * from [nt:base] where name = 'World'
+/test/a
+
+commit / - "test"
+
 # test the property content index
 
 select * from [nt:base] as p inner join [nt:base] as p on ischildnode(p, p) where p.[jcr:path] = '/'
@@ -29,8 +46,17 @@ java.lang.IllegalArgumentException: Two 
 commit / + "test": { "a": { "id": "10" }, "b": { "id" : "20" }}
 commit /jcr:system/indexes + "property@id,unique": {}
 
+# combining 'not' and 'and'
+
+select * from [nt:base] where id is not null and not id = '100' and id <> '20'
+/test/a
+
+select * from [nt:base] where id is not null and not (id = '100' and id <> '20')
+/test/a
+/test/b
+
 explain select * from [nt:base] where id = '10'
-nt:base AS nt:base /* propertyIndex "id [10..10]" */
+nt:base as nt:base /* propertyIndex "id [10..10]" */
 
 select * from [nt:base] where id = '10'
 /test/a
@@ -39,7 +65,7 @@ select [jcr:path], * from [nt:base] wher
 /test/a, null
 
 explain select * from [nt:base] where id > '10'
-nt:base AS nt:base /* traverse "//*" */
+nt:base as nt:base /* traverse "//*" */
 
 commit / - "test"
 commit /jcr:system/indexes - "property@id,unique"
@@ -63,10 +89,10 @@ commit / + "test": { "jcr:resource": {},
 select * from [nt:base] where id = -1
 
 explain select * from [nt:base] as b where ischildnode(b, '/test')
-nt:base AS b /* traverse "/test/*" */
+nt:base as b /* traverse "/test/*" */
 
 explain select * from [nt:base] as b where isdescendantnode(b, '/test')
-nt:base AS b /* traverse "/test//*" */
+nt:base as b /* traverse "/test//*" */
 
 select * from [nt:base] as b where ischildnode(b, '/test')
 /test/jcr:resource
@@ -152,7 +178,7 @@ select * from [nt:base] as p inner join 
 /parents/p2, /children/c3
 
 explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
-nt:base AS p /* traverse "//*" */ INNER JOIN nt:base AS c /* traverse "//*" */
+nt:base as p /* traverse "//*" */ INNER join nt:base as c /* traverse "//*" */
 
 commit / - "parents"
 commit / - "children"

Modified: jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt?rev=1358170&r1=1358169&r2=1358170&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryXpathTest.txt Fri Jul  6 12:49:10 2012
@@ -18,6 +18,22 @@
 # * lines starting with "xpath" are xpath queries, followed by expected sql2 query
 # * use ascii character only
 
+# jboss example queries
+
+xpath //*
+select [jcr:path], [jcr:score], * from [nt:base]
+
+xpath //element(*,my:type)
+select [jcr:path], [jcr:score], * from [my:type]
+
+xpath //element(*,my:type)/@my:title
+select [jcr:path], [jcr:score], [my:title] from [my:type]
+
+xpath //element(*,my:type)/(@my:title | @my:text)
+select [jcr:path], [jcr:score], [my:title], [my:text] from [my:type]
+
+# other queries
+
 xpath /jcr:root/testdata/node[@jcr:primaryType]
 select [jcr:path], [jcr:score], * from [nt:base] where ([jcr:primaryType] is not null) and issamenode('/testdata/node')