This is an automated email from the ASF dual-hosted git repository.

kgyrtkirk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new c462838  [CALCITE-2838] Simplification: Remove redundant IS TRUE/IS 
NOT FALSE checks
c462838 is described below

commit c462838f37f02b490088a216773415926688e9f3
Author: Zoltan Haindrich <k...@rxd.hu>
AuthorDate: Thu Feb 14 09:15:31 2019 +0100

    [CALCITE-2838] Simplification: Remove redundant IS TRUE/IS NOT FALSE checks
    
    Earlier expressions like ((x IS TRUE) IS TRUE) were left as is, the new 
behaviour
    recognizes if the IS TRUE/IS NOT FALSE check is redundant.
    In case ((x IS TRUE) IS TRUE) is a filter expression, it is simplified to 
'x'.
---
 .../java/org/apache/calcite/rex/RexSimplify.java   | 46 ++++++++++++----
 .../org/apache/calcite/test/RelOptRulesTest.java   |  2 +-
 .../org/apache/calcite/test/RexProgramTest.java    | 63 ++++++++++++++++++----
 .../calcite/test/fuzzer/RexProgramFuzzyTest.java   |  7 +--
 .../org/apache/calcite/test/RelOptRulesTest.xml    | 18 +++----
 core/src/test/resources/sql/blank.iq               |  4 +-
 core/src/test/resources/sql/sub-query.iq           | 36 +++----------
 7 files changed, 112 insertions(+), 64 deletions(-)

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 7ae8195..15e3b94 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -275,7 +275,7 @@ public class RexSimplify {
     case IS_FALSE:
     case IS_NOT_FALSE:
       assert e instanceof RexCall;
-      return simplifyIs((RexCall) e);
+      return simplifyIs((RexCall) e, unknownAs);
     case EQUALS:
     case GREATER_THAN:
     case GREATER_THAN_OR_EQUAL:
@@ -534,16 +534,35 @@ public class RexSimplify {
     return rexBuilder.makeCall(SqlStdOperatorTable.NOT, a2);
   }
 
-  private RexNode simplifyIs(RexCall call) {
+  private RexNode simplifyIs(RexCall call, RexUnknownAs unknownAs) {
     final SqlKind kind = call.getKind();
     final RexNode a = call.getOperands().get(0);
 
+    // UnknownAs.FALSE corresponds to x IS TRUE evaluation
+    // UnknownAs.TRUE to x IS NOT FALSE
+    // Note that both UnknownAs.TRUE and UnknownAs.FALSE only changes the 
meaning of Unknown
+    // (1) if we are already in UnknownAs.FALSE mode; x IS TRUE can be 
simiplified to x
+    // (2) similarily  in UnknownAs.TRUE mode ; x IS NOT FALSE can be 
simplified to x
+    // (3) x IS FALSE could be rewritten to (NOT x) IS TRUE and from there the 
1. rule applies
+    // (4) x IS NOT TRUE can be rewritten to (NOT x) IS NOT FALSE and from 
there the 2. rule applies
+    if (kind == SqlKind.IS_TRUE && unknownAs == RexUnknownAs.FALSE) {
+      return simplify(a, unknownAs);
+    }
+    if (kind == SqlKind.IS_FALSE && unknownAs == RexUnknownAs.FALSE) {
+      return simplify(rexBuilder.makeCall(SqlStdOperatorTable.NOT, a), 
unknownAs);
+    }
+    if (kind == SqlKind.IS_NOT_FALSE && unknownAs == RexUnknownAs.TRUE) {
+      return simplify(a, unknownAs);
+    }
+    if (kind == SqlKind.IS_NOT_TRUE && unknownAs == RexUnknownAs.TRUE) {
+      return simplify(rexBuilder.makeCall(SqlStdOperatorTable.NOT, a), 
unknownAs);
+    }
     final RexNode pred = simplifyIsPredicate(kind, a);
     if (pred != null) {
       return pred;
     }
 
-    final RexNode simplified = simplifyIs2(kind, a);
+    final RexNode simplified = simplifyIs2(kind, a, unknownAs);
     if (simplified != null) {
       return simplified;
     }
@@ -567,21 +586,21 @@ public class RexSimplify {
     return null;
   }
 
-  private RexNode simplifyIs2(SqlKind kind, RexNode a) {
+  private RexNode simplifyIs2(SqlKind kind, RexNode a, RexUnknownAs unknownAs) 
{
     final RexNode simplified;
     switch (kind) {
     case IS_NULL:
       // x IS NULL ==> FALSE (if x is not nullable)
       simplified = simplifyIsNull(a);
       if (simplified != null) {
-        return simplified;
+        return simplify(simplified, unknownAs);
       }
       break;
     case IS_NOT_NULL:
       // x IS NOT NULL ==> TRUE (if x is not nullable)
       simplified = simplifyIsNotNull(a);
       if (simplified != null) {
-        return simplified;
+        return simplify(simplified, unknownAs);
       }
       break;
     case IS_TRUE:
@@ -589,16 +608,21 @@ public class RexSimplify {
       // x IS TRUE ==> x (if x is not nullable)
       // x IS NOT FALSE ==> x (if x is not nullable)
       if (!a.getType().isNullable()) {
-        return simplify(a, UNKNOWN);
+        return simplify(a, unknownAs);
+      } else {
+        RexNode newSub =
+            simplify(a, kind == SqlKind.IS_TRUE ? RexUnknownAs.FALSE : 
RexUnknownAs.TRUE);
+        if (newSub == a) {
+          return null;
+        }
+        return rexBuilder.makeCall(RexUtil.op(kind), ImmutableList.of(newSub));
       }
-      break;
     case IS_FALSE:
     case IS_NOT_TRUE:
       // x IS NOT TRUE ==> NOT x (if x is not nullable)
       // x IS FALSE ==> NOT x (if x is not nullable)
       if (!a.getType().isNullable()) {
-        return simplify(rexBuilder.makeCall(SqlStdOperatorTable.NOT, a),
-            UNKNOWN);
+        return simplify(rexBuilder.makeCall(SqlStdOperatorTable.NOT, a), 
unknownAs);
       }
       break;
     }
@@ -1129,7 +1153,7 @@ public class RexSimplify {
       for (RexNode notSatisfiableNullable : notSatisfiableNullables) {
         terms.add(
             simplifyIs((RexCall)
-                rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, 
notSatisfiableNullable)));
+            rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, 
notSatisfiableNullable), UNKNOWN));
       }
     }
     // Add the NOT disjunctions back in.
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 9dca7b1..ef2b705 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -1805,7 +1805,7 @@ public class RelOptRulesTest extends RelOptTestBase {
         .addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
         .build();
 
-    checkPlanning(new HepPlanner(program),
+    checkPlanUnchanged(new HepPlanner(program),
         "select p1 is not distinct from p0 from (values (2, cast(null as 
integer))) as t(p0, p1)");
   }
 
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 3234050..b9e9ba0 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -299,9 +299,8 @@ public class RexProgramTest extends RexProgramBuilderBase {
     assertThat(program.normalize(rexBuilder, simplify).toString(),
         is("(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], expr#3=[1], "
             + "expr#4=[+($t0, $t3)], expr#5=[+($t2, $t4)], "
-            + "expr#6=[+($t0, $t4)], expr#7=[5], expr#8=[>($t4, $t7)], "
-            + "expr#9=[NOT($t8)], "
-            + "a=[$t5], b=[$t6], $condition=[$t9])"));
+            + "expr#6=[+($t0, $t4)], expr#7=[5], expr#8=[<=($t4, $t7)], "
+            + "a=[$t5], b=[$t6], $condition=[$t8])"));
   }
 
   /**
@@ -321,9 +320,8 @@ public class RexProgramTest extends RexProgramBuilderBase {
     assertThat(program.normalize(rexBuilder, simplify).toString(),
         is("(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], expr#3=[1], "
             + "expr#4=[+($t0, $t3)], expr#5=[+($t2, $t4)], "
-            + "expr#6=[+($t0, $t4)], expr#7=[5], expr#8=[>($t4, $t7)], "
-            + "expr#9=[NOT($t8)], "
-            + "a=[$t5], b=[$t6], $condition=[$t9])"));
+            + "expr#6=[+($t0, $t4)], expr#7=[5], expr#8=[<=($t4, $t7)], "
+            + "a=[$t5], b=[$t6], $condition=[$t8])"));
   }
 
   /**
@@ -1801,7 +1799,7 @@ public class RexProgramTest extends RexProgramBuilderBase 
{
             isTrue(vBool()), literal(1),
             isNotTrue(vBool()), literal(1),
             literal(2)),
-        "CASE(OR(IS TRUE(?0.bool0), IS NOT TRUE(?0.bool0)), 1, 2)");
+        "CASE(OR(?0.bool0, IS NOT TRUE(?0.bool0)), 1, 2)");
   }
 
   @Test public void testSimplifyCaseBranchesCollapse2() {
@@ -1909,7 +1907,7 @@ public class RexProgramTest extends RexProgramBuilderBase 
{
                 isTrue(vBool()), vBool(1),
                 gt(div(vIntNotNull(), literal(2)), literal(1)), vBool(2),
                 vBool(3))),
-        "CASE(IS TRUE(?0.bool0), NOT(?0.bool1), >(/(?0.notNullInt0, 2), 1), 
NOT(?0.bool2), NOT(?0.bool3))");
+        "CASE(?0.bool0, NOT(?0.bool1), >(/(?0.notNullInt0, 2), 1), 
NOT(?0.bool2), NOT(?0.bool3))");
   }
 
   @Test public void testNotRecursion() {
@@ -2434,9 +2432,13 @@ public class RexProgramTest extends 
RexProgramBuilderBase {
     // "NOT(false)" => "true"
     checkSimplify(not(falseLiteral), "true");
     // "NOT(IS FALSE(x))" => "IS NOT FALSE(x)"
-    checkSimplify(not(isFalse(vBool())), "IS NOT FALSE(?0.bool0)");
+    checkSimplify3(not(isFalse(vBool())),
+        "IS NOT FALSE(?0.bool0)", "IS NOT FALSE(?0.bool0)", "?0.bool0");
     // "NOT(IS TRUE(x))" => "IS NOT TRUE(x)"
-    checkSimplify(not(isTrue(vBool())), "IS NOT TRUE(?0.bool0)");
+    checkSimplify3(not(isTrue(vBool())),
+        "IS NOT TRUE(?0.bool0)",
+        "IS NOT TRUE(?0.bool0)",
+        "NOT(?0.bool0)");
     // "NOT(IS NULL(x))" => "IS NOT NULL(x)"
     checkSimplify(not(isNull(vBool())), "IS NOT NULL(?0.bool0)");
     // "NOT(IS NOT NULL(x)) => "IS NULL(x)"
@@ -2512,6 +2514,47 @@ public class RexProgramTest extends 
RexProgramBuilderBase {
         is(false));
   }
 
+  @Test public void testIsNullRecursion() {
+    // make sure that simplifcation is visiting below isX expressions
+    checkSimplify(
+        isNull(or(coalesce(nullBool, trueLiteral), falseLiteral)),
+        "false");
+  }
+
+  @Test public void testRedundantIsTrue() {
+    checkSimplify2(
+        isTrue(isTrue(vBool())),
+        "IS TRUE(?0.bool0)",
+        "?0.bool0"
+    );
+  }
+
+  @Test public void testRedundantIsFalse() {
+    checkSimplify2(
+        isTrue(isFalse(vBool())),
+        "IS FALSE(?0.bool0)",
+        "NOT(?0.bool0)"
+    );
+  }
+
+  @Test public void testRedundantIsNotTrue() {
+    checkSimplify3(
+        isNotFalse(isNotTrue(vBool())),
+        "IS NOT TRUE(?0.bool0)",
+        "IS NOT TRUE(?0.bool0)",
+        "NOT(?0.bool0)"
+    );
+  }
+
+  @Test public void testRedundantIsNotFalse() {
+    checkSimplify3(
+        isNotFalse(isNotFalse(vBool())),
+        "IS NOT FALSE(?0.bool0)",
+        "IS NOT FALSE(?0.bool0)",
+        "?0.bool0"
+    );
+  }
+
   /** Unit tests for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-2438";>[CALCITE-2438]
    * RexCall#isAlwaysTrue returns incorrect result</a>. */
diff --git 
a/core/src/test/java/org/apache/calcite/test/fuzzer/RexProgramFuzzyTest.java 
b/core/src/test/java/org/apache/calcite/test/fuzzer/RexProgramFuzzyTest.java
index 4b86f5b..e745d49 100644
--- a/core/src/test/java/org/apache/calcite/test/fuzzer/RexProgramFuzzyTest.java
+++ b/core/src/test/java/org/apache/calcite/test/fuzzer/RexProgramFuzzyTest.java
@@ -262,11 +262,12 @@ public class RexProgramFuzzyTest extends 
RexProgramBuilderBase {
         }
       }
     }
-    if (opt.getType().isNullable() && !node.getType().isNullable()) {
+    if (unknownAs == RexUnknownAs.UNKNOWN
+        && opt.getType().isNullable()
+        && !node.getType().isNullable()) {
       fail(nodeToString(node) + " had non-nullable type " + opt.getType()
           + ", and it was optimized to " + nodeToString(opt)
-          + " that has nullable type " + opt.getType()
-          + ", " + uaf);
+          + " that has nullable type " + opt.getType());
     }
     if (!SqlTypeUtil.equalSansNullability(typeFactory, node.getType(), 
opt.getType())) {
       assertEquals(nodeToString(node) + " has different type after 
simplification to "
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 8c7e46c..5da4200 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -481,7 +481,7 @@ LogicalProject(DEPTNO=[$0])
             <![CDATA[
 LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
   LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-    LogicalFilter(condition=[AND(OR(IS NOT TRUE(<=($0, $9)), =($10, 0)), 
OR(<=($10, $11), =($10, 0), IS TRUE(<=($0, $9))), OR(>($0, $9), =($10, 0), IS 
TRUE(<=($0, $9)), >($10, $11)))])
+    LogicalFilter(condition=[AND(OR(IS NOT TRUE(<=($0, $9)), =($10, 0)), 
OR(<=($10, $11), =($10, 0), <=($0, $9)), OR(>($0, $9), =($10, 0), <=($0, $9), 
>($10, $11)))])
       LogicalJoin(condition=[true], joinType=[inner])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
         LogicalAggregate(group=[{}], m=[MAX($0)], c=[COUNT()], d=[COUNT($0)])
@@ -493,7 +493,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], 
HIREDATE=[$4], SAL=[$
             <![CDATA[
 LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
   LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-    LogicalFilter(condition=[AND(OR(IS NOT TRUE(<=($0, $9)), =($10, 0)), 
OR(<=($10, $11), =($10, 0), IS TRUE(<=($0, $9))), OR(>($0, $9), =($10, 0), IS 
TRUE(<=($0, $9)), >($10, $11)))])
+    LogicalFilter(condition=[AND(OR(IS NOT TRUE(<=($0, $9)), =($10, 0)), 
OR(<=($10, $11), =($10, 0), <=($0, $9)), OR(>($0, $9), =($10, 0), <=($0, $9), 
>($10, $11)))])
       LogicalJoin(condition=[true], joinType=[inner])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
         LogicalAggregate(group=[{}], m=[MAX($0)], c=[COUNT()], d=[COUNT($0)])
@@ -2241,7 +2241,7 @@ LogicalCalc(expr#0=[{inputs}], expr#1=['TABLE        
':VARCHAR(26)], expr#2=['t'
         </Resource>
         <Resource name="planBefore">
             <![CDATA[
-LogicalProject(EXPR$0=[IS TRUE(null:BOOLEAN)])
+LogicalProject(EXPR$0=[false])
   LogicalValues(tuples=[[{ 0 }]])
 ]]>
         </Resource>
@@ -2637,7 +2637,7 @@ LogicalFilter(condition=[IS NOT DISTINCT FROM($7, 20)])
         </Resource>
         <Resource name="planAfter">
             <![CDATA[
-LogicalFilter(condition=[IS TRUE(=($7, 20))])
+LogicalFilter(condition=[=($7, 20)])
   LogicalTableScan(table=[[scott, EMP]])
 ]]>
         </Resource>
@@ -4551,7 +4551,7 @@ LogicalAggregate(group=[{}], EXPR$0=[COUNT()])
             <![CDATA[
 LogicalAggregate(group=[{}], EXPR$0=[COUNT()])
   LogicalProject($f0=[0])
-    LogicalFilter(condition=[IS TRUE(<($0, 10))])
+    LogicalFilter(condition=[<($0, 10)])
       LogicalProject(MGR=[$3])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
@@ -8512,7 +8512,7 @@ LogicalProject(DEPTNO=[$0])
         <Resource name="planAfter">
             <![CDATA[
 LogicalProject(SAL=[$5])
-  LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), 
IS TRUE(=($10, 0)))])
+  LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), 
=($10, 0))])
     LogicalJoin(condition=[AND(=($0, $12), =($2, $14))], joinType=[left])
       LogicalJoin(condition=[=($2, $9)], joinType=[left])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -8527,7 +8527,7 @@ LogicalProject(SAL=[$5])
             <![CDATA[
 LogicalProject(SAL=[$5])
   LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-    LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), 
IS TRUE(=($9, 0)))])
+    LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), 
=($9, 0))])
       LogicalCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{2}])
         LogicalCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{2}])
           LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -8604,7 +8604,7 @@ LogicalProject(EMPNO=[$1])
             <![CDATA[
 LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
   LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-    LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), 
IS TRUE(=($9, 0)))])
+    LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), 
=($9, 0))])
       LogicalCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{1}])
         LogicalCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{1}])
           LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -8623,7 +8623,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], 
MGR=[$3], HIREDATE=[$4], SAL=[$
         <Resource name="planAfter">
             <![CDATA[
 LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-  LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), 
IS TRUE(=($10, 0)))])
+  LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), 
=($10, 0))])
     LogicalJoin(condition=[AND(=($0, $12), =($1, $14))], joinType=[left])
       LogicalJoin(condition=[=($1, $9)], joinType=[left])
         LogicalTableScan(table=[[CATALOG, SALES, EMP]])
diff --git a/core/src/test/resources/sql/blank.iq 
b/core/src/test/resources/sql/blank.iq
index 80bfe3d..1cae199 100644
--- a/core/src/test/resources/sql/blank.iq
+++ b/core/src/test/resources/sql/blank.iq
@@ -73,9 +73,9 @@ insert into table2 values (NULL, 1), (2, 1);
 # Checked on Oracle
 !set lateDecorrelate true
 select i, j from table1 where table1.j NOT IN (select i from table2 where 
table1.i=table2.j);
-EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t7)], expr#9=[<($t4, 
$t3)], expr#10=[OR($t8, $t9)], expr#11=[IS NOT TRUE($t10)], expr#12=[0], 
expr#13=[=($t3, $t12)], expr#14=[IS TRUE($t13)], expr#15=[IS NULL($t1)], 
expr#16=[OR($t11, $t14, $t15)], proj#0..1=[{exprs}], $condition=[$t16])
+EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t7)], expr#9=[<($t4, 
$t3)], expr#10=[OR($t8, $t9)], expr#11=[IS NOT TRUE($t10)], expr#12=[0], 
expr#13=[=($t3, $t12)], expr#14=[IS NULL($t1)], expr#15=[OR($t11, $t13, $t14)], 
proj#0..1=[{exprs}], $condition=[$t15])
   EnumerableJoin(condition=[AND(=($0, $6), =($1, $5))], joinType=[left])
-    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[IS NOT NULL($t1)], 
expr#6=[0], expr#7=[=($t3, $t6)], expr#8=[IS TRUE($t7)], expr#9=[OR($t5, $t8)], 
proj#0..4=[{exprs}], $condition=[$t9])
+    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[IS NOT NULL($t1)], 
expr#6=[0], expr#7=[=($t3, $t6)], expr#8=[OR($t5, $t7)], proj#0..4=[{exprs}], 
$condition=[$t8])
       EnumerableJoin(condition=[=($0, $2)], joinType=[left])
         EnumerableTableScan(table=[[BLANK, TABLE1]])
         EnumerableAggregate(group=[{1}], c=[COUNT()], ck=[COUNT($0)])
diff --git a/core/src/test/resources/sql/sub-query.iq 
b/core/src/test/resources/sql/sub-query.iq
index b9f6b3f..c3aa3f2 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -1440,7 +1440,7 @@ select sal from "scott".emp
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[IS TRUE($t5)], expr#10=[OR($t7, $t9)], expr#11=[AND($t8, $t10)], 
SAL=[$t1], $condition=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[OR($t7, $t5)], expr#10=[AND($t8, $t9)], SAL=[$t1], $condition=[$t10])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1482,7 +1482,7 @@ select sal from "scott".emp
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[IS TRUE($t5)], expr#10=[OR($t7, $t9)], expr#11=[AND($t8, $t10)], 
SAL=[$t1], $condition=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[OR($t7, $t5)], expr#10=[AND($t8, $t9)], SAL=[$t1], $condition=[$t10])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1503,7 +1503,7 @@ select sal from "scott".emp
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[IS TRUE($t5)], expr#10=[OR($t7, $t9)], expr#11=[AND($t8, $t10)], 
SAL=[$t1], $condition=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[OR($t7, $t5)], expr#10=[AND($t8, $t9)], SAL=[$t1], $condition=[$t10])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1524,7 +1524,7 @@ select sal from "scott".emp
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[IS TRUE($t5)], expr#10=[OR($t7, $t9)], expr#11=[AND($t8, $t10)], 
SAL=[$t1], $condition=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], 
expr#6=[IS NOT TRUE($t5)], expr#7=[IS NULL($t3)], expr#8=[OR($t6, $t7)], 
expr#9=[OR($t7, $t5)], expr#10=[AND($t8, $t9)], SAL=[$t1], $condition=[$t10])
   EnumerableJoin(condition=[true], joinType=[left])
     EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
       EnumerableTableScan(table=[[scott, EMP]])
@@ -1747,12 +1747,7 @@ select sal from "scott".emp e
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[false], expr#6=[=($t4, $t5)], 
expr#7=[IS NOT TRUE($t6)], expr#8=[IS TRUE($t6)], expr#9=[AND($t7, $t8)], 
SAL=[$t1], $condition=[$t9])
-  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=[false], DEPTNO=[$t0], 
$f1=[$t3])
-      EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableValues(tuples=[[]])
 !plan
 
 # Test filter literal NOT IN null correlated
@@ -1783,12 +1778,7 @@ select sal from "scott".emp e
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[false], expr#6=[=($t4, $t5)], 
expr#7=[IS NOT TRUE($t6)], expr#8=[IS TRUE($t6)], expr#9=[AND($t7, $t8)], 
SAL=[$t1], $condition=[$t9])
-  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], DEPTNO=[$t0], 
$f1=[$t3])
-      EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableValues(tuples=[[]])
 !plan
 
 # Test filter null NOT IN required correlated
@@ -1801,12 +1791,7 @@ select sal from "scott".emp e
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[false], expr#6=[=($t4, $t5)], 
expr#7=[IS NOT TRUE($t6)], expr#8=[IS TRUE($t6)], expr#9=[AND($t7, $t8)], 
SAL=[$t1], $condition=[$t9])
-  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], DEPTNO=[$t0], 
$f1=[$t3])
-      EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableValues(tuples=[[]])
 !plan
 
 # Test filter null NOT IN nullable correlated
@@ -1819,12 +1804,7 @@ select sal from "scott".emp e
 (0 rows)
 
 !ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[false], expr#6=[=($t4, $t5)], 
expr#7=[IS NOT TRUE($t6)], expr#8=[IS TRUE($t6)], expr#9=[AND($t7, $t8)], 
SAL=[$t1], $condition=[$t9])
-  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], DEPTNO=[$t0], 
$f1=[$t3])
-      EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableValues(tuples=[[]])
 !plan
 
 # Test filter literal NOT IN required correlated

Reply via email to