vlsi commented on code in PR #5295:
URL: https://github.com/apache/calcite/pull/5295#discussion_r4189685779


##########
core/src/main/java/org/apache/calcite/rex/RexSimplify.java:
##########
@@ -2013,6 +2013,10 @@ private <C extends Comparable<C>> RexNode 
simplifyAnd2ForUnknownAsFalse(
       // Simplify BOOLEAN expressions if possible
       while (term.getKind() == SqlKind.EQUALS) {
         RexCall call = (RexCall) term;
+        if (call.getOperands().get(0).getType().getSqlTypeName()
+            != call.getOperands().get(1).getType().getSqlTypeName()) {
+          break;
+        }

Review Comment:
   Julian suggested an `isWellFormed` check 
([comment](https://github.com/apache/calcite/pull/5295#discussion_r4124950334)).
 A helper of that shape, called here and from `simplifyComparison` before L751, 
would also stop the swapped-operand case from the review body, and its name 
would say why the term is left alone. As written, the guard exists only in this 
loop and carries no comment.
   
   This also changes plans for `ANY`: under `UNKNOWN_AS_FALSE`, `AND(=($0, 
true), ?0.bool1)` with `$0` of type `ANY` used to become `AND($0, ?0.bool1)` 
and now stays unchanged. It needs a mention in the JIRA and a test, since 
`ITEM` on a `MAP<VARCHAR, ANY>` column, such as MongoDB's `_MAP`, produces 
`ANY`.



##########
core/src/test/java/org/apache/calcite/rex/RexProgramTest.java:
##########
@@ -2472,6 +2472,35 @@ private void checkExponentialCnf(int n) {
         "=(?0.notNullInt0, ?0.int1)");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5907";>[CALCITE-5907]
+   * Unexpected boolean expression simplification for And expression</a>. */
+  @Test void testSimplifyAndEqualityTrue() {
+    // "=(x, true)" can be simplified to "x" only if x has BOOLEAN type;
+    // there is no implicit cast from VARCHAR or INTEGER, so the equality
+    // must be retained

Review Comment:
   The stated reason is not accurate: Calcite does coerce VARCHAR and numeric 
types to BOOLEAN (`SqlTypeCoercionRule`). The equality has to stay because 
replacing it with `x` would put a non-BOOLEAN operand into the AND. Suggest: 
`"=(x, true)" simplifies to "x" only if x is BOOLEAN; otherwise the AND would 
get a non-BOOLEAN operand.`



##########
core/src/test/java/org/apache/calcite/rex/RexProgramTest.java:
##########
@@ -2472,6 +2472,35 @@ private void checkExponentialCnf(int n) {
         "=(?0.notNullInt0, ?0.int1)");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5907";>[CALCITE-5907]
+   * Unexpected boolean expression simplification for And expression</a>. */
+  @Test void testSimplifyAndEqualityTrue() {
+    // "=(x, true)" can be simplified to "x" only if x has BOOLEAN type;
+    // there is no implicit cast from VARCHAR or INTEGER, so the equality
+    // must be retained
+    checkSimplifyUnchanged(
+        and(eq(vVarchar(0), trueLiteral),
+        eq(vVarchar(1), trueLiteral)));

Review Comment:
   With paranoid mode on (`RexProgramBuilderBase` turns it on for every test), 
a regression here throws `ClassCastException` from `RexInterpreter` inside 
`RexSimplify.verify` and never shows the simplified expression. Turning 
paranoid mode off for the non-BOOLEAN inputs, as `testSimplifyItemRangeTerms` 
does with `simplify = simplify.withParanoid(false)`, makes 
`checkSimplifyUnchanged` print the expression it got instead.
   
   Nit: the second argument of `and(` is indented at the same level as `and(` 
itself, so it reads like a second argument of `checkSimplifyUnchanged`; the 
same applies at L2487, L2494, L2497, and L2500.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to