You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jc...@apache.org on 2018/11/28 05:37:16 UTC

[1/2] calcite git commit: [CALCITE-2695] Simplify casts which are only widening nullability (Zoltan Haindrich)

Repository: calcite
Updated Branches:
  refs/heads/master da57c903f -> 439ca73b8


[CALCITE-2695] Simplify casts which are only widening nullability (Zoltan Haindrich)

Close apache/calcite#934


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/439ca73b
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/439ca73b
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/439ca73b

Branch: refs/heads/master
Commit: 439ca73b8a335213b5f2764514b14e17c9d3c216
Parents: 463255c
Author: Zoltan Haindrich <ki...@rxd.hu>
Authored: Thu Nov 22 18:31:09 2018 +0100
Committer: Jesus Camacho Rodriguez <jc...@apache.org>
Committed: Tue Nov 27 20:33:11 2018 -0800

----------------------------------------------------------------------
 .../apache/calcite/rex/RexProgramBuilder.java   |  2 +-
 .../org/apache/calcite/rex/RexSimplify.java     | 13 +++++++++----
 .../java/org/apache/calcite/test/JdbcTest.java  |  2 +-
 .../org/apache/calcite/test/RexProgramTest.java |  9 ++++++++-
 .../org/apache/calcite/test/RelOptRulesTest.xml |  2 +-
 .../calcite/test/SqlToRelConverterTest.xml      | 14 +++++++-------
 core/src/test/resources/sql/agg.iq              |  2 +-
 core/src/test/resources/sql/some.iq             |  2 +-
 core/src/test/resources/sql/sub-query.iq        | 20 ++++++++++----------
 9 files changed, 39 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/main/java/org/apache/calcite/rex/RexProgramBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexProgramBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexProgramBuilder.java
index 94329e2..f871b9d 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexProgramBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexProgramBuilder.java
@@ -326,7 +326,7 @@ public class RexProgramBuilder {
   private RexLocalRef registerInternal(RexNode expr, boolean force) {
     final RexSimplify simplify =
         new RexSimplify(rexBuilder, RelOptPredicateList.EMPTY, RexUtil.EXECUTOR);
-    expr = simplify.simplify(expr);
+    expr = simplify.simplifyPreservingType(expr);
 
     RexLocalRef ref;
     final Pair<String, String> key;

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
index 17946f2..a8e95e9 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -1535,7 +1535,11 @@ public class RexSimplify {
   }
 
   private RexNode simplifyCast(RexCall e) {
-    final RexNode operand = e.getOperands().get(0);
+    RexNode operand = e.getOperands().get(0);
+    operand = simplify(operand, UNKNOWN);
+    if (sameTypeOrNarrowsNullability(e.getType(), operand.getType())) {
+      return operand;
+    }
     switch (operand.getKind()) {
     case LITERAL:
       final RexLiteral literal = (RexLiteral) operand;
@@ -1564,10 +1568,11 @@ public class RexSimplify {
       return Objects.requireNonNull(
           Iterables.getOnlyElement(reducedValues));
     default:
-      if (operand.getType().equals(e.getType())) {
-        return simplify(operand, UNKNOWN);
+      if (operand == e.getOperands().get(0)) {
+        return e;
+      } else {
+        return rexBuilder.makeCast(e.getType(), operand);
       }
-      return e;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index e1d2917..f84f24f 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -3472,7 +3472,7 @@ public class JdbcTest {
         .typeIs(
             "[deptno INTEGER NOT NULL, empid INTEGER NOT NULL, S REAL, FIVE INTEGER NOT NULL, M REAL, C BIGINT NOT NULL]")
         .explainContains(""
-            + "EnumerableCalc(expr#0..7=[{inputs}], expr#8=[0], expr#9=[>($t4, $t8)], expr#10=[CAST($t5):JavaType(class java.lang.Float)], expr#11=[null], expr#12=[CASE($t9, $t10, $t11)], expr#13=[5], deptno=[$t1], empid=[$t0], S=[$t12], FIVE=[$t13], M=[$t6], C=[$t7])\n"
+            + "EnumerableCalc(expr#0..7=[{inputs}], expr#8=[0], expr#9=[>($t4, $t8)], expr#10=[null], expr#11=[CASE($t9, $t5, $t10)], expr#12=[5], deptno=[$t1], empid=[$t0], S=[$t11], FIVE=[$t12], M=[$t6], C=[$t7])\n"
             + "  EnumerableWindow(window#0=[window(partition {1} order by [0] rows between $4 PRECEDING and CURRENT ROW aggs [COUNT($3), $SUM0($3), MIN($2), COUNT()])])\n"
             + "    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[+($t3, $t0)], proj#0..1=[{exprs}], salary=[$t3], $3=[$t5])\n"
             + "      EnumerableTableScan(table=[[hr, emps]])\n")

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
index 5f50144..b52937f 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -739,7 +739,7 @@ public class RexProgramTest extends RexProgramBuilderBase {
   @Test public void removeRedundantCast() {
     checkSimplify(cast(vInt(), nullable(tInt())), "?0.int0");
     checkSimplifyUnchanged(cast(vInt(), tInt()));
-    checkSimplifyUnchanged(cast(vIntNotNull(), nullable(tInt())));
+    checkSimplify(cast(vIntNotNull(), nullable(tInt())), "?0.notNullInt0");
     checkSimplify(cast(vIntNotNull(), tInt()), "?0.notNullInt0");
 
     // Nested int int cast is removed
@@ -2112,6 +2112,13 @@ public class RexProgramTest extends RexProgramBuilderBase {
         "2011-07-20 01:23:45");
   }
 
+  @Test public void testRemovalOfNullabilityWideningCast() {
+    RexNode expr = cast(isTrue(vBoolNotNull()), tBoolean(true));
+    assertThat(expr.getType().isNullable(), is(true));
+    RexNode result = simplify.simplifyUnknownAs(expr, RexUnknownAs.UNKNOWN);
+    assertThat(result.getType().isNullable(), is(false));
+  }
+
   @Test public void testCompareTimestampWithTimeZone() {
     final TimestampWithTimeZoneString timestampLTZChar1 =
         new TimestampWithTimeZoneString("2011-07-20 10:34:56 America/Los_Angeles");

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 883338a..ba38082 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -7926,7 +7926,7 @@ LogicalProject(DEPTNO=[$1])
         <Resource name="planAfter">
             <![CDATA[
 LogicalProject(EMPNO=[$0], D=[CASE(=($9, 0), false, IS NULL(CASE(true, CAST($7):INTEGER, null)), null, IS NOT NULL($12), true, <($10, $9), null, false)])
-  LogicalJoin(condition=[=(CAST($7):INTEGER, $11)], joinType=[left])
+  LogicalJoin(condition=[=($7, $11)], joinType=[left])
     LogicalJoin(condition=[true], joinType=[inner])
       LogicalTableScan(table=[[CATALOG, SALES, EMP]])
       LogicalAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index a289675..4f5b8d9 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -327,7 +327,7 @@ LogicalProject(DEPTNO=[$0], NAME=[$1])
     <TestCase name="testSelectOverDistinct">
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(>(COUNT(DISTINCT $7) OVER (ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), 0), CAST($SUM0(DISTINCT $7) OVER (ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)):INTEGER, null)])
+LogicalProject(EXPR$0=[CASE(>(COUNT(DISTINCT $7) OVER (ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), 0), $SUM0(DISTINCT $7) OVER (ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), null)])
   LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
         </Resource>
@@ -690,7 +690,7 @@ LogicalProject(EXPR$0=[NOT(LIKE('a', 'b', 'c'))])
     <TestCase name="testOverMultiple">
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null)], EXPR$1=[CASE(>(COUNT($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null)], EXPR$2=[CASE(>=(COUNT() OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), 2), CASE(>(COUNT($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)):INTEGER, null), null)])
+LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), $SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null)], EXPR$1=[CASE(>(COUNT($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), $SUM0($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null)], EXPR$2=[CASE(>=(COUNT() OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), 2), CASE(>(COUNT($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), 0), $SUM0($7) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), null), null)])
   LogicalFilter(condition=[>(-($7, $5), 999)])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
@@ -753,7 +753,7 @@ LogicalProject(C_NATIONKEY=[$1], FAKE_COL3=[$2])
     <TestCase name="testOverAvg">
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null)], EXPR$1=[CAST(/(CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null), COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW))):INTEGER])
+LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), $SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null)], EXPR$1=[CAST(/(CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null), COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW))):INTEGER])
   LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
         </Resource>
@@ -1245,7 +1245,7 @@ window w1 as (partition by job order by hiredate rows 2 preceding)]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):INTEGER, null)], EXPR$1=[/(CASE(>(COUNT(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):REAL, null), COUNT(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW))])
+LogicalProject(EXPR$0=[CASE(>(COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), $SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null)], EXPR$1=[/(CASE(>(COUNT(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), CAST($SUM0(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)):REAL, null), COUNT(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW))])
   LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
         </Resource>
@@ -2155,7 +2155,7 @@ from emp]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN])
+LogicalProject(EMPNO=[$0], EXPR$1=[CAST(IS NOT TRUE($11)):BOOLEAN])
   LogicalJoin(condition=[=($9, $10)], joinType=[left])
     LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7])
       LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -2174,7 +2174,7 @@ from emp]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN])
+LogicalProject(EMPNO=[$0], EXPR$1=[CAST(IS NOT TRUE($11)):BOOLEAN])
   LogicalJoin(condition=[=($9, $10)], joinType=[left])
     LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7])
       LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -2194,7 +2194,7 @@ from emp]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[CAST(NOT(AND(IS TRUE($11), IS NOT NULL($9)))):BOOLEAN])
+LogicalProject(EMPNO=[$0], EXPR$1=[CAST(IS NOT TRUE($11)):BOOLEAN])
   LogicalJoin(condition=[=($9, $10)], joinType=[left])
     LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$7])
       LogicalTableScan(table=[[CATALOG, SALES, EMP]])

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/resources/sql/agg.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/agg.iq b/core/src/test/resources/sql/agg.iq
index b7688fc..3d4468d 100755
--- a/core/src/test/resources/sql/agg.iq
+++ b/core/src/test/resources/sql/agg.iq
@@ -2148,7 +2148,7 @@ from (values (1,2),(3,4));
 (1 row)
 
 !ok
-EnumerableCalc(expr#0=[{inputs}], expr#1=[0], expr#2=[=($t0, $t1)], expr#3=[null], expr#4=[CAST($t0):BIGINT], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+EnumerableCalc(expr#0=[{inputs}], expr#1=[0], expr#2=[=($t0, $t1)], expr#3=[null], expr#4=[CASE($t2, $t3, $t0)], EXPR$0=[$t4])
   EnumerableAggregate(group=[{}], agg#0=[COUNT($0)])
     EnumerableAggregate(group=[{0}])
       EnumerableCalc(expr#0..1=[{inputs}], expr#2=['1'], $f0=[$t2])

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/resources/sql/some.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/some.iq b/core/src/test/resources/sql/some.iq
index 065476c..6eb7e92 100644
--- a/core/src/test/resources/sql/some.iq
+++ b/core/src/test/resources/sql/some.iq
@@ -108,7 +108,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..10=[{inputs}], expr#11=[0], expr#12=[=($t1, $t11)], expr#13=[false], expr#14=[CAST($t13):BOOLEAN], expr#15=[AND($t12, $t14)], expr#16=[<=($t8, $t0)], expr#17=[IS TRUE($t16)], expr#18=[true], expr#19=[CAST($t18):BOOLEAN], expr#20=[NOT($t12)], expr#21=[AND($t17, $t19, $t20)], expr#22=[>($t1, $t2)], expr#23=[null], expr#24=[CAST($t23):BOOLEAN], expr#25=[NOT($t17)], expr#26=[AND($t22, $t24, $t20, $t25)], expr#27=[NOT($t22)], expr#28=[AND($t16, $t20, $t25, $t27)], expr#29=[OR($t15, $t21, $t26, $t28)], expr#30=[NOT($t29)], EMPNO=[$t3], ENAME=[$t4], JOB=[$t5], MGR=[$t6], HIREDATE=[$t7], SAL=[$t8], COMM=[$t9], DEPTNO=[$t10], X=[$t30])
+EnumerableCalc(expr#0..10=[{inputs}], expr#11=[0], expr#12=[=($t1, $t11)], expr#13=[false], expr#14=[AND($t12, $t13)], expr#15=[<=($t8, $t0)], expr#16=[IS TRUE($t15)], expr#17=[true], expr#18=[NOT($t12)], expr#19=[AND($t16, $t17, $t18)], expr#20=[>($t1, $t2)], expr#21=[null], expr#22=[CAST($t21):BOOLEAN], expr#23=[NOT($t16)], expr#24=[AND($t20, $t22, $t18, $t23)], expr#25=[NOT($t20)], expr#26=[AND($t15, $t18, $t23, $t25)], expr#27=[OR($t14, $t19, $t24, $t26)], expr#28=[NOT($t27)], EMPNO=[$t3], ENAME=[$t4], JOB=[$t5], MGR=[$t6], HIREDATE=[$t7], SAL=[$t8], COMM=[$t9], DEPTNO=[$t10], X=[$t28])
   EnumerableJoin(condition=[true], joinType=[inner])
     EnumerableAggregate(group=[{}], m=[MAX($6)], c=[COUNT()], d=[COUNT($6)])
       EnumerableTableScan(table=[[scott, EMP]])

http://git-wip-us.apache.org/repos/asf/calcite/blob/439ca73b/core/src/test/resources/sql/sub-query.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sub-query.iq b/core/src/test/resources/sql/sub-query.iq
index 864f62d..e29948f 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -1009,7 +1009,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], expr#
     EnumerableLimit(fetch=[1])
       EnumerableSort(sort0=[$0], dir0=[DESC])
         EnumerableAggregate(group=[{0}], c=[COUNT()])
-          EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], cs=[$t3], $condition=[$t6])
+          EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
             EnumerableTableScan(table=[[scott, DEPT]])
 !plan
 
@@ -1038,7 +1038,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[null], expr#10=[IS NULL($t9)], expr#11=[OR($t8, $t10)], expr#12=[IS TRUE($t11)], expr#13=[null], expr#14=[CAST($t13):BOOLEAN], expr#15=[NOT($t4)], expr#16=[AND($t12, $t14, $t15)], expr#17=[IS NOT NULL($t2)], expr#18=[true], expr#19=[CAST($t18):BOOLEAN], expr#20=[IS NOT TRUE($t11)], expr#21=[AND($t17, $t19, $t20, $t15)], expr#22=[NOT($t17)], expr#23=[AND($t6, $t20, $t15, $t22)], expr#24=[OR($t7, $t16, $t21, $t23)], expr#25=[NOT($t24)], SAL=[$t1], EXPR$1=[$t25])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[null], expr#9=[IS NULL($t8)], expr#10=[OR($t7, $t9)], expr#11=[IS TRUE($t10)], expr#12=[null], expr#13=[CAST($t12):BOOLEAN], expr#14=[NOT($t4)], expr#15=[AND($t11, $t13, $t14)], expr#16=[IS NOT NULL($t2)], expr#17=[true], expr#18=[IS NOT TRUE($t10)], expr#19=[AND($t16, $t17, $t18, $t14)], expr#20=[NOT($t16)], expr#21=[AND($t5, $t18, $t14, $t20)], expr#22=[OR($t6, $t15, $t19, $t21)], expr#23=[NOT($t22)], SAL=[$t1], EXPR$1=[$t23])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1074,7 +1074,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[IS TRUE($t8)], expr#10=[null], expr#11=[CAST($t10):BOOLEAN], expr#12=[NOT($t4)], expr#13=[AND($t9, $t11, $t12)], expr#14=[IS NOT NULL($t2)], expr#15=[true], expr#16=[CAST($t15):BOOLEAN], expr#17=[IS NOT TRUE($t8)], expr#18=[AND($t14, $t16, $t17, $t12)], expr#19=[NOT($t14)], expr#20=[AND($t6, $t17, $t12, $t19)], expr#21=[OR($t7, $t13, $t18, $t20)], expr#22=[NOT($t21)], SAL=[$t1], EXPR$1=[$t22])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[IS TRUE($t7)], expr#9=[null], expr#10=[CAST($t9):BOOLEAN], expr#11=[NOT($t4)], expr#12=[AND($t8, $t10, $t11)], expr#13=[IS NOT NULL($t2)], expr#14=[true], expr#15=[IS NOT TRUE($t7)], expr#16=[AND($t13, $t14, $t15, $t11)], expr#17=[NOT($t13)], expr#18=[AND($t5, $t15, $t11, $t17)], expr#19=[OR($t6, $t12, $t16, $t18)], expr#20=[NOT($t19)], SAL=[$t1], EXPR$1=[$t20])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1110,7 +1110,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[null], expr#10=[IS NULL($t9)], expr#11=[OR($t8, $t10)], expr#12=[IS TRUE($t11)], expr#13=[null], expr#14=[CAST($t13):BOOLEAN], expr#15=[NOT($t4)], expr#16=[AND($t12, $t14, $t15)], expr#17=[IS NOT NULL($t2)], expr#18=[true], expr#19=[CAST($t18):BOOLEAN], expr#20=[IS NOT TRUE($t11)], expr#21=[AND($t17, $t19, $t20, $t15)], expr#22=[NOT($t17)], expr#23=[AND($t6, $t20, $t15, $t22)], expr#24=[OR($t7, $t16, $t21, $t23)], expr#25=[NOT($t24)], SAL=[$t1], EXPR$1=[$t25])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[null], expr#9=[IS NULL($t8)], expr#10=[OR($t7, $t9)], expr#11=[IS TRUE($t10)], expr#12=[null], expr#13=[CAST($t12):BOOLEAN], expr#14=[NOT($t4)], expr#15=[AND($t11, $t13, $t14)], expr#16=[IS NOT NULL($t2)], expr#17=[true], expr#18=[IS NOT TRUE($t10)], expr#19=[AND($t16, $t17, $t18, $t14)], expr#20=[NOT($t16)], expr#21=[AND($t5, $t18, $t14, $t20)], expr#22=[OR($t6, $t15, $t19, $t21)], expr#23=[NOT($t22)], SAL=[$t1], EXPR$1=[$t23])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1146,7 +1146,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[null], expr#10=[IS NULL($t9)], expr#11=[OR($t8, $t10)], expr#12=[IS TRUE($t11)], expr#13=[null], expr#14=[CAST($t13):BOOLEAN], expr#15=[NOT($t4)], expr#16=[AND($t12, $t14, $t15)], expr#17=[IS NOT NULL($t2)], expr#18=[true], expr#19=[CAST($t18):BOOLEAN], expr#20=[IS NOT TRUE($t11)], expr#21=[AND($t17, $t19, $t20, $t15)], expr#22=[NOT($t17)], expr#23=[AND($t6, $t20, $t15, $t22)], expr#24=[OR($t7, $t16, $t21, $t23)], expr#25=[NOT($t24)], SAL=[$t1], EXPR$1=[$t25])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[null], expr#9=[IS NULL($t8)], expr#10=[OR($t7, $t9)], expr#11=[IS TRUE($t10)], expr#12=[null], expr#13=[CAST($t12):BOOLEAN], expr#14=[NOT($t4)], expr#15=[AND($t11, $t13, $t14)], expr#16=[IS NOT NULL($t2)], expr#17=[true], expr#18=[IS NOT TRUE($t10)], expr#19=[AND($t16, $t17, $t18, $t14)], expr#20=[NOT($t16)], expr#21=[AND($t5, $t18, $t14, $t20)], expr#22=[OR($t6, $t15, $t19, $t21)], expr#23=[NOT($t22)], SAL=[$t1], EXPR$1=[$t23])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1182,7 +1182,7 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[null], expr#10=[IS NULL($t9)], expr#11=[OR($t8, $t10)], expr#12=[IS TRUE($t11)], expr#13=[null], expr#14=[CAST($t13):BOOLEAN], expr#15=[NOT($t4)], expr#16=[AND($t12, $t14, $t15)], expr#17=[IS NOT NULL($t2)], expr#18=[true], expr#19=[CAST($t18):BOOLEAN], expr#20=[IS NOT TRUE($t11)], expr#21=[AND($t17, $t19, $t20, $t15)], expr#22=[NOT($t17)], expr#23=[AND($t6, $t20, $t15, $t22)], expr#24=[OR($t7, $t16, $t21, $t23)], expr#25=[NOT($t24)], SAL=[$t1], EXPR$1=[$t25])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[null], expr#9=[IS NULL($t8)], expr#10=[OR($t7, $t9)], expr#11=[IS TRUE($t10)], expr#12=[null], expr#13=[CAST($t12):BOOLEAN], expr#14=[NOT($t4)], expr#15=[AND($t11, $t13, $t14)], expr#16=[IS NOT NULL($t2)], expr#17=[true], expr#18=[IS NOT TRUE($t10)], expr#19=[AND($t16, $t17, $t18, $t14)], expr#20=[NOT($t16)], expr#21=[AND($t5, $t18, $t14, $t20)], expr#22=[OR($t6, $t15, $t19, $t21)], expr#23=[NOT($t22)], SAL=[$t1], EXPR$1=[$t23])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1252,14 +1252,14 @@ from "scott".emp;
 (14 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[CAST($t5):BOOLEAN], expr#7=[AND($t4, $t6)], expr#8=[=($t2, $t5)], expr#9=[IS TRUE($t8)], expr#10=[null], expr#11=[CAST($t10):BOOLEAN], expr#12=[NOT($t4)], expr#13=[AND($t9, $t11, $t12)], expr#14=[IS NOT NULL($t2)], expr#15=[true], expr#16=[CAST($t15):BOOLEAN], expr#17=[IS NOT TRUE($t8)], expr#18=[AND($t14, $t16, $t17, $t12)], expr#19=[NOT($t14)], expr#20=[AND($t6, $t17, $t12, $t19)], expr#21=[OR($t7, $t13, $t18, $t20)], expr#22=[NOT($t21)], SAL=[$t1], EXPR$1=[$t22])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr#6=[AND($t4, $t5)], expr#7=[=($t2, $t5)], expr#8=[IS TRUE($t7)], expr#9=[null], expr#10=[CAST($t9):BOOLEAN], expr#11=[NOT($t4)], expr#12=[AND($t8, $t10, $t11)], expr#13=[IS NOT NULL($t2)], expr#14=[true], expr#15=[IS NOT TRUE($t7)], expr#16=[AND($t13, $t14, $t15, $t11)], expr#17=[NOT($t13)], expr#18=[AND($t5, $t15, $t11, $t17)], expr#19=[OR($t6, $t12, $t16, $t18)], expr#20=[NOT($t19)], SAL=[$t1], EXPR$1=[$t20])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
     EnumerableLimit(fetch=[1])
       EnumerableSort(sort0=[$0], dir0=[DESC])
         EnumerableAggregate(group=[{0}], c=[COUNT()])
-          EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], cs=[$t3], $condition=[$t6])
+          EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
             EnumerableTableScan(table=[[scott, DEPT]])
 !plan
 
@@ -1731,7 +1731,7 @@ select sal from "scott".emp e
 !ok
 EnumerableCalc(expr#0..3=[{inputs}], SAL=[$t2])
   EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
-    EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[CAST($t0):TINYINT], expr#5=[=($t3, $t4)], DEPTNO=[$t0], $condition=[$t5])
+    EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[=($t3, $t0)], DEPTNO=[$t0], $condition=[$t4])
       EnumerableTableScan(table=[[scott, DEPT]])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1881,7 +1881,7 @@ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[false], expr#6=[=($t4, $t5)], expr#
   EnumerableJoin(condition=[=($2, $3)], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
       EnumerableTableScan(table=[[scott, EMP]])
-    EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], DEPTNO=[$t0], $f1=[$t3], $condition=[$t6])
+    EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], DEPTNO=[$t0], $f1=[$t3], $condition=[$t5])
       EnumerableTableScan(table=[[scott, DEPT]])
 !plan
 


[2/2] calcite git commit: [CALCITE-2687] Is distinct from could lead to Exceptions in ReduceExpressionRule (Zoltan Haindrich)

Posted by jc...@apache.org.
[CALCITE-2687] Is distinct from could lead to Exceptions in ReduceExpressionRule (Zoltan Haindrich)

Close apache/calcite#929


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/463255c7
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/463255c7
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/463255c7

Branch: refs/heads/master
Commit: 463255c75f7e83081f56e657549d69d4feb7dbdf
Parents: da57c90
Author: Zoltan Haindrich <ki...@rxd.hu>
Authored: Tue Nov 20 09:28:20 2018 +0100
Committer: Jesus Camacho Rodriguez <jc...@apache.org>
Committed: Tue Nov 27 20:33:11 2018 -0800

----------------------------------------------------------------------
 .../org/apache/calcite/plan/RelOptUtil.java     | 48 ++++++++------------
 .../apache/calcite/test/RelOptRulesTest.java    | 14 +++++-
 .../org/apache/calcite/test/RelOptRulesTest.xml | 27 ++++++++++-
 .../calcite/test/SqlToRelConverterTest.xml      | 23 ++++++++--
 4 files changed, 74 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/463255c7/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index e15e491..0e68a11 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -1927,38 +1927,26 @@ public abstract class RelOptUtil {
       RexNode x,
       RexNode y,
       boolean neg) {
-    SqlOperator nullOp;
-    SqlOperator eqOp;
+
     if (neg) {
-      nullOp = SqlStdOperatorTable.IS_NULL;
-      eqOp = SqlStdOperatorTable.EQUALS;
+      // x is not distinct from y
+      // x=y IS TRUE or ((x is null) and (y is null)),
+      return rexBuilder.makeCall(SqlStdOperatorTable.OR,
+          rexBuilder.makeCall(SqlStdOperatorTable.AND,
+              rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, x),
+              rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, y)),
+          rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE,
+              rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, x, y)));
     } else {
-      nullOp = SqlStdOperatorTable.IS_NOT_NULL;
-      eqOp = SqlStdOperatorTable.NOT_EQUALS;
+      // x is distinct from y
+      // x=y IS NOT TRUE and ((x is not null) or (y is not null)),
+      return rexBuilder.makeCall(SqlStdOperatorTable.AND,
+          rexBuilder.makeCall(SqlStdOperatorTable.OR,
+              rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, x),
+              rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, y)),
+          rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_TRUE,
+              rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, x, y)));
     }
-    // By the time the ELSE is reached, x and y are known to be not null;
-    // therefore the whole CASE is not null.
-    RexNode[] whenThenElse = {
-        // when x is null
-        rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, x),
-
-        // then return y is [not] null
-        rexBuilder.makeCall(nullOp, y),
-
-        // when y is null
-        rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, y),
-
-        // then return x is [not] null
-        rexBuilder.makeCall(nullOp, x),
-
-        // else return x compared to y
-        rexBuilder.makeCall(eqOp,
-            rexBuilder.makeNotNull(x),
-            rexBuilder.makeNotNull(y))
-    };
-    return rexBuilder.makeCall(
-        SqlStdOperatorTable.CASE,
-        whenThenElse);
   }
 
   /**
@@ -2703,7 +2691,7 @@ public abstract class RelOptUtil {
     //noinspection unchecked
     return (T) rel.copy(
         rel.getTraitSet().replace(trait),
-        (List) rel.getInputs());
+        rel.getInputs());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/463255c7/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index e91af51..3db0ccc 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -1791,10 +1791,22 @@ public class RelOptRulesTest extends RelOptTestBase {
         .addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
         .build();
 
-    checkPlanUnchanged(new HepPlanner(program),
+    checkPlanning(new HepPlanner(program),
         "select p1 is not distinct from p0 from (values (2, cast(null as integer))) as t(p0, p1)");
   }
 
+  @Test public void testReduceConstants3() throws Exception {
+    HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(ReduceExpressionsRule.PROJECT_INSTANCE)
+        .addRuleInstance(ReduceExpressionsRule.FILTER_INSTANCE)
+        .addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
+        .build();
+
+    final String sql = "select e.mgr is not distinct from f.mgr "
+        + "from emp e join emp f on (e.mgr=f.mgr) where e.mgr is null";
+    checkPlanning(new HepPlanner(program), sql);
+  }
+
   /** Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-902">[CALCITE-902]
    * Match nullability when reducing expressions in a Project</a>. */

http://git-wip-us.apache.org/repos/asf/calcite/blob/463255c7/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 7d90b75..883338a 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -2194,7 +2194,7 @@ LogicalCalc(expr#0=[{inputs}], expr#1=['TABLE        '], expr#2=['t'], U=[$t1],
         </Resource>
         <Resource name="planBefore">
             <![CDATA[
-LogicalProject(EXPR$0=[false])
+LogicalProject(EXPR$0=[IS TRUE(null)])
   LogicalValues(tuples=[[{ 0 }]])
 ]]>
         </Resource>
@@ -2590,7 +2590,7 @@ LogicalFilter(condition=[IS NOT DISTINCT FROM($7, 20)])
         </Resource>
         <Resource name="planAfter">
             <![CDATA[
-LogicalFilter(condition=[CASE(IS NULL($7), false, =(CAST($7):TINYINT NOT NULL, 20))])
+LogicalFilter(condition=[IS TRUE(=($7, 20))])
   LogicalTableScan(table=[[scott, EMP]])
 ]]>
         </Resource>
@@ -6200,6 +6200,29 @@ LogicalProject(QX=[CAST(CASE(=($0, 1), 1, 2)):INTEGER])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testReduceConstants3">
+        <Resource name="sql">
+            <![CDATA[select e.mgr is not distinct from f.mgr from emp e join emp f on (e.mgr=f.mgr) where e.mgr is null]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalProject(EXPR$0=[OR(AND(IS NULL($3), IS NULL($12)), IS TRUE(=($3, $12)))])
+  LogicalFilter(condition=[IS NULL($3)])
+    LogicalJoin(condition=[=($3, $12)], joinType=[inner])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalProject(EXPR$0=[IS NULL($12)])
+  LogicalFilter(condition=[IS NULL($3)])
+    LogicalJoin(condition=[=($3, $12)], joinType=[inner])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testReduceConstantsDynamicFunction">
         <Resource name="sql">
             <![CDATA[select sal, t

http://git-wip-us.apache.org/repos/asf/calcite/blob/463255c7/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index db6d2a9..a289675 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -645,7 +645,7 @@ LogicalProject(DEPTNO=[$7])
     <TestCase name="testIsDistinctFrom">
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(IS NULL($0), IS NOT NULL($1), IS NULL($1), IS NOT NULL($0), <>(CAST($0):INTEGER NOT NULL, CAST($1):INTEGER NOT NULL))])
+LogicalProject(EXPR$0=[AND(OR(IS NOT NULL($0), IS NOT NULL($1)), IS NOT TRUE(=($0, $1)))])
   LogicalUnion(all=[true])
     LogicalProject(EXPR$0=[null], EXPR$1=[1])
       LogicalValues(tuples=[[{ 0 }]])
@@ -662,7 +662,7 @@ from (values (cast(null as int), 1),
     <TestCase name="testIsNotDistinctFrom">
         <Resource name="plan">
             <![CDATA[
-LogicalProject(EXPR$0=[CASE(IS NULL($0), IS NULL($1), IS NULL($1), IS NULL($0), =(CAST($0):INTEGER NOT NULL, CAST($1):INTEGER NOT NULL))])
+LogicalProject(EXPR$0=[OR(AND(IS NULL($0), IS NULL($1)), IS TRUE(=($0, $1)))])
   LogicalUnion(all=[true])
     LogicalProject(EXPR$0=[null], EXPR$1=[1])
       LogicalValues(tuples=[[{ 0 }]])
@@ -5298,7 +5298,10 @@ LogicalProject(ANYEMPNO=[$1])
     </TestCase>
     <TestCase name="testWithinGroup1">
         <Resource name="sql">
-            <![CDATA[select deptno, collect(empno) within group (order by deptno, hiredate desc) from emp group by deptno]]>
+            <![CDATA[select deptno,
+ collect(empno) within group (order by deptno, hiredate desc)
+from emp
+group by deptno]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
@@ -5310,7 +5313,14 @@ LogicalAggregate(group=[{0}], EXPR$1=[COLLECT($1) WITHIN GROUP ([1, 2 DESC])])
     </TestCase>
     <TestCase name="testWithinGroup2">
         <Resource name="sql">
-            <![CDATA[select dept.deptno, collect(sal) within group (order by sal desc) as s, collect(sal) within group (order by 1)as s1, collect(sal) within group (order by sal) filter (where sal > 2000) as s2 from emp join dept using (deptno) group by dept.deptn]]>
+            <![CDATA[select dept.deptno,
+ collect(sal) within group (order by sal desc) as s,
+ collect(sal) within group (order by 1)as s1,
+ collect(sal) within group (order by sal)
+  filter (where sal > 2000) as s2
+from emp
+join dept using (deptno)
+group by dept.deptno]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[
@@ -5324,7 +5334,10 @@ LogicalAggregate(group=[{0}], S=[COLLECT($1) WITHIN GROUP ([1 DESC])], S1=[COLLE
     </TestCase>
     <TestCase name="testWithinGroup3">
         <Resource name="sql">
-            <![CDATA[select deptno, collect(empno) filter (where empno not in (1, 2)), count(*) from emp group by deptno]]>
+            <![CDATA[select deptno,
+ collect(empno) within group (order by empno not in (1, 2)), count(*)
+from emp
+group by deptno]]>
         </Resource>
         <Resource name="plan">
             <![CDATA[