You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2012/04/04 21:32:07 UTC

svn commit: r1309561 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/access/trans/ main/java/org/apache/cayenne/exp/ main/java/org/apache/cayenne/exp/parser/ main/java/org/apache/cayenne/util/ test/java/o...

Author: aadamchik
Date: Wed Apr  4 19:32:06 2012
New Revision: 1309561

URL: http://svn.apache.org/viewvc?rev=1309561&view=rev
Log:
Merge branch 'CAY-1693' into mm

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/QualifierTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/Expression.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ConversionUtil.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/SelectQueryTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/MySQLUnitDbAdapter.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/UnitDbAdapter.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/QualifierTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/QualifierTranslator.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/QualifierTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/QualifierTranslator.java Wed Apr  4 19:32:06 2012
@@ -53,7 +53,7 @@ public class QualifierTranslator extends
 
     public QualifierTranslator(QueryAssembler queryAssembler) {
         super(queryAssembler);
-        
+
         caseInsensitive = false;
     }
 
@@ -67,7 +67,7 @@ public class QualifierTranslator extends
     protected void doAppendPart() throws IOException {
         doAppendPart(extractQualifier());
     }
-    
+
     public void setCaseInsensitive(boolean caseInsensitive) {
         this.caseInsensitive = caseInsensitive;
     }
@@ -299,6 +299,15 @@ public class QualifierTranslator extends
                     else if (childIndex == 1)
                         out.append(" AND ");
                     break;
+                case Expression.BITWISE_OR:
+                    out.append(" ").append(operandForBitwiseOr()).append(" ");
+                    break;
+                case Expression.BITWISE_AND:
+                    out.append(" ").append(operandForBitwiseAnd()).append(" ");
+                    break;
+                case Expression.BITWISE_XOR:
+                    out.append(" ").append(operandForBitwiseXor()).append(" ");
+                    break;
             }
         }
         catch (IOException ioex) {
@@ -311,6 +320,34 @@ public class QualifierTranslator extends
         }
     }
 
+    /**
+     * @since 3.1
+     */
+    protected String operandForBitwiseNot() {
+        return "~";
+    }
+
+    /**
+     * @since 3.1
+     */
+    protected String operandForBitwiseOr() {
+        return "|";
+    }
+
+    /**
+     * @since 3.1
+     */
+    protected String operandForBitwiseAnd() {
+        return "&";
+    }
+    
+    /**
+     * @since 3.1
+     */
+    protected String operandForBitwiseXor() {
+        return "^";
+    }
+
     public void startNode(Expression node, Expression parentNode) {
         int count = node.getOperandCount();
 
@@ -343,9 +380,11 @@ public class QualifierTranslator extends
                 // qualBuf.append('+');
                 else if (node.getType() == Expression.NOT)
                     out.append("NOT ");
+                else if (node.getType() == Expression.BITWISE_NOT) {
+                    out.append(operandForBitwiseNot());
+                }
             }
-            else if ((node.getType() == Expression.LIKE_IGNORE_CASE
-                    || node.getType() == Expression.NOT_LIKE_IGNORE_CASE)
+            else if ((node.getType() == Expression.LIKE_IGNORE_CASE || node.getType() == Expression.NOT_LIKE_IGNORE_CASE)
                     && !caseInsensitive) {
                 out.append("UPPER(");
             }
@@ -375,10 +414,10 @@ public class QualifierTranslator extends
 
             if (parenthesisNeeded)
                 out.append(')');
-            
+
             if (isPatternMatchNode && !likeIgnoreCase)
                 appendLikeEscapeCharacter((PatternMatchNode) node);
-            
+
             if (likeIgnoreCase && !caseInsensitive)
                 out.append(')');
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/Expression.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/Expression.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/Expression.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/Expression.java Wed Apr  4 19:32:06 2012
@@ -118,6 +118,26 @@ public abstract class Expression impleme
     public static final int NOT_IN = 36;
     public static final int NOT_LIKE = 37;
     public static final int NOT_LIKE_IGNORE_CASE = 38;
+    
+    /**
+     * @since 3.1
+     */
+    public static final int BITWISE_NOT = 39;
+    
+    /**
+     * @since 3.1
+     */
+    public static final int BITWISE_AND = 40;
+    
+    /**
+     * @since 3.1
+     */
+    public static final int BITWISE_OR = 41;
+    
+    /**
+     * @since 3.1
+     */
+    public static final int BITWISE_XOR = 42;
 
     private static final int PARSE_BUFFER_MAX_SIZE = 4096;
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java Wed Apr  4 19:32:06 2012
@@ -29,6 +29,10 @@ import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.parser.ASTAdd;
 import org.apache.cayenne.exp.parser.ASTAnd;
 import org.apache.cayenne.exp.parser.ASTBetween;
+import org.apache.cayenne.exp.parser.ASTBitwiseAnd;
+import org.apache.cayenne.exp.parser.ASTBitwiseNot;
+import org.apache.cayenne.exp.parser.ASTBitwiseOr;
+import org.apache.cayenne.exp.parser.ASTBitwiseXor;
 import org.apache.cayenne.exp.parser.ASTDbPath;
 import org.apache.cayenne.exp.parser.ASTDivide;
 import org.apache.cayenne.exp.parser.ASTEqual;
@@ -60,7 +64,6 @@ import org.apache.cayenne.map.Entity;
 /**
  * Helper class to build expressions. Alternatively expressions can be built using
  * {@link org.apache.cayenne.exp.Expression#fromString(String)} method.
- * 
  */
 public class ExpressionFactory {
 
@@ -88,7 +91,9 @@ public class ExpressionFactory {
                 Expression.MULTIPLY, Expression.DIVIDE, Expression.NEGATIVE,
                 Expression.OBJ_PATH, Expression.DB_PATH, Expression.LIST,
                 Expression.NOT_BETWEEN, Expression.NOT_IN, Expression.NOT_LIKE,
-                Expression.NOT_LIKE_IGNORE_CASE, Expression.TRUE, Expression.FALSE
+                Expression.NOT_LIKE_IGNORE_CASE, Expression.TRUE, Expression.FALSE,
+                Expression.BITWISE_NOT, Expression.BITWISE_AND, Expression.BITWISE_OR,
+                Expression.BITWISE_XOR
         };
 
         int max = 0;
@@ -143,6 +148,11 @@ public class ExpressionFactory {
 
         typeLookup[Expression.TRUE] = ASTTrue.class;
         typeLookup[Expression.FALSE] = ASTFalse.class;
+
+        typeLookup[Expression.BITWISE_NOT] = ASTBitwiseNot.class;
+        typeLookup[Expression.BITWISE_OR] = ASTBitwiseOr.class;
+        typeLookup[Expression.BITWISE_AND] = ASTBitwiseAnd.class;
+        typeLookup[Expression.BITWISE_XOR] = ASTBitwiseXor.class;
     }
 
     /**
@@ -190,9 +200,9 @@ public class ExpressionFactory {
     /**
      * Creates an expression that matches any of the key-values pairs in <code>map</code>.
      * <p>
-     * For each pair <code>pairType</code> operator is used to build a binary
-     * expression. Key is considered to be a DB_PATH expression. OR is used to join pair
-     * binary expressions.
+     * For each pair <code>pairType</code> operator is used to build a binary expression.
+     * Key is considered to be a DB_PATH expression. OR is used to join pair binary
+     * expressions.
      */
     public static Expression matchAnyDbExp(Map<String, ?> map, int pairType) {
         List<Expression> pairs = new ArrayList<Expression>(map.size());
@@ -210,9 +220,9 @@ public class ExpressionFactory {
     /**
      * Creates an expression that matches all key-values pairs in <code>map</code>.
      * <p>
-     * For each pair <code>pairType</code> operator is used to build a binary
-     * expression. Key is considered to be a DB_PATH expression. AND is used to join pair
-     * binary expressions.
+     * For each pair <code>pairType</code> operator is used to build a binary expression.
+     * Key is considered to be a DB_PATH expression. AND is used to join pair binary
+     * expressions.
      */
     public static Expression matchAllDbExp(Map<String, ?> map, int pairType) {
         List<Expression> pairs = new ArrayList<Expression>(map.size());
@@ -231,9 +241,9 @@ public class ExpressionFactory {
      * Creates an expression that matches any of the key-values pairs in the
      * <code>map</code>.
      * <p>
-     * For each pair <code>pairType</code> operator is used to build a binary
-     * expression. Key is considered to be a OBJ_PATH expression. OR is used to join pair
-     * binary expressions.
+     * For each pair <code>pairType</code> operator is used to build a binary expression.
+     * Key is considered to be a OBJ_PATH expression. OR is used to join pair binary
+     * expressions.
      */
     public static Expression matchAnyExp(Map<String, ?> map, int pairType) {
         List<Expression> pairs = new ArrayList<Expression>(map.size());
@@ -251,8 +261,7 @@ public class ExpressionFactory {
 
     /**
      * Creates an expression to match a collection of values against a single path
-     * expression.
-     * <h3>Splits</h3>
+     * expression. <h3>Splits</h3>
      * <p>
      * Note that "path" argument here can use a split character (a pipe symbol - '|')
      * instead of dot to indicate that relationship following a path should be split into
@@ -332,9 +341,9 @@ public class ExpressionFactory {
     /**
      * Creates an expression that matches all key-values pairs in <code>map</code>.
      * <p>
-     * For each pair <code>pairType</code> operator is used to build a binary
-     * expression. Key is considered to be a OBJ_PATH expression. AND is used to join pair
-     * binary expressions.
+     * For each pair <code>pairType</code> operator is used to build a binary expression.
+     * Key is considered to be a OBJ_PATH expression. AND is used to join pair binary
+     * expressions.
      */
     public static Expression matchAllExp(Map<String, ?> map, int pairType) {
         List<Expression> pairs = new ArrayList<Expression>(map.size());
@@ -576,19 +585,21 @@ public class ExpressionFactory {
     }
 
     /**
-     * <p>A convenience shortcut for building LIKE expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building LIKE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
     public static Expression likeExp(String pathSpec, Object value, char escapeChar) {
         return new ASTLike(new ASTObjPath(pathSpec), value, escapeChar);
     }
-    
+
     /**
      * A convenience shortcut for building LIKE DB_PATH expression.
      * 
@@ -599,33 +610,37 @@ public class ExpressionFactory {
     }
 
     /**
-     * <p>A convenience shortcut for building LIKE DB_PATH expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building LIKE DB_PATH expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
     public static Expression likeDbExp(String pathSpec, Object value, char escapeChar) {
-        return new ASTLike(new ASTDbPath(pathSpec), value,escapeChar);
+        return new ASTLike(new ASTDbPath(pathSpec), value, escapeChar);
     }
-    
+
     /**
      * A convenience shortcut for building NOT_LIKE expression.
      */
     public static Expression notLikeExp(String pathSpec, Object value) {
         return new ASTNotLike(new ASTObjPath(pathSpec), value);
     }
-    
+
     /**
-     * <p>A convenience shortcut for building NOT_LIKE expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building NOT_LIKE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
@@ -641,14 +656,16 @@ public class ExpressionFactory {
     public static Expression notLikeDbExp(String pathSpec, Object value) {
         return new ASTNotLike(new ASTDbPath(pathSpec), value);
     }
-    
+
     /**
-     * <p>A convenience shortcut for building NOT_LIKE expression.</p>
-     *
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building NOT_LIKE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
@@ -664,19 +681,24 @@ public class ExpressionFactory {
     }
 
     /**
-     * <p>A convenience shortcut for building LIKE_IGNORE_CASE expression.</p>
-     *
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building LIKE_IGNORE_CASE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
-    public static Expression likeIgnoreCaseExp(String pathSpec, Object value, char escapeChar) {
+    public static Expression likeIgnoreCaseExp(
+            String pathSpec,
+            Object value,
+            char escapeChar) {
         return new ASTLikeIgnoreCase(new ASTObjPath(pathSpec), value, escapeChar);
     }
-    
+
     /**
      * A convenience shortcut for building LIKE_IGNORE_CASE expression.
      * 
@@ -685,18 +707,23 @@ public class ExpressionFactory {
     public static Expression likeIgnoreCaseDbExp(String pathSpec, Object value) {
         return new ASTLikeIgnoreCase(new ASTDbPath(pathSpec), value);
     }
-    
+
     /**
-     * <p>A convenience shortcut for building LIKE_IGNORE_CASE expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building LIKE_IGNORE_CASE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
-    public static Expression likeIgnoreCaseDbExp(String pathSpec, Object value, char escapeChar) {
+    public static Expression likeIgnoreCaseDbExp(
+            String pathSpec,
+            Object value,
+            char escapeChar) {
         return new ASTLikeIgnoreCase(new ASTDbPath(pathSpec), value, escapeChar);
     }
 
@@ -708,19 +735,24 @@ public class ExpressionFactory {
     }
 
     /**
-     * <p>A convenience shortcut for building NOT_LIKE_IGNORE_CASE expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building NOT_LIKE_IGNORE_CASE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
-     */ 
-    public static Expression notLikeIgnoreCaseExp(String pathSpec, Object value, char escapeChar) {
+     */
+    public static Expression notLikeIgnoreCaseExp(
+            String pathSpec,
+            Object value,
+            char escapeChar) {
         return new ASTNotLikeIgnoreCase(new ASTObjPath(pathSpec), value, escapeChar);
     }
-    
+
     /**
      * A convenience shortcut for building NOT_LIKE_IGNORE_CASE expression.
      * 
@@ -731,19 +763,24 @@ public class ExpressionFactory {
     }
 
     /**
-     * <p>A convenience shortcut for building NOT_LIKE_IGNORE_CASE expression.</p>
-     * 
-     * <p>The escape character allows for escaping meta-characters
-     * in the LIKE clause.  Note that the escape character cannot
-     * be '?'.  To specify no escape character, supply 0 as the
-     * escape character.</p>
+     * <p>
+     * A convenience shortcut for building NOT_LIKE_IGNORE_CASE expression.
+     * </p>
+     * <p>
+     * The escape character allows for escaping meta-characters in the LIKE clause. Note
+     * that the escape character cannot be '?'. To specify no escape character, supply 0
+     * as the escape character.
+     * </p>
      * 
      * @since 3.0.1
      */
-    public static Expression notLikeIgnoreCaseDbExp(String pathSpec, Object value, char escapeChar) {
+    public static Expression notLikeIgnoreCaseDbExp(
+            String pathSpec,
+            Object value,
+            char escapeChar) {
         return new ASTNotLikeIgnoreCase(new ASTDbPath(pathSpec), value, escapeChar);
     }
-    
+
     /**
      * A convenience shortcut for boolean true expression.
      * 
@@ -788,7 +825,7 @@ public class ExpressionFactory {
         }
         return exp;
     }
-    
+
     /**
      * Creates an expression that matches the primary key of object in
      * <code>ObjectId</code>'s <code>IdSnapshot</code> for the argument
@@ -806,10 +843,10 @@ public class ExpressionFactory {
         if (objects == null || objects.size() == 0) {
             return expFalse();
         }
-        
+
         return matchAnyExp(objects.toArray(new Persistent[objects.size()]));
-    } 
-    
+    }
+
     /**
      * Creates an expression that matches any of the objects contained in the
      * <code>objects</code> array
@@ -818,7 +855,7 @@ public class ExpressionFactory {
         if (objects == null || objects.length == 0) {
             return expFalse();
         }
-        
+
         List<Expression> pairs = new ArrayList<Expression>(objects.length);
 
         for (Persistent object : objects) {

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java?rev=1309561&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java Wed Apr  4 19:32:06 2012
@@ -0,0 +1,92 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 3.1
+ */
+public class ASTBitwiseAnd extends SimpleNode {
+
+    ASTBitwiseAnd(int id) {
+        super(id);
+    }
+
+    public ASTBitwiseAnd() {
+
+        // TODO: parser support
+        super(-1);
+    }
+
+    public ASTBitwiseAnd(SimpleNode left, SimpleNode right) {
+        // TODO: parser support
+        super(-1);
+
+        jjtAddChild(left, 0);
+        jjtAddChild(right, 1);
+        connectChildren();
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        int len = jjtGetNumChildren();
+        if (len != 2) {
+            return Boolean.FALSE;
+        }
+
+        long result = Long.MIN_VALUE;
+        for (int i = 0; i < len; i++) {
+            long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+
+            if (value == Long.MIN_VALUE) {
+                return null;
+            }
+
+            result = (i == 0) ? value : result & value;
+        }
+
+        return result;
+    }
+
+    /**
+     * Creates a copy of this expression node, without copying children.
+     */
+    @Override
+    public Expression shallowCopy() {
+        return new ASTBitwiseAnd(id);
+    }
+
+    @Override
+    protected String getExpressionOperator(int index) {
+        return "|";
+    }
+
+    @Override
+    protected String getEJBQLExpressionOperator(int index) {
+        throw new UnsupportedOperationException("EJBQL 'bitwise and' is not supported");
+    }
+
+    @Override
+    public int getType() {
+        return Expression.BITWISE_AND;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java?rev=1309561&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java Wed Apr  4 19:32:06 2012
@@ -0,0 +1,85 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 3.1
+ */
+public class ASTBitwiseNot extends SimpleNode {
+
+    ASTBitwiseNot(int id) {
+        super(id);
+    }
+
+    public ASTBitwiseNot() {
+
+        // TODO: parser support
+        super(-1);
+    }
+
+    public ASTBitwiseNot(SimpleNode expression) {
+        // TODO: parser support
+        super(-1);
+
+        jjtAddChild(expression, 0);
+        connectChildren();
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        int len = jjtGetNumChildren();
+        if (len != 1) {
+            return Boolean.FALSE;
+        }
+
+        long value = ConversionUtil.toLong(evaluateChild(0, o), Long.MIN_VALUE);
+
+        if (value == Long.MIN_VALUE) {
+            return null;
+        }
+
+        return ~value;
+    }
+
+    /**
+     * Creates a copy of this expression node, without copying children.
+     */
+    @Override
+    public Expression shallowCopy() {
+        return new ASTBitwiseNot(id);
+    }
+
+    @Override
+    protected String getExpressionOperator(int index) {
+        return "~";
+    }
+
+    @Override
+    protected String getEJBQLExpressionOperator(int index) {
+        throw new UnsupportedOperationException("EJBQL 'bitwise not' is not supported");
+    }
+
+    @Override
+    public int getType() {
+        return Expression.BITWISE_NOT;
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java?rev=1309561&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java Wed Apr  4 19:32:06 2012
@@ -0,0 +1,92 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 3.1
+ */
+public class ASTBitwiseOr extends SimpleNode {
+
+    ASTBitwiseOr(int id) {
+        super(id);
+    }
+
+    public ASTBitwiseOr() {
+
+        // TODO: parser support
+        super(-1);
+    }
+
+    public ASTBitwiseOr(SimpleNode left, SimpleNode right) {
+        // TODO: parser support
+        super(-1);
+
+        jjtAddChild(left, 0);
+        jjtAddChild(right, 1);
+        connectChildren();
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        int len = jjtGetNumChildren();
+        if (len != 2) {
+            return Boolean.FALSE;
+        }
+
+        long result = Long.MIN_VALUE;
+        for (int i = 0; i < len; i++) {
+            long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+
+            if (value == Long.MIN_VALUE) {
+                return null;
+            }
+
+            result = (i == 0) ? value : result | value;
+        }
+
+        return result;
+    }
+
+    /**
+     * Creates a copy of this expression node, without copying children.
+     */
+    @Override
+    public Expression shallowCopy() {
+        return new ASTBitwiseOr(id);
+    }
+
+    @Override
+    protected String getExpressionOperator(int index) {
+        return "|";
+    }
+
+    @Override
+    protected String getEJBQLExpressionOperator(int index) {
+        throw new UnsupportedOperationException("EJBQL 'bitwise or' is not supported");
+    }
+
+    @Override
+    public int getType() {
+        return Expression.BITWISE_OR;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java?rev=1309561&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java Wed Apr  4 19:32:06 2012
@@ -0,0 +1,92 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 3.1
+ */
+public class ASTBitwiseXor extends SimpleNode {
+
+    ASTBitwiseXor(int id) {
+        super(id);
+    }
+
+    public ASTBitwiseXor() {
+
+        // TODO: parser support
+        super(-1);
+    }
+
+    public ASTBitwiseXor(SimpleNode left, SimpleNode right) {
+        // TODO: parser support
+        super(-1);
+
+        jjtAddChild(left, 0);
+        jjtAddChild(right, 1);
+        connectChildren();
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        int len = jjtGetNumChildren();
+        if (len != 2) {
+            return Boolean.FALSE;
+        }
+
+        long result = Long.MIN_VALUE;
+        for (int i = 0; i < len; i++) {
+            long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+
+            if (value == Long.MIN_VALUE) {
+                return null;
+            }
+
+            result = (i == 0) ? value : result ^ value;
+        }
+
+        return result;
+    }
+
+    /**
+     * Creates a copy of this expression node, without copying children.
+     */
+    @Override
+    public Expression shallowCopy() {
+        return new ASTBitwiseXor(id);
+    }
+
+    @Override
+    protected String getExpressionOperator(int index) {
+        return "^";
+    }
+
+    @Override
+    protected String getEJBQLExpressionOperator(int index) {
+        throw new UnsupportedOperationException("EJBQL 'bitwise xor' is not supported");
+    }
+
+    @Override
+    public int getType() {
+        return Expression.BITWISE_XOR;
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ConversionUtil.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ConversionUtil.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ConversionUtil.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ConversionUtil.java Wed Apr  4 19:32:06 2012
@@ -50,6 +50,28 @@ public final class ConversionUtil {
 
         return defaultValue;
     }
+    
+    /**
+     * @since 3.1
+     */
+    public static long toLong(Object object, long defaultValue) {
+        if (object == null) {
+            return defaultValue;
+        }
+        else if (object instanceof Number) {
+            return ((Number) object).longValue();
+        }
+        else if (object instanceof String) {
+            try {
+                return Long.parseLong((String) object);
+            }
+            catch (NumberFormatException ex) {
+                return defaultValue;
+            }
+        }
+
+        return defaultValue;
+    }
 
     public static boolean toBoolean(Object object) {
         if (object instanceof Boolean) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/SelectQueryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/SelectQueryTest.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/SelectQueryTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/SelectQueryTest.java Wed Apr  4 19:32:06 2012
@@ -30,6 +30,14 @@ import org.apache.cayenne.Persistent;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.parser.ASTBitwiseAnd;
+import org.apache.cayenne.exp.parser.ASTBitwiseNot;
+import org.apache.cayenne.exp.parser.ASTBitwiseOr;
+import org.apache.cayenne.exp.parser.ASTBitwiseXor;
+import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTGreater;
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTScalar;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.ObjEntity;
@@ -42,6 +50,7 @@ import org.apache.cayenne.testdo.testmap
 import org.apache.cayenne.testdo.testmap.Exhibit;
 import org.apache.cayenne.testdo.testmap.Gallery;
 import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.testdo.testmap.ReturnTypesMap1;
 import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -66,9 +75,10 @@ public class SelectQueryTest extends Ser
         dbHelper.deleteAll("ARTIST_GROUP");
         dbHelper.deleteAll("ARTIST");
         dbHelper.deleteAll("CLOB_TEST_RELATION");
-        
+        dbHelper.delete("TYPES_MAPPING_TEST1");
+
         if (accessStackAdapter.supportsLobs()) {
-              dbHelper.deleteAll("CLOB_TEST");
+            dbHelper.deleteAll("CLOB_TEST");
         }
     }
 
@@ -101,6 +111,17 @@ public class SelectQueryTest extends Ser
         tArtist.insert(2, "Y_");
     }
 
+    protected void createNumericsDataSet() throws Exception {
+        TableHelper tNumerics = new TableHelper(dbHelper, "TYPES_MAPPING_TEST1");
+        tNumerics.setColumns("AAAID", "INTEGER_COLUMN");
+
+        tNumerics.insert(1, 0);
+        tNumerics.insert(2, 1);
+        tNumerics.insert(3, 2);
+        tNumerics.insert(4, 3);
+        tNumerics.insert(5, 4);
+    }
+
     public void testFetchLimit() throws Exception {
         createArtistsDataSet();
 
@@ -421,6 +442,99 @@ public class SelectQueryTest extends Ser
         assertEquals(1, objects.size());
     }
 
+    public void testSelectBitwiseNot() throws Exception {
+
+        if (!accessStackAdapter.supportsBitwiseOps()) {
+            return;
+        }
+
+        createNumericsDataSet();
+
+        // to simplify result checking, do double NOT
+        Expression left = new ASTBitwiseNot(new ASTBitwiseNot(new ASTObjPath(
+                ReturnTypesMap1.INTEGER_COLUMN_PROPERTY)));
+        Expression right = new ASTScalar(2);
+        Expression greater = new ASTGreater();
+        greater.setOperand(0, left);
+        greater.setOperand(1, right);
+
+        SelectQuery query = new SelectQuery(ReturnTypesMap1.class);
+        query.setQualifier(greater);
+
+        List<ReturnTypesMap1> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+    }
+    
+    public void testSelectBitwiseOr() throws Exception {
+
+        if (!accessStackAdapter.supportsBitwiseOps()) {
+            return;
+        }
+
+        createNumericsDataSet();
+
+        // to simplify result checking, do double NOT
+        Expression left = new ASTBitwiseOr(new ASTObjPath(
+                ReturnTypesMap1.INTEGER_COLUMN_PROPERTY), new ASTScalar(1));
+        Expression right = new ASTScalar(1);
+        Expression equal = new ASTEqual();
+        equal.setOperand(0, left);
+        equal.setOperand(1, right);
+
+        SelectQuery query = new SelectQuery(ReturnTypesMap1.class);
+        query.setQualifier(equal);
+
+        List<ReturnTypesMap1> objects = context.performQuery(query);
+        assertEquals(2, objects.size());
+    }
+    
+    public void testSelectBitwiseAnd() throws Exception {
+
+        if (!accessStackAdapter.supportsBitwiseOps()) {
+            return;
+        }
+
+        createNumericsDataSet();
+
+        // to simplify result checking, do double NOT
+        Expression left = new ASTBitwiseAnd(new ASTObjPath(
+                ReturnTypesMap1.INTEGER_COLUMN_PROPERTY), new ASTScalar(1));
+        Expression right = new ASTScalar(0);
+        Expression equal = new ASTEqual();
+        equal.setOperand(0, left);
+        equal.setOperand(1, right);
+
+        SelectQuery query = new SelectQuery(ReturnTypesMap1.class);
+        query.setQualifier(equal);
+
+        List<ReturnTypesMap1> objects = context.performQuery(query);
+        assertEquals(3, objects.size());
+    }
+    
+    public void testSelectBitwiseXor() throws Exception {
+
+        if (!accessStackAdapter.supportsBitwiseOps()) {
+            return;
+        }
+
+        createNumericsDataSet();
+
+        // to simplify result checking, do double NOT
+        Expression left = new ASTBitwiseXor(new ASTObjPath(
+                ReturnTypesMap1.INTEGER_COLUMN_PROPERTY), new ASTScalar(1));
+        Expression right = new ASTScalar(5);
+        Expression equal = new ASTEqual();
+        equal.setOperand(0, left);
+        equal.setOperand(1, right);
+
+        SelectQuery query = new SelectQuery(ReturnTypesMap1.class);
+        query.setQualifier(equal);
+
+        List<ReturnTypesMap1> objects = context.performQuery(query);
+        assertEquals(1, objects.size());
+        assertEquals(4, objects.get(0).getIntegerColumn().intValue());
+    }
+
     public void testSelectBooleanNotTrueOr() throws Exception {
         createArtistsDataSet();
         SelectQuery query = new SelectQuery(Artist.class);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/MySQLUnitDbAdapter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/MySQLUnitDbAdapter.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/MySQLUnitDbAdapter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/MySQLUnitDbAdapter.java Wed Apr  4 19:32:06 2012
@@ -45,6 +45,11 @@ public class MySQLUnitDbAdapter extends 
     public boolean supportsLobs() {
         return true;
     }
+    
+    @Override
+    public boolean supportsBitwiseOps() {
+        return true;
+    }
 
     @Override
     public boolean supportsCaseSensitiveLike() {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/UnitDbAdapter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/UnitDbAdapter.java?rev=1309561&r1=1309560&r2=1309561&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/UnitDbAdapter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/unit/UnitDbAdapter.java Wed Apr  4 19:32:06 2012
@@ -229,6 +229,10 @@ public class UnitDbAdapter {
     public boolean supportsBatchPK() {
         return true;
     }
+    
+    public boolean supportsBitwiseOps() {
+        return false;
+    }
 
     protected void executeDDL(Connection con, String ddl) throws Exception {
         logger.info(ddl);