Skip to content

Commit

Permalink
[CALCITE-1413] Enhance boolean case statement simplifications (Zoltan…
Browse files Browse the repository at this point in the history
… Haindrich)

Enables the simplification of case branch conditionals and values.
Adds a new case statement rewrite logic which could rewrite any case statement returning booleans
into and/or expressions.

Close #886
  • Loading branch information
kgyrtkirk authored and jcamachor committed Oct 17, 2018
1 parent 064974d commit b470a0c
Show file tree
Hide file tree
Showing 9 changed files with 463 additions and 216 deletions.
405 changes: 293 additions & 112 deletions core/src/main/java/org/apache/calcite/rex/RexSimplify.java

Large diffs are not rendered by default.

Expand Up @@ -1556,7 +1556,7 @@ private void checkPredicates(RelOptCluster cluster, RelOptTable empTable,
RelOptPredicateList list = mq.getPulledUpPredicates(rel);
// Uses "IS NOT DISTINCT FROM" rather than "=" because cannot guarantee not null.
assertThat(list.pulledUpPredicates,
sortsAs("[IS NOT DISTINCT FROM($0, CASE(=(1, 1), null, 1))]"));
sortsAs("[IS NULL($0)]"));
}

@Test public void testDistributionSimple() {
Expand Down
Expand Up @@ -266,7 +266,7 @@ protected DiffRepository getDiffRepos() {
final String sql = "SELECT CASE WHEN 1=2 "
+ "THEN cast((values(1)) as integer) "
+ "ELSE 2 end from (values(1))";
sql(sql).with(hepPlanner).check();
sql(sql).with(hepPlanner).checkUnchanged();
}

@Test public void testReduceNullableCase2() {
Expand All @@ -278,7 +278,7 @@ protected DiffRepository getDiffRepos() {
final String sql = "SELECT deptno, ename, CASE WHEN 1=2 "
+ "THEN substring(ename, 1, cast(2 as int)) ELSE NULL end from emp"
+ " group by deptno, ename, case when 1=2 then substring(ename,1, cast(2 as int)) else null end";
sql(sql).with(hepPlanner).check();
sql(sql).with(hepPlanner).checkUnchanged();
}

@Test public void testProjectToWindowRuleForMultipleWindows() {
Expand Down Expand Up @@ -1738,7 +1738,7 @@ public void testMinusMergeRule() throws Exception {
.addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
.build();

checkPlanning(program,
checkPlanUnchanged(new HepPlanner(program),
"select p1 is not distinct from p0 from (values (2, cast(null as integer))) as t(p0, p1)");
}

Expand Down
111 changes: 88 additions & 23 deletions core/src/test/java/org/apache/calcite/test/RexProgramTest.java
Expand Up @@ -270,8 +270,8 @@ private static int nodeCount(RexNode node) {
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=[CAST($t8):BOOLEAN], expr#10=[IS FALSE($t9)], "
+ "a=[$t5], b=[$t6], $condition=[$t10])"));
+ "expr#9=[NOT($t8)], "
+ "a=[$t5], b=[$t6], $condition=[$t9])"));
}

/**
Expand All @@ -292,8 +292,8 @@ private static int nodeCount(RexNode node) {
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=[CAST($t8):BOOLEAN], expr#10=[IS FALSE($t9)], "
+ "a=[$t5], b=[$t6], $condition=[$t10])"));
+ "expr#9=[NOT($t8)], "
+ "a=[$t5], b=[$t6], $condition=[$t9])"));
}

/**
Expand Down Expand Up @@ -1100,12 +1100,12 @@ private void checkExponentialCnf(int n) {

// case: remove false branches
checkSimplify(case_(eq(bRef, cRef), dRef, falseLiteral, aRef, eRef),
"CASE(=(?0.b, ?0.c), ?0.d, ?0.e)");
"OR(AND(=(?0.b, ?0.c), ?0.d), AND(?0.e, <>(?0.b, ?0.c)))");

// case: true branches become the last branch
checkSimplify(
case_(eq(bRef, cRef), dRef, trueLiteral, aRef, eq(cRef, dRef), eRef, cRef),
"CASE(=(?0.b, ?0.c), ?0.d, ?0.a)");
"OR(AND(=(?0.b, ?0.c), ?0.d), AND(?0.a, <>(?0.b, ?0.c)))");

// case: singleton
checkSimplify(case_(trueLiteral, aRef, eq(cRef, dRef), eRef, cRef), "?0.a");
Expand All @@ -1117,9 +1117,9 @@ private void checkExponentialCnf(int n) {
// case: trailing false and null, no simplification
checkSimplify3(
case_(aRef, trueLiteral, bRef, trueLiteral, cRef, falseLiteral, nullBool),
"CASE(?0.a, true, ?0.b, true, ?0.c, false, null)",
"CAST(OR(?0.a, ?0.b)):BOOLEAN",
"CAST(OR(?0.a, ?0.b)):BOOLEAN");
"OR(?0.a, ?0.b, AND(null, NOT(?0.a), NOT(?0.b), NOT(?0.c)))",
"OR(?0.a, ?0.b)",
"OR(?0.a, ?0.b, NOT(?0.c))");

// case: form an AND of branches that return true
checkSimplify(
Expand Down Expand Up @@ -1341,7 +1341,8 @@ private void checkExponentialCnf(int n) {
// case: trailing false and null, remove
checkSimplifyFilter(
case_(cRef, trueLiteral, dRef, trueLiteral, eRef, falseLiteral, fRef,
falseLiteral, nullBool), "CAST(OR(?0.c, ?0.d)):BOOLEAN");
falseLiteral, nullBool),
"OR(?0.c, ?0.d)");

// condition with null value for range
checkSimplifyFilter(and(gt(aRef, nullBool), ge(bRef, literal1)), "false");
Expand Down Expand Up @@ -1716,23 +1717,15 @@ private void checkExponentialCnf(int n) {
* <a href="https://issues.apache.org/jira/browse/CALCITE-1289">[CALCITE-1289]
* RexUtil.simplifyCase() should account for nullability</a>. */
@Test public void testSimplifyCaseNotNullableBoolean() {
RexNode condition = eq(
rexBuilder.makeInputRef(
typeFactory.createTypeWithNullability(
typeFactory.createSqlType(SqlTypeName.VARCHAR), true),
0),
rexBuilder.makeLiteral("S"));
RexNode condition = eq(vVarchar(), literal("S"));
RexCall caseNode = (RexCall) case_(condition, trueLiteral, falseLiteral);

final RexCall result =
(RexCall) simplify.simplifyUnknownAs(caseNode, RexUnknownAs.UNKNOWN);
assertThat(result.getType().isNullable(), is(false));
final RexCall result = (RexCall) simplify.simplifyUnknownAs(caseNode, RexUnknownAs.UNKNOWN);
assertThat("The case should be nonNullable", caseNode.getType().isNullable(), is(false));
assertThat("Expected a nonNullable type", result.getType().isNullable(), is(false));
assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.BOOLEAN));
assertThat(result.getOperator(), is((SqlOperator) SqlStdOperatorTable.CASE));
assertThat(result.getOperands().size(), is((Object) 3));
assertThat(result.getOperator(), is((SqlOperator) SqlStdOperatorTable.IS_TRUE));
assertThat(result.getOperands().get(0), is(condition));
assertThat(result.getOperands().get(1), is((RexNode) trueLiteral));
assertThat(result.getOperands().get(2), is((RexNode) falseLiteral));
}

@Test public void testSimplifyCaseNullableBoolean() {
Expand All @@ -1757,6 +1750,78 @@ private void checkExponentialCnf(int n) {
assertThat(result, is(caseNode));
}

@Test public void testSimplifyCaseCasting() {
RexNode caseNode = case_(eq(vIntNotNull(), literal(3)), nullBool, falseLiteral);

checkSimplify3(caseNode, "AND(=(?0.notNullInt0, 3), null)",
"false",
"=(?0.notNullInt0, 3)");
}

@Test public void testSimplifyCaseAndNotSimplicationIsInAction() {
RexNode caseNode = case_(
eq(vIntNotNull(), literal(0)), falseLiteral,
eq(vIntNotNull(), literal(1)), trueLiteral,
falseLiteral);
checkSimplify(caseNode, "=(?0.notNullInt0, 1)");
}

@Test public void testSimplifyCaseBranchRemovalStrengthensType() {
RexNode caseNode =
case_(falseLiteral, nullBool, eq(div(vInt(), literal(2)), literal(3)), trueLiteral,
falseLiteral);
assertThat("Expected to have a nullable type for " + caseNode + ".",
caseNode.getType().isNullable(), is(true));
RexNode res = simplify.simplify(caseNode);
assertThat("Expected to have a nonNullable type for " + res + ".",
res.getType().isNullable(), is(false));
}

@Test public void testSimplifyCaseCompaction() {
RexNode caseNode = case_(vBool(0), vInt(0), vBool(1), vInt(0), vInt(1));
checkSimplify(caseNode, "CASE(OR(?0.bool0, ?0.bool1), ?0.int0, ?0.int1)");
}

@Test public void testSimplifyCaseCompaction2() {
RexNode caseNode = case_(vBool(0), vInt(0), vBool(1), vInt(1), vInt(1));
checkSimplify(caseNode, "CASE(?0.bool0, ?0.int0, ?0.int1)");
}

@Test public void testSimplifyCaseCompactionDiv() {
// FIXME: RexInterpreter currently evaluates childs beforehand.
simplify = simplify.withParanoid(false);
RexNode caseNode = case_(vBool(0), vInt(0),
eq(div(literal(3), vIntNotNull()), literal(11)), vInt(0),
vInt(1));
// expectation here is that the 2 branches are not merged.
checkSimplify(caseNode,
"CASE(?0.bool0, ?0.int0, =(/(3, ?0.notNullInt0), 11), ?0.int0, ?0.int1)");
}

/* case value branch contains division */
@Test public void testSimplifyCaseDiv1() {
// FIXME: RexInterpreter currently evaluates childs beforehand.
simplify = simplify.withParanoid(false);
RexNode caseNode = case_(
ne(vIntNotNull(), literal(0)),
eq(div(literal(3), vIntNotNull()), literal(11)),
falseLiteral);
checkSimplify(caseNode,
"CASE(<>(?0.notNullInt0, 0), =(/(3, ?0.notNullInt0), 11), false)");
}

/* case condition contains division */
@Test public void testSimplifyCaseDiv2() {
// FIXME: RexInterpreter currently evaluates childs beforehand.
simplify = simplify.withParanoid(false);
RexNode caseNode = case_(
eq(vIntNotNull(), literal(0)), trueLiteral,
gt(div(literal(3), vIntNotNull()), literal(1)), trueLiteral,
falseLiteral);
checkSimplify(caseNode,
"CASE(=(?0.notNullInt0, 0), true, >(/(3, ?0.notNullInt0), 1), true, false)");
}

@Test public void testSimplifyAnd() {
RelDataType booleanNotNullableType =
typeFactory.createTypeWithNullability(
Expand Down
34 changes: 17 additions & 17 deletions core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
Expand Up @@ -106,7 +106,7 @@ LogicalProject(CASECOL=[$0])
<![CDATA[
LogicalProject(CASECOL=[$0])
LogicalFilter(condition=[NOT($0)])
LogicalProject(CASECOL=[CASE(>($5, 1000), null, false)])
LogicalProject(CASECOL=[AND(>($5, 1000), null)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
Expand All @@ -122,7 +122,7 @@ where case when (sal = 1000) then
<Resource name="planAfter">
<![CDATA[
LogicalProject(SAL=[$5])
LogicalFilter(condition=[CASE(=($5, 1000), =($5, 1000), =($5, 2000))])
LogicalFilter(condition=[OR(=($5, 1000), AND(=($5, 2000), <>($5, 1000)))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
Expand Down Expand Up @@ -162,7 +162,7 @@ LogicalProject(SAL=[$5])
</Resource>
<Resource name="planBefore">
<![CDATA[
LogicalProject(EXPR$0=[CASE(=(1, 2), CAST($1):INTEGER, 2)])
LogicalProject(EXPR$0=[CAST(2):INTEGER])
LogicalJoin(condition=[true], joinType=[left])
LogicalValues(tuples=[[{ 1 }]])
LogicalValues(tuples=[[{ 1 }]])
Expand Down Expand Up @@ -434,7 +434,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=[NOT(CASE(=($10, 0), false, IS TRUE(<=($0, $9)), true, >($10, $11), null, <=($0, $9)))])
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)))])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{}], m=[MAX($0)], c=[COUNT()], d=[COUNT($0)])
Expand All @@ -446,7 +446,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=[NOT(CASE(=($10, 0), false, IS TRUE(<=($0, $9)), true, >($10, $11), null, <=($0, $9)))])
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)))])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{}], m=[MAX($0)], c=[COUNT()], d=[COUNT($0)])
Expand All @@ -469,7 +469,7 @@ LogicalProject(EMPNO=[$0])
<Resource name="planAfter">
<![CDATA[
LogicalProject(EMPNO=[$0])
LogicalFilter(condition=[CASE(>($5, 1000), =($0, 1), =($5, 1))])
LogicalFilter(condition=[OR(AND(>($5, 1000), =($0, 1)), =($5, 1))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
Expand Down Expand Up @@ -2194,7 +2194,7 @@ LogicalCalc(expr#0=[{inputs}], expr#1=['TABLE '], expr#2=['t'], U=[$t1],
</Resource>
<Resource name="planBefore">
<![CDATA[
LogicalProject(EXPR$0=[CASE(IS NULL(null), IS NULL(2), =(CAST(null):INTEGER NOT NULL, 2))])
LogicalProject(EXPR$0=[false])
LogicalValues(tuples=[[{ 0 }]])
]]>
</Resource>
Expand Down Expand Up @@ -2527,7 +2527,7 @@ LogicalFilter(condition=[IS NOT DISTINCT FROM($7, 20)])
</Resource>
<Resource name="planAfter">
<![CDATA[
LogicalFilter(condition=[CASE(IS NULL($7), IS NULL(20), =(CAST($7):TINYINT NOT NULL, 20))])
LogicalFilter(condition=[CASE(IS NULL($7), false, =(CAST($7):TINYINT NOT NULL, 20))])
LogicalTableScan(table=[[scott, EMP]])
]]>
</Resource>
Expand Down Expand Up @@ -4398,7 +4398,7 @@ LogicalAggregate(group=[{}], EXPR$0=[COUNT()])
<![CDATA[
LogicalAggregate(group=[{}], EXPR$0=[COUNT()])
LogicalProject($f0=[0])
LogicalFilter(condition=[<($0, 10)])
LogicalFilter(condition=[IS TRUE(<($0, 10))])
LogicalProject(MGR=[$3])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
Expand Down Expand Up @@ -6664,7 +6664,7 @@ LogicalProject(NAME=[$3], SUM_SAL=[$1], C=[$2])
<Resource name="planBefore">
<![CDATA[
LogicalAggregate(group=[{0, 1, 2}])
LogicalProject(DEPTNO=[$7], ENAME=[$1], EXPR$2=[CASE(=(1, 2), CAST(SUBSTRING($1, 1, 2)):VARCHAR(20) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary", null)])
LogicalProject(DEPTNO=[$7], ENAME=[$1], EXPR$2=[null])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
Expand Down Expand Up @@ -6876,7 +6876,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=[CASE(=($10, 0), false, IS TRUE(>($0, $9)), true, >($10, $11), null, >($0, $9))])
LogicalFilter(condition=[OR(AND(IS TRUE(>($0, $9)), <>($10, 0)), AND(>($0, $9), <>($10, 0), IS NOT TRUE(>($0, $9)), <=($10, $11)))])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{}], m=[MIN($0)], c=[COUNT()], d=[COUNT($0)])
Expand All @@ -6888,7 +6888,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=[CASE(=($10, 0), false, IS TRUE(>($0, $9)), true, >($10, $11), null, >($0, $9))])
LogicalFilter(condition=[OR(AND(IS TRUE(>($0, $9)), <>($10, 0)), AND(>($0, $9), <>($10, 0), IS NOT TRUE(>($0, $9)), <=($10, $11)))])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{}], m=[MIN($0)], c=[COUNT()], d=[COUNT($0)])
Expand Down Expand Up @@ -7826,7 +7826,7 @@ LogicalProject(EXPR$0=[CASE(true, CAST($7):INTEGER, null)])
<![CDATA[
LogicalProject(EMPNO=[$0])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
LogicalFilter(condition=[<($0, CASE(=(CASE(=($9, 0), false, IS NOT NULL($12), true, <($10, $9), null, false), true), 10, =(CASE(=($9, 0), false, IS NOT NULL($12), true, <($10, $9), null, false), false), 20, 30))])
LogicalFilter(condition=[<($0, CASE(=(OR(AND(IS NOT NULL($12), <>($9, 0)), AND(<($10, $9), null, <>($9, 0), IS NULL($12))), true), 10, =(OR(AND(IS NOT NULL($12), <>($9, 0)), AND(<($10, $9), null, <>($9, 0), IS NULL($12))), false), 20, 30))])
LogicalJoin(condition=[=($7, $11)], joinType=[left])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
Expand Down Expand Up @@ -8253,7 +8253,7 @@ LogicalProject(DEPTNO=[$0])
<Resource name="planAfter">
<![CDATA[
LogicalProject(SAL=[$5])
LogicalFilter(condition=[NOT(CASE(=($10, 0), false, IS NOT NULL($13), true, <($11, $10), true, false))])
LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), IS TRUE(=($10, 0)))])
LogicalJoin(condition=[AND(=($0, $12), =($2, $14))], joinType=[left])
LogicalJoin(condition=[=($2, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
Expand All @@ -8268,7 +8268,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=[NOT(CASE(=($9, 0), false, IS NOT NULL($12), true, <($10, $9), true, false))])
LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), IS TRUE(=($9, 0)))])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{2}])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{2}])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
Expand Down Expand Up @@ -8345,7 +8345,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=[NOT(CASE(=($9, 0), false, IS NOT NULL($12), true, <($10, $9), true, false))])
LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))), IS TRUE(=($9, 0)))])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
Expand All @@ -8364,7 +8364,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=[NOT(CASE(=($10, 0), false, IS NOT NULL($13), true, <($11, $10), true, false))])
LogicalFilter(condition=[OR(IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))), IS TRUE(=($10, 0)))])
LogicalJoin(condition=[AND(=($0, $12), =($1, $14))], joinType=[left])
LogicalJoin(condition=[=($1, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
Expand Down

0 comments on commit b470a0c

Please sign in to comment.