jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r1373284 - 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...
Date Wed, 15 Aug 2012 09:23:39 GMT
Author: thomasm
Date: Wed Aug 15 09:23:38 2012
New Revision: 1373284

URL: http://svn.apache.org/viewvc?rev=1373284&view=rev
Log:
OAK-28 Query implementation

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/SQL2Parser.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.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/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/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/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/SourceImpl.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/query/index/TraversingCursor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/Filter.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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -529,7 +529,6 @@ public class Indexer implements QueryInd
 
         // 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) {
@@ -675,7 +674,7 @@ public class Indexer implements QueryInd
                 if (index instanceof PropertyIndex) {
                     qi = new PropertyContentIndex((PropertyIndex) index);
                 } else if (index instanceof PrefixIndex) {
-                    // TODO support prefix indexes?
+                    // TODO support prefix indexes in the query engine?
                 }
                 queryIndexList.add(qi);
             }

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -43,6 +43,7 @@ import java.util.HashMap;
 
 /**
  * The SQL2 parser can convert a JCR-SQL2 query to a query.
+ * The 'old' SQL query language is also supported if
  */
 public class SQL2Parser {
 
@@ -151,7 +152,12 @@ public class SQL2Parser {
         list.add(column);
     }
 
-    void setSupportSQL1(boolean sql1) {
+    /**
+     * Enable or disable support for SQL-1 queries.
+     *
+     * @param sql1 the new value
+     */
+    public void setSupportSQL1(boolean sql1) {
         this.supportSQL1 = sql1;
     }
 
@@ -332,6 +338,18 @@ public class SQL2Parser {
             c = factory.comparison(left, Operator.GREATER_OR_EQUAL, parseStaticOperand());
         } else if (readIf("LIKE")) {
             c = factory.comparison(left, Operator.LIKE, parseStaticOperand());
+            if (supportSQL1) {
+                if (readIf("ESCAPE")) {
+                    StaticOperandImpl esc = parseStaticOperand();
+                    if (!(esc instanceof LiteralImpl)) {
+                        throw getSyntaxError("only ESCAPE '\' is supported");
+                    }
+                    CoreValue v = ((LiteralImpl) esc).getLiteralValue();
+                    if (!v.getString().equals("\\")) {
+                        throw getSyntaxError("only ESCAPE '\' is supported");
+                    }
+                }
+            }
         } else if (readIf("IS")) {
             boolean not = readIf("NOT");
             read("NULL");
@@ -563,6 +581,19 @@ public class SQL2Parser {
             literal = factory.literal(value);
             return literal;
         } else {
+            if (supportSQL1) {
+                if (readIf("TIMESTAMP")) {
+                    StaticOperandImpl op = parseStaticOperand();
+                    if (!(op instanceof LiteralImpl)) {
+                        throw getSyntaxError("literal");
+                    }
+                    LiteralImpl literal = (LiteralImpl) op;
+                    CoreValue value = literal.getLiteralValue();
+                    value = valueFactory.createValue(value.getString(), PropertyType.DATE);
+                    literal = factory.literal(value);
+                    return literal;
+                }
+            }
             throw getSyntaxError("static operand");
         }
     }
@@ -939,6 +970,15 @@ public class SQL2Parser {
             return;
         case CHAR_QUOTED:
             readString(i, '\"');
+            if (supportSQL1) {
+                // for SQL-2, this is a literal, as defined in
+                // the JCR 2.0 spec, 6.7.34 Literal - UncastLiteral
+                // but for compatibility with Jackrabbit 2.x, for
+                // SQL-1, this is an identifier, as in ANSI SQL
+                // (not in the JCR 1.0 spec)
+                // (confusing isn't it?)
+                currentTokenType = IDENTIFIER;
+            }
             return;
         case CHAR_END:
             currentToken = "";
@@ -1069,6 +1109,11 @@ public class SQL2Parser {
         return '\'' + value.replace("'", "''") + '\'';
     }
 
+    /**
+     * Enable or disable support for text literals in queries. The default is enabled.
+     *
+     * @param allowTextLiterals
+     */
     public void setAllowTextLiterals(boolean allowTextLiterals) {
         this.allowTextLiterals = allowTextLiterals;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java?rev=1373284&r1=1373283&r2=1373284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/XPathToSQL2Converter.java
Wed Aug 15 09:23:38 2012
@@ -56,11 +56,11 @@ public class XPathToSQL2Converter {
      * @throws ParseException if parsing fails
      */
     public String convert(String query) throws ParseException {
-        // TODO verify this is correct
         boolean explain = query.startsWith("explain ");
         if (explain) {
             query = query.substring("explain ".length());
         }
+        // TODO verify this is correct
         if (!query.startsWith("/")) {
             query = "/jcr:root/" + query;
         }
@@ -74,6 +74,10 @@ public class XPathToSQL2Converter {
         ArrayList<Expression> columnList = new ArrayList<Expression>();
         boolean children = false;
         boolean descendants = false;
+        // TODO support one node matcher ('*' wildcard), example:
+        // /jcr:root/content/acme/*/jcr:content[@template='/apps/acme']
+        // TODO verify '//' is behaving correctly, as specified, example:
+        // /jcr:root/content/acme//jcr:content[@template='/apps/acme']
         while (true) {
             String nodeType;
             if (readIf("/")) {
@@ -90,6 +94,11 @@ public class XPathToSQL2Converter {
                         }
                     } else {
                         descendants = true;
+                        if (readIf("[")) {
+                            Expression c = parseConstraint();
+                            condition = add(condition, c);
+                            read("]");
+                        }
                         // expected end of statement
                         break;
                     }
@@ -291,6 +300,8 @@ public class XPathToSQL2Converter {
             c = new Condition(left, "=", parseExpression());
         } else if (readIf("<>")) {
             c = new Condition(left, "<>", parseExpression());
+        } else if (readIf("!=")) {
+            c = new Condition(left, "<>", parseExpression());
         } else if (readIf("<")) {
             c = new Condition(left, "<", parseExpression());
         } else if (readIf(">")) {
@@ -386,13 +397,17 @@ public class XPathToSQL2Converter {
             f.params.add(parseExpression());
             read(")");
             return f;
+        } else if ("fn:name".equals(functionName)) {
+            Function f = new Function("name");
+            read(")");
+            return f;
         } else if ("fn:upper-case".equals(functionName)) {
             Function f = new Function("upper");
             f.params.add(parseExpression());
             read(")");
             return f;
-        // } else if ("jcr:deref".equals(functionName)) {
-            // TODO support jcr:deref?
+         } else if ("jcr:deref".equals(functionName)) {
+             throw getSyntaxError("jcr:deref is not supported");
         } else {
             throw getSyntaxError("jcr:like | jcr:contains | jcr:score | jcr:deref | fn:lower-case
| fn:upper-case");
         }
@@ -496,6 +511,14 @@ public class XPathToSQL2Converter {
                     checkRunOver(i, len, startLoop);
                 }
                 break;
+            case '\"':
+                type = CHAR_STRING;
+                types[i] = CHAR_STRING;
+                startLoop = i;
+                while (command[++i] != '\"') {
+                    checkRunOver(i, len, startLoop);
+                }
+                break;
             case ':':
             case '_':
                 type = CHAR_NAME;
@@ -547,7 +570,7 @@ public class XPathToSQL2Converter {
         case CHAR_NAME:
             while (true) {
                 type = types[i];
-                // the '-' can be part of a name, 
+                // the '-' can be part of a name,
                 // for example in "fn:lower-case"
                 if (type != CHAR_NAME && type != CHAR_VALUE && chars[i] !=
'-') {
                     c = chars[i];
@@ -623,7 +646,11 @@ public class XPathToSQL2Converter {
             readDecimal(i - 1, i);
             return;
         case CHAR_STRING:
-            readString(i, '\'');
+            if (chars[i - 1] == '\'') {
+                readString(i, '\'');
+            } else {
+                readString(i, '\"');
+            }
             return;
         case CHAR_END:
             currentToken = "";
@@ -635,7 +662,7 @@ public class XPathToSQL2Converter {
         }
     }
 
-    private void readString(int i, char end) {
+    private void readString(int i, char end) throws ParseException {
         char[] chars = statementChars;
         String result = null;
         while (true) {

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -55,10 +55,7 @@ public class ChildNodeImpl extends Const
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -58,14 +58,8 @@ public class ChildNodeJoinConditionImpl 
     }
 
     public void bindSelector(SourceImpl source) {
-        parentSelector = source.getSelector(parentSelectorName);
-        if (parentSelector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + parentSelector);
-        }
-        childSelector = source.getSelector(childSelectorName);
-        if (childSelector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + childSelectorName);
-        }
+        parentSelector = source.getExistingSelector(parentSelectorName);
+        childSelector = source.getExistingSelector(childSelectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -77,7 +77,7 @@ public class ColumnImpl extends AstEleme
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
+        selector = source.getExistingSelector(selectorName);
     }
 
 }

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -194,6 +194,33 @@ public class ComparisonImpl extends Cons
         return operand1 + " " + operator + " " + operand2;
     }
 
+    @Override
+    public void apply(FilterImpl f) {
+        CoreValue v = operand2.currentValue();
+        if (v != null) {
+            if (operator == Operator.LIKE) {
+                String pattern;
+                pattern = v.getString();
+                LikePattern p = new LikePattern(pattern);
+                String lowerBound = p.getLowerBound();
+                String upperBound = p.getUpperBound();
+                if (lowerBound == null && upperBound == null) {
+                    // ignore
+                } else {
+                    CoreValueFactory vf = query.getValueFactory();
+                    if (lowerBound != null) {
+                        operand1.apply(f, Operator.GREATER_OR_EQUAL, vf.createValue(lowerBound));
+                    }
+                    if (upperBound != null) {
+                        operand1.apply(f, Operator.LESS_OR_EQUAL, vf.createValue(upperBound));
+                    }
+                }
+            } else {
+                operand1.apply(f, operator, v);
+            }
+        }
+    }
+
     /**
      * A pattern matcher.
      */
@@ -361,31 +388,4 @@ public class ComparisonImpl extends Cons
 
     }
 
-    @Override
-    public void apply(FilterImpl f) {
-        CoreValue v = operand2.currentValue();
-        if (v != null) {
-            if (operator == Operator.LIKE) {
-                String pattern;
-                pattern = v.getString();
-                LikePattern p = new LikePattern(pattern);
-                String lowerBound = p.getLowerBound();
-                String upperBound = p.getUpperBound();
-                if (lowerBound == null && upperBound == null) {
-                    // ignore
-                } else {
-                    CoreValueFactory vf = query.getValueFactory();
-                    if (lowerBound != null) {
-                        operand1.apply(f, Operator.GREATER_OR_EQUAL, vf.createValue(lowerBound));
-                    }
-                    if (upperBound != null) {
-                        operand1.apply(f, Operator.LESS_OR_EQUAL, vf.createValue(upperBound));
-                    }
-                }
-            } else {
-                operand1.apply(f, operator, v);
-            }
-        }
-    }
-
 }

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -62,10 +62,7 @@ public class DescendantNodeImpl extends 
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -59,14 +59,8 @@ public class DescendantNodeJoinCondition
     }
 
     public void bindSelector(SourceImpl source) {
-        descendantSelector = source.getSelector(descendantSelectorName);
-        if (descendantSelector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + descendantSelectorName);
-        }
-        ancestorSelector = source.getSelector(ancestorSelectorName);
-        if (ancestorSelector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + ancestorSelectorName);
-        }
+        descendantSelector = source.getExistingSelector(descendantSelectorName);
+        ancestorSelector = source.getExistingSelector(ancestorSelectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -70,14 +70,8 @@ public class EquiJoinConditionImpl exten
     }
 
     public void bindSelector(SourceImpl source) {
-        selector1 = source.getSelector(selector1Name);
-        if (selector1 == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selector1Name);
-        }
-        selector2 = source.getSelector(selector2Name);
-        if (selector2 == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selector2Name);
-        }
+        selector1 = source.getExistingSelector(selector1Name);
+        selector2 = source.getExistingSelector(selector2Name);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -110,10 +110,7 @@ public class FullTextSearchImpl extends 
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
         CoreValue v = fullTextSearchExpression.currentValue();
         try {
             expr = FullTextParser.parse(v.getString());
@@ -133,7 +130,16 @@ public class FullTextSearchImpl extends 
     }
 
     /**
-     * A parser for fulltext condition literals.
+     * A parser for fulltext condition literals. The grammar is defined in the
+     * <a href="http://www.day.com/specs/jcr/2.0/6_Query.html#6.7.19">
+     * JCR 2.0 specification, 6.7.19 FullTextSearch</a>,
+     * as follows (a bit simplified):
+     * <pre>
+     * FullTextSearchLiteral ::= Disjunct {' OR ' Disjunct}
+     * Disjunct ::= Term {' ' Term}
+     * Term ::= ['-'] SimpleTerm
+     * SimpleTerm ::= Word | '"' Word {' ' Word} '"'
+     * </pre>
      */
     public static class FullTextParser {
 

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -55,10 +55,7 @@ public class FullTextSearchScoreImpl ext
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @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=1373284&r1=1373283&r2=1373284&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 15 09:23:38 2012
@@ -51,10 +51,7 @@ public class NodeLocalNameImpl extends D
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @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=1373284&r1=1373283&r2=1373284&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 15 09:23:38 2012
@@ -52,10 +52,7 @@ public class NodeNameImpl extends Dynami
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -62,10 +62,7 @@ public class PropertyExistenceImpl exten
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -84,10 +84,7 @@ public class PropertyValueImpl extends D
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -61,10 +61,7 @@ public class SameNodeImpl extends Constr
     }
 
     public void bindSelector(SourceImpl source) {
-        selector = source.getSelector(selectorName);
-        if (selector == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selectorName);
-        }
+        selector = source.getExistingSelector(selectorName);
     }
 
     @Override

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -72,14 +72,8 @@ public class SameNodeJoinConditionImpl e
     }
 
     public void bindSelector(SourceImpl source) {
-        selector1 = source.getSelector(selector1Name);
-        if (selector1 == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selector1Name);
-        }
-        selector2 = source.getSelector(selector2Name);
-        if (selector2 == null) {
-            throw new IllegalArgumentException("Unknown selector: " + selector2Name);
-        }
+        selector1 = source.getExistingSelector(selector1Name);
+        selector2 = source.getExistingSelector(selector2Name);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java?rev=1373284&r1=1373283&r2=1373284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
Wed Aug 15 09:23:38 2012
@@ -74,6 +74,20 @@ public abstract class SourceImpl extends
      * @return the selector, or null
      */
     public abstract SelectorImpl getSelector(String selectorName);
+    
+    /**
+     * Get the selector with the given name, or fail if not found.
+     *
+     * @param selectorName the selector name
+     * @return the selector (never null)
+     */
+    public SelectorImpl getExistingSelector(String selectorName) {
+        SelectorImpl s = getSelector(selectorName);
+        if (s == null) {
+            throw new IllegalArgumentException("Unknown selector: " + selectorName);
+        }
+        return s;
+    }
 
     /**
      * Get the query plan.

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -24,8 +24,10 @@ import org.apache.jackrabbit.oak.query.a
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
 import org.apache.jackrabbit.oak.spi.Filter;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map.Entry;
 
 /**
@@ -60,7 +62,10 @@ public class FilterImpl implements Filte
      */
     private String valuePrefix;
 
-    private String fulltextCondition;
+    /**
+     * The fulltext search conditions, if any.
+     */
+    private final ArrayList<String> fulltextConditions = new ArrayList<String>();
 
     private final HashMap<String, PropertyRestriction> propertyRestrictions =
             new HashMap<String, PropertyRestriction>();
@@ -349,14 +354,13 @@ public class FilterImpl implements Filte
     }
 
     @Override
-    public String getFulltextCondition() {
-        return fulltextCondition;
+    public List<String> getFulltextConditions() {
+        // TODO support fulltext conditions on certain properties
+        return fulltextConditions;
     }
 
-    public void restrictFulltextCondition(String fulltextCondition) {
-        // TODO support combining multiple conditions as in
-        // contains('x') and contains('y')
-        this.fulltextCondition = fulltextCondition;
+    public void restrictFulltextCondition(String condition) {
+        fulltextConditions.add(condition);
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java?rev=1373284&r1=1373283&r2=1373284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java
Wed Aug 15 09:23:38 2012
@@ -65,7 +65,8 @@ public class TraversingCursor implements
                 node = parent.getChildNode(name);
 
                 if (node == null) {
-                    return; // nothing can match this filter, leave nodes empty
+                    // nothing can match this filter, leave nodes empty
+                    return; 
                 }
             }
         }
@@ -150,7 +151,7 @@ public class TraversingCursor implements
         return true;
     }
 
-    private PropertyState getProperty(NodeState node, String path) {
+    private static PropertyState getProperty(NodeState node, String path) {
         int slash = path.indexOf('/');
         while (slash != -1) {
             node = node.getChildNode(path.substring(0, slash));
@@ -163,7 +164,7 @@ public class TraversingCursor implements
         return node.getProperty(path);
     }
 
-    private boolean matchesValue(CoreValue value, PropertyRestriction pr) {
+    private static boolean matchesValue(CoreValue value, PropertyRestriction pr) {
         int first = -1;
         if (pr.first != null) {
             first = compareValues(pr.first, value, pr.first.getType());
@@ -183,7 +184,7 @@ public class TraversingCursor implements
         return true;
     }
 
-    private int compareValues(CoreValue a, CoreValue b, int type) {
+    private static int compareValues(CoreValue a, CoreValue b, int type) {
         if (type == PropertyType.BOOLEAN) {
             return Boolean.valueOf(a.getBoolean()).compareTo(
                     Boolean.valueOf(b.getBoolean()));

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -27,14 +27,19 @@ import org.apache.jackrabbit.oak.api.Cor
  */
 public interface Filter {
 
+    /**
+     * Get the list of property restrictions, if any.
+     * 
+     * @return the conditions (an empty collection if not used)
+     */
     Collection<PropertyRestriction> getPropertyRestrictions();
 
     /**
-     * Get the fulltext search condition.
+     * Get the fulltext search conditions, if any.
      *
-     * @return the condition, or null if not used
+     * @return the conditions (an empty collection if not used)
      */
-    String getFulltextCondition();
+    Collection<String> getFulltextConditions();
 
     /**
      * Get the property restriction for the given property, if any.

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -25,6 +25,17 @@
 
 sql1 select prop1 from nt:unstructured where prop1 is not null order by prop1 asc
 
+sql1 select * from nt:base where jcr:path like '/testroot/%' and birth > timestamp '1976-01-01t00:00:00.000+01:00'
+
+sql1 select * from nt:base where jcr:path like '/testroot/%' and value like 'foo\_bar' escape
'\'
+
+sql1 select * from nt:unstructured where "jcr:path" = '/testroot/foo' and contains(., 'fox')
+
+sql1 select * from nt:unstructured where "jcr:path" like '/testroot/%' and contains(., 'fox
test')
+
+# not supported currently
+# sql1 select [jcr:path], [jcr:score], * from [nt:base] where (0 is not null) and isdescendantnode('/testroot')
+
 # test multi-valued properties
 
 commit / + "test": { "a": { "name": ["Hello", "World" ] }, "b": { "name" : "Hello" }}

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=1373284&r1=1373283&r2=1373284&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
Wed Aug 15 09:23:38 2012
@@ -18,6 +18,61 @@
 # * lines starting with "xpath" are xpath queries, followed by expected sql2 query
 # * use ascii character only
 
+# jackrabbit test queries
+
+xpath /jcr:root/testroot/*[jcr:contains(@jcr:content, 'lazy')]
+select [jcr:path], [jcr:score], * from [nt:base] where contains([jcr:content], 'lazy') and
ischildnode('/testroot')
+
+# TODO is the @ before jcr:content not needed, if not why?
+xpath /jcr:root/testroot/*[jcr:contains(jcr:content, 'lazy')]
+invalid: Query: /jcr:root/testroot/*[jcr:contains(jcr:content,(*)'lazy')]; expected: (
+
+xpath /jcr:root/testroot/*[@prop1 = 1 and jcr:like(fn:name(), 'F%')]
+select [jcr:path], [jcr:score], * from [nt:base] where (([prop1] = 1) and (name() like 'F%'))
and ischildnode('/testroot')
+
+# TODO support rep:excerpt() and rep:similar()? how?
+xpath /jcr:root/testroot/*[jcr:contains(., 'jackrabbit')]/rep:excerpt(.)
+invalid: Query: /jcr:root/testroot/*[jcr:contains(., 'jackrabbit')]/rep:excerpt((*).); expected:
<end>
+
+xpath /jcr:root/testroot//child/..[@foo1]
+invalid: Query: /jcr:root/testroot//child/.(*).[@foo1]; expected: non-path condition
+
+xpath //testroot/*[@jcr:primaryType='nt:unstructured' and fn:not(@mytext)]
+invalid: Query: //testroot/*(*)[@jcr:primaryType='nt:unstructured' and fn:not(@mytext)];
expected: non-path condition
+
+xpath /jcr:root/testroot/people/jcr:deref(@worksfor, '*')
+invalid: Query: /jcr:root/testroot/people/jcr:deref((*)@worksfor, '*'); expected: <end>
+
+xpath /jcr:root[@foo = 'does-not-exist']
+select [jcr:path], [jcr:score], * from [nt:base] where ([foo] = 'does-not-exist') and isdescendantnode('/')
+
+xpath //*[@jcr:primaryType='nt:unstructured' and jcr:like(@foo,"%ar'ba%")]
+select [jcr:path], [jcr:score], * from [nt:base] where ([jcr:primaryType] = 'nt:unstructured')
and ([foo] like '%ar''ba%')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) = 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) = 'foo') and ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) != 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) <> 'foo') and
ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) <= 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) <= 'foo') and ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) >= 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) >= 'foo') and ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) < 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) < 'foo') and ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) > 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) > 'foo') and ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[fn:lower-case(@prop1) <> 'foo']
+select [jcr:path], [jcr:score], * from [nt:base] where (lower([prop1]) <> 'foo') and
ischildnode('/testroot')
+
+xpath /jcr:root/testroot/*[@prop1 = 1 and fn:name() = 'node1']
+select [jcr:path], [jcr:score], * from [nt:base] where (([prop1] = 1) and (name() = 'node1'))
and ischildnode('/testroot')
+
 # sling queries
 
 xpath //element(*,mix:language)[fn:lower-case(@jcr:language)='en']//element(*,sling:Message)[@sling:message]/(@sling:key|@sling:message)



Mime
View raw message