OPENJPA-2770 ensure equal(xxx, literal(boolean)) works in criteria builder
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
index d850c16..5f2f8e5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
@@ -76,6 +76,16 @@
         assertEquivalence(q.where(cb.literal(Boolean.FALSE)), FALSE_JPQL);
     }
 
+    public void testBooleanLiteralInEquals() {
+        CriteriaQuery<Order> q = cb.createQuery(Order.class);
+        Root<Order> root = q.from(Order.class);
+        Path<Object> path = root.get("delivered");
+        Expression<Boolean> literal = cb.literal(Boolean.FALSE);
+        assertEquals( // we don't want o.delivered = 1 <> 1 but o.delivered = false
+                "SELECT o FROM Order o WHERE o.delivered = false",
+                ((OpenJPACriteriaQuery<?>) q.select(root).where(cb.equal(path, literal))).toCQL());
+    }
+
     public void testDefaultAndIsTrue() {
         CriteriaQuery<Person> q = cb.createQuery(Person.class);
         q.from(Person.class);
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
index 05a6b13..a3e54ed 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilderImpl.java
@@ -264,19 +264,19 @@
     @Override
     public <N extends Number> Expression<N> diff(Expression<? extends N> x,
         Expression<? extends N> y) {
-        return new Expressions.Diff<>(x, y);
+        return new Expressions.Diff<>(replaceExpressionForBinaryOperator(x), replaceExpressionForBinaryOperator(y));
     }
 
     @Override
     public <N extends Number> Expression<N> diff(
         Expression<? extends N> x, N y) {
-        return new Expressions.Diff<>(x, y);
+        return new Expressions.Diff<>(replaceExpressionForBinaryOperator(x), y);
     }
 
     @Override
     public <N extends Number> Expression<N> diff(N x,
         Expression<? extends N> y) {
-        return new Expressions.Diff<>(x, y);
+        return new Expressions.Diff<>(x, replaceExpressionForBinaryOperator(y));
     }
 
     @Override
@@ -288,7 +288,17 @@
     public Predicate equal(Expression<?> x, Expression<?> y) {
         if (y == null)
             return new Expressions.IsNull((ExpressionImpl<?> )x);
-        return new Expressions.Equal(x, y);
+        return new Expressions.Equal(replaceExpressionForBinaryOperator(x), replaceExpressionForBinaryOperator(y));
+    }
+
+    private <T> Expression<T> replaceExpressionForBinaryOperator(final Expression<T> expression) {
+        if (expression == PredicateImpl.TRUE()) {
+            return (Expression<T>) PredicateImpl.TRUE_CONSTANT;
+        }
+        if (expression == PredicateImpl.FALSE()) {
+            return (Expression<T>) PredicateImpl.FALSE_CONSTANT;
+        }
+        return expression;
     }
 
     @Override
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
index 9c6f34a..ea79d75 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
@@ -45,6 +45,9 @@
  * @since 2.0.0
  */
 abstract class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
+    static final Expression<?> TRUE_CONSTANT = new Expressions.Constant<>(true);
+    static final Expression<?> FALSE_CONSTANT = new Expressions.Constant<>(false);
+
     private static Predicate TRUE;
     private static Predicate FALSE;