You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/03/31 15:33:11 UTC

svn commit: r159585 - in incubator/jackrabbit/trunk/src: grammar/sql/ java/org/apache/jackrabbit/core/search/ java/org/apache/jackrabbit/core/search/lucene/ java/org/apache/jackrabbit/core/search/sql/ test/org/apache/jackrabbit/core/search/

Author: mreutegg
Date: Thu Mar 31 05:33:09 2005
New Revision: 159585

URL: http://svn.apache.org/viewcvs?view=rev&rev=159585
Log:
Changed semantics of SQL operators: <, >, <=, >=, <>, = to general comparison.

Modified:
    incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryConstants.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/search/SimpleQueryTest.java

Modified: incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt (original)
+++ incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt Thu Mar 31 05:33:09 2005
@@ -303,11 +303,11 @@
 {
   (
     (
-      identifier = Identifier() { jjtThis.setIdentifier(identifier); } ( <PERIOD> identifier = Identifier() { jjtThis.setIdentifier(identifier); } )?
+      identifier = Identifier() { jjtThis.setIdentifier(identifier); } ( <PERIOD> identifier = Identifier() { Node n = jjtree.popNode(); jjtree.popNode(); jjtree.pushNode(n); jjtThis.setIdentifier(identifier); } )?
       (
         (
           operationType = ComparisonOperation() { jjtThis.setOperationType(operationType); }
-          (Literal() | (identifier = Identifier() { jjtThis.setIdentifier(identifier); } ( <PERIOD> identifier = Identifier() { jjtThis.setIdentifier(identifier); } )? ) )
+          (Literal() | (identifier = Identifier() { jjtThis.setIdentifier(identifier); } ( <PERIOD> identifier = Identifier() { Node n = jjtree.popNode(); jjtree.popNode(); jjtree.pushNode(n); jjtThis.setIdentifier(identifier); } )? ) )
         )
       |
         ((<NOT> { jjtThis.setNegate(true); })?
@@ -355,12 +355,12 @@
 }
 {
   (
-      <EQ_OPERATOR> { operationType = QueryConstants.OPERATION_EQ_VALUE; }
-    | <NE_OPERATOR> { operationType = QueryConstants.OPERATION_NE_VALUE; }
-    | <LT_OPERATOR> { operationType = QueryConstants.OPERATION_LT_VALUE; }
-    | <GT_OPERATOR> { operationType = QueryConstants.OPERATION_GT_VALUE; }
-    | <LE_OPERATOR> { operationType = QueryConstants.OPERATION_LE_VALUE; }
-    | <GE_OPERATOR> { operationType = QueryConstants.OPERATION_GE_VALUE; }
+      <EQ_OPERATOR> { operationType = QueryConstants.OPERATION_EQ_GENERAL; }
+    | <NE_OPERATOR> { operationType = QueryConstants.OPERATION_NE_GENERAL; }
+    | <LT_OPERATOR> { operationType = QueryConstants.OPERATION_LT_GENERAL; }
+    | <GT_OPERATOR> { operationType = QueryConstants.OPERATION_GT_GENERAL; }
+    | <LE_OPERATOR> { operationType = QueryConstants.OPERATION_LE_GENERAL; }
+    | <GE_OPERATOR> { operationType = QueryConstants.OPERATION_GE_GENERAL; }
   )
   {
     return operationType;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryConstants.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryConstants.java?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryConstants.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryConstants.java Thu Mar 31 05:33:09 2005
@@ -86,61 +86,85 @@
      * equal operation: =
      * general comparison
      */
-    public static int OPERATION_EQ_GENERAL = OPERATIONS + 2;
+    public static int OPERATION_EQ_GENERAL = OPERATION_EQ_VALUE + 1;
 
     /**
      * not equal operation: <>
      */
-    public static int OPERATION_NE_VALUE = OPERATIONS + 3;
+    public static int OPERATION_NE_VALUE = OPERATION_EQ_GENERAL + 1;
 
     /**
      * not equal operation: <>
      * general comparision
      */
-    public static int OPERATION_NE_GENERAL = OPERATIONS + 4;
+    public static int OPERATION_NE_GENERAL = OPERATION_NE_VALUE + 1;
 
     /**
      * less than operation: &lt;
      */
-    public static int OPERATION_LT_VALUE = OPERATIONS + 5;
+    public static int OPERATION_LT_VALUE = OPERATION_NE_GENERAL + 1;
+
+    /**
+     * less than operation: &lt;
+     * general comparison
+     */
+    public static int OPERATION_LT_GENERAL = OPERATION_LT_VALUE + 1;
 
     /**
      * greater than operation: >
      */
-    public static int OPERATION_GT_VALUE = OPERATIONS + 6;
+    public static int OPERATION_GT_VALUE = OPERATION_LT_GENERAL + 1;
+
+    /**
+     * greater than operation: >
+     * general comparision
+     */
+    public static int OPERATION_GT_GENERAL = OPERATION_GT_VALUE + 1;
 
     /**
      * greater or equal operation: >=
      */
-    public static int OPERATION_GE_VALUE = OPERATIONS + 7;
+    public static int OPERATION_GE_VALUE = OPERATION_GT_GENERAL + 1;
+
+    /**
+     * greater or equal operation: >=
+     * general comparison
+     */
+    public static int OPERATION_GE_GENERAL = OPERATION_GE_VALUE + 1;
+
+    /**
+     * less than or equal operation: <=
+     */
+    public static int OPERATION_LE_VALUE = OPERATION_GE_GENERAL + 1;
 
     /**
      * less than or equal operation: <=
+     * general comparison
      */
-    public static int OPERATION_LE_VALUE = OPERATIONS + 8;
+    public static int OPERATION_LE_GENERAL = OPERATION_LE_VALUE + 1;
 
     /**
      * like operation: identifier LIKE string_literal
      */
-    public static int OPERATION_LIKE = OPERATIONS + 9;
+    public static int OPERATION_LIKE = OPERATION_LE_GENERAL + 1;
 
     /**
      * between operation: identifier [ NOT ] BETWEEN literal AND literal
      */
-    public static int OPERATION_BETWEEN = OPERATIONS + 10;
+    public static int OPERATION_BETWEEN = OPERATION_LIKE + 1;
 
     /**
      * on operation: identifier [ NOT ] IN ( literal {, literal}* )
      */
-    public static int OPERATION_IN = OPERATIONS + 11;
+    public static int OPERATION_IN = OPERATION_BETWEEN + 1;
 
     /**
      * is null operation: identifier IS NULL
      */
-    public static int OPERATION_NULL = OPERATIONS + 12;
+    public static int OPERATION_NULL = OPERATION_IN + 1;
 
     /**
      * is not null operation: identifier IS NOT NULL
      */
-    public static int OPERATION_NOT_NULL = OPERATIONS + 13;
+    public static int OPERATION_NOT_NULL = OPERATION_NULL + 1;
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java Thu Mar 31 05:33:09 2005
@@ -310,10 +310,10 @@
             // replace unescaped ' with " and escaped ' with just '
             StringBuffer query = new StringBuffer();
             String textsearch = node.getQuery();
-            // the default lucene query parser recognizes 'AND', 'OR' and
-            // 'NOT' as keywords. when the whole statement is lowercased, this
-            // will not happen ;)
-            textsearch = textsearch.toLowerCase();
+            // the default lucene query parser recognizes 'AND' and 'NOT' as
+            // keywords.
+            textsearch = textsearch.replaceAll("AND", "and");
+            textsearch = textsearch.replaceAll("NOT", "not");
             boolean escaped = false;
             for (int i = 0; i < textsearch.length(); i++) {
                 if (textsearch.charAt(i) == '\\') {
@@ -568,6 +568,15 @@
                     query = or;
                 }
                 break;
+            case QueryConstants.OPERATION_GE_GENERAL:   // >=
+                // search in single and multi valued properties
+                or = new BooleanQuery();
+                for (int i = 0; i < stringValues.length; i++) {
+                    or.add(new RangeQuery(new Term(field, stringValues[i]), null, true), false, false);
+                    or.add(new RangeQuery(new Term(mvpField, stringValues[i]), null, true), false, false);
+                }
+                query = or;
+                break;
             case QueryConstants.OPERATION_GT_VALUE:      // >
                 if (stringValues.length == 1) {
                     query = new RangeQuery(new Term(field, stringValues[0]), null, false);
@@ -579,6 +588,14 @@
                     query = or;
                 }
                 break;
+            case QueryConstants.OPERATION_GT_GENERAL:      // >
+                or = new BooleanQuery();
+                for (int i = 0; i < stringValues.length; i++) {
+                    or.add(new RangeQuery(new Term(field, stringValues[i]), null, false), false, false);
+                    or.add(new RangeQuery(new Term(mvpField, stringValues[i]), null, false), false, false);
+                }
+                query = or;
+                break;
             case QueryConstants.OPERATION_LE_VALUE:      // <=
                 if (stringValues.length == 1) {
                     query = new RangeQuery(null, new Term(field, stringValues[0]), true);
@@ -590,6 +607,14 @@
                     query = or;
                 }
                 break;
+            case QueryConstants.OPERATION_LE_GENERAL:      // <=
+                or = new BooleanQuery();
+                for (int i = 0; i < stringValues.length; i++) {
+                    or.add(new RangeQuery(null, new Term(field, stringValues[i]), true), false, false);
+                    or.add(new RangeQuery(null, new Term(mvpField, stringValues[i]), true), false, false);
+                }
+                query = or;
+                break;
             case QueryConstants.OPERATION_LIKE:          // LIKE
                 // the like operation always has one string value.
                 // no coercing, see above
@@ -609,6 +634,14 @@
                     }
                     query = or;
                 }
+                break;
+            case QueryConstants.OPERATION_LT_GENERAL:      // <
+                or = new BooleanQuery();
+                for (int i = 0; i < stringValues.length; i++) {
+                    or.add(new RangeQuery(null, new Term(field, stringValues[i]), false), false, false);
+                    or.add(new RangeQuery(null, new Term(mvpField, stringValues[i]), false), false, false);
+                }
+                query = or;
                 break;
             case QueryConstants.OPERATION_NE_VALUE:      // !=
                 BooleanQuery notQuery = new BooleanQuery();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java Thu Mar 31 05:33:09 2005
@@ -232,24 +232,33 @@
         NAryQueryNode parent = (NAryQueryNode) data;
 
         int type = node.getOperationType();
-        QueryNode predicateNode = null;
+        QueryNode predicateNode;
 
         try {
-            final QName[] tmp = new QName[1];
+            final QName[] tmp = new QName[2];
+            final ASTLiteral[] value = new ASTLiteral[1];
             node.childrenAccept(new DefaultParserVisitor() {
                 public Object visit(ASTIdentifier node, Object data) {
-                    // only assign first identifier
-                    tmp[0] = (tmp[0] == null) ? node.getName() : tmp[0];
+                    if (tmp[0] == null) {
+                        tmp[0] = node.getName();
+                    } else if (tmp[1] == null) {
+                        tmp[1] = node.getName();
+                    }
+                    return data;
+                }
+
+                public Object visit(ASTLiteral node, Object data) {
+                    value[0] = node;
                     return data;
                 }
             }, data);
             QName identifier = tmp[0];
 
             if (identifier.equals(QueryConstants.JCR_PATH)) {
-                if (node.children[1] instanceof ASTIdentifier) {
+                if (tmp[1] != null) {
                     // simply ignore, this is a join of a mixin node type
                 } else {
-                    createPathQuery(((ASTLiteral) node.children[1]).getValue(), parent.getType());
+                    createPathQuery(value[0].getValue(), parent.getType());
                 }
                 // done
                 return data;
@@ -258,32 +267,22 @@
             if (type == QueryConstants.OPERATION_BETWEEN) {
                 AndQueryNode between = new AndQueryNode(parent);
                 RelationQueryNode rel = createRelationQueryNode(between,
-                        identifier, QueryConstants.OPERATION_GE_VALUE, (ASTLiteral) node.children[1]);
+                        identifier, QueryConstants.OPERATION_GE_GENERAL, (ASTLiteral) node.children[1]);
                 between.addOperand(rel);
                 rel = createRelationQueryNode(between,
-                        identifier, QueryConstants.OPERATION_LE_VALUE, (ASTLiteral) node.children[2]);
+                        identifier, QueryConstants.OPERATION_LE_GENERAL, (ASTLiteral) node.children[2]);
                 between.addOperand(rel);
                 predicateNode = between;
-            } else if (type == QueryConstants.OPERATION_EQ_VALUE) {
-                if (node.children[1] instanceof ASTIdentifier) {
-                    // simply ignore, this is a join of a mixin node type
-                } else {
-                    predicateNode = createRelationQueryNode(parent,
-                            identifier, type, (ASTLiteral) node.children[1]);
-                }
-            } else if (type == QueryConstants.OPERATION_GE_VALUE
-                    || type == QueryConstants.OPERATION_GT_VALUE
-                    || type == QueryConstants.OPERATION_LE_VALUE
-                    || type == QueryConstants.OPERATION_LT_VALUE
-                    || type == QueryConstants.OPERATION_NE_VALUE) {
-                predicateNode = createRelationQueryNode(parent,
-                        identifier, type, (ASTLiteral) node.children[1]);
-            } else if (type == QueryConstants.OPERATION_EQ_GENERAL
-                    || type == QueryConstants.OPERATION_NE_GENERAL) {
+            } else if (type == QueryConstants.OPERATION_GE_GENERAL
+                    || type == QueryConstants.OPERATION_GT_GENERAL
+                    || type == QueryConstants.OPERATION_LE_GENERAL
+                    || type == QueryConstants.OPERATION_LT_GENERAL
+                    || type == QueryConstants.OPERATION_NE_GENERAL
+                    || type == QueryConstants.OPERATION_EQ_GENERAL) {
                 predicateNode = createRelationQueryNode(parent,
-                        identifier, type, (ASTLiteral) node.children[0]);
+                        identifier, type, value[0]);
             } else if (type == QueryConstants.OPERATION_LIKE) {
-                ASTLiteral pattern = (ASTLiteral) node.children[1];
+                ASTLiteral pattern = value[0];
                 if (node.getEscapeString() != null) {
                     if (node.getEscapeString().length() == 1) {
                         // backslash is the escape character we use internally

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java Thu Mar 31 05:33:09 2005
@@ -361,23 +361,19 @@
     public Object visit(RelationQueryNode node, Object data) {
         StringBuffer sb = (StringBuffer) data;
         try {
-            if (node.getOperation() == OPERATION_EQ_VALUE) {
+            if (node.getOperation() == OPERATION_EQ_VALUE || node.getOperation() == OPERATION_EQ_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" = ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_EQ_GENERAL) {
-                appendValue(node, sb);
-                sb.append(" IN ");
-                appendName(node.getProperty(), resolver, sb);
-            } else if (node.getOperation() == OPERATION_GE_VALUE) {
+            } else if (node.getOperation() == OPERATION_GE_VALUE || node.getOperation() == OPERATION_GE_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" >= ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_GT_VALUE) {
+            } else if (node.getOperation() == OPERATION_GT_VALUE || node.getOperation() == OPERATION_GT_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" > ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_LE_VALUE) {
+            } else if (node.getOperation() == OPERATION_LE_VALUE || node.getOperation() == OPERATION_LE_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" <= ");
                 appendValue(node, sb);
@@ -385,18 +381,14 @@
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" LIKE ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_LT_VALUE) {
+            } else if (node.getOperation() == OPERATION_LT_VALUE || node.getOperation() == OPERATION_LT_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" < ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_NE_VALUE) {
+            } else if (node.getOperation() == OPERATION_NE_VALUE || node.getOperation() == OPERATION_NE_GENERAL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" <> ");
                 appendValue(node, sb);
-            } else if (node.getOperation() == OPERATION_NE_GENERAL) {
-                appendValue(node, sb);
-                sb.append(" NOT IN ");
-                appendName(node.getProperty(), resolver, sb);
             } else if (node.getOperation() == OPERATION_NULL) {
                 appendName(node.getProperty(), resolver, sb);
                 sb.append(" IS NULL");

Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/search/SimpleQueryTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/search/SimpleQueryTest.java?view=diff&r1=159584&r2=159585
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/search/SimpleQueryTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/search/SimpleQueryTest.java Thu Mar 31 05:33:09 2005
@@ -368,11 +368,12 @@
         result = q.execute();
         checkResult(result, 3); // foo, bar, bla
 
+        // the text = 'foo' is now also a general comparison
         sql = "SELECT * FROM nt:unstructured WHERE text = 'foo' " +
                 "and jcr:path LIKE '" + testRoot + "/%'";
         q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
         result = q.execute();
-        checkResult(result, 2); // bar, bla
+        checkResult(result, 3); // foo, bar, bla
 
         xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured' and @text eq 'foo']";
         q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH);