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 c3fd74a [CALCITE-2841] Simplification: push negation into Case
expression
c3fd74a is described below
commit c3fd74a897ca1b469b6b776baeaa3c660ce5876a
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Thu Oct 4 15:25:29 2018 +0200
[CALCITE-2841] Simplification: push negation into Case expression
Earlier NOT was not pushed into CASE expressions.
Also ensure that recursion under NOT happens.
---
.../java/org/apache/calcite/rex/RexSimplify.java | 26 +++++++++++++++++++++-
.../org/apache/calcite/test/RexProgramTest.java | 16 +++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 4 ++--
.../apache/calcite/test/SqlToRelConverterTest.xml | 4 ++--
core/src/test/resources/sql/some.iq | 2 +-
core/src/test/resources/sql/sub-query.iq | 14 ++++++------
6 files changed, 53 insertions(+), 13 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 ab29c96..7ae8195 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -507,7 +507,31 @@ public class RexSimplify {
return simplify(
rexBuilder.makeCall(SqlStdOperatorTable.AND, newOperands),
unknownAs);
}
- return call;
+ if (a.getKind() == SqlKind.CASE) {
+ final List<RexNode> newOperands = new ArrayList<>();
+ List<RexNode> operands = ((RexCall) a).getOperands();
+ for (int i = 0; i < operands.size(); i += 2) {
+ if (i + 1 == operands.size()) {
+ newOperands.add(rexBuilder.makeCall(SqlStdOperatorTable.NOT,
operands.get(i + 0)));
+ } else {
+ newOperands.add(operands.get(i + 0));
+ newOperands.add(rexBuilder.makeCall(SqlStdOperatorTable.NOT,
operands.get(i + 1)));
+ }
+ }
+ return simplify(
+ rexBuilder.makeCall(SqlStdOperatorTable.CASE, newOperands),
unknownAs);
+ }
+ RexNode a2 = simplify(a, unknownAs.negate());
+ if (a == a2) {
+ return call;
+ }
+ if (a2.isAlwaysTrue()) {
+ return rexBuilder.makeLiteral(false);
+ }
+ if (a2.isAlwaysFalse()) {
+ return rexBuilder.makeLiteral(true);
+ }
+ return rexBuilder.makeCall(SqlStdOperatorTable.NOT, a2);
}
private RexNode simplifyIs(RexCall call) {
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 3ff9260..3234050 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -1902,6 +1902,22 @@ public class RexProgramTest extends
RexProgramBuilderBase {
checkSimplify(caseNode, "<=(/(?0.notNullInt0, 1), 1)");
}
+ @Test public void testPushNotIntoCase() {
+ checkSimplify(
+ not(
+ case_(
+ 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))");
+ }
+
+ @Test public void testNotRecursion() {
+ checkSimplify(
+ not(coalesce(nullBool, trueLiteral)),
+ "false");
+ }
+
@Test public void testSimplifyAnd() {
RelDataType booleanNotNullableType =
typeFactory.createTypeWithNullability(
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 5accc18..8c7e46c 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -8562,7 +8562,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=[OR(=($5, 4), NOT(CASE(IS NOT NULL($10), true,
false)))])
+ LogicalFilter(condition=[OR(=($5, 4), IS NULL($10))])
LogicalJoin(condition=[=($0, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], i=[true])
@@ -8573,7 +8573,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=[OR(=($5, 4), NOT(CASE(IS NOT NULL($10), true,
false)))])
+ LogicalFilter(condition=[OR(=($5, 4), IS NULL($10))])
LogicalJoin(condition=[=($0, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], i=[true])
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 7642f98..fbe4df8 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -2098,7 +2098,7 @@ from emp]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[NOT(CASE(=($9, 0), false, IS NOT NULL($13),
true, IS NULL($11), null:BOOLEAN, <($10, $9), null:BOOLEAN, false))])
+LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(<($10, $9), null, <>($9,
0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), >=($10, $9)))])
LogicalJoin(condition=[=($11, $12)], joinType=[left])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10],
DEPTNO0=[$7])
LogicalJoin(condition=[true], joinType=[inner])
@@ -2242,7 +2242,7 @@ from emp]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[NOT(CASE(=($9, 0), false, IS NOT NULL($13),
true, IS NULL($11), null:BOOLEAN, <($10, $9), null:BOOLEAN, false))])
+LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(<($10, $9), null, <>($9,
0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), >=($10, $9)))])
LogicalJoin(condition=[=($11, $12)], joinType=[left])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10],
DEPTNO0=[$7])
LogicalJoin(condition=[true], joinType=[inner])
diff --git a/core/src/test/resources/sql/some.iq
b/core/src/test/resources/sql/some.iq
index df3e99b..fbceee7 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=[<=($t8, $t0)], expr#15=[IS TRUE($t14)],
expr#16=[true], expr#17=[>($t1, $t2)], expr#18=[null:NULL], expr#19=[CASE($t12,
$t13, $t15, $t16, $t17, $t18, $t14)], expr#20=[NOT($t19)], EMPNO=[$t3],
ENAME=[$t4], JOB=[$t5], MGR=[$t6], HIREDATE=[$t7], SAL=[$t8], COMM=[$t9],
DEPTNO=[$t10], X=[$t20])
+EnumerableCalc(expr#0..10=[{inputs}], expr#11=[0], expr#12=[=($t1, $t11)],
expr#13=[>($t1, $t2)], expr#14=[null:BOOLEAN], expr#15=[<>($t1, $t11)],
expr#16=[<=($t8, $t0)], expr#17=[IS NOT TRUE($t16)], expr#18=[AND($t13, $t14,
$t15, $t17)], expr#19=[>($t8, $t0)], expr#20=[<=($t1, $t2)], expr#21=[AND($t19,
$t15, $t17, $t20)], expr#22=[OR($t12, $t18, $t21)], EMPNO=[$t3], ENAME=[$t4],
JOB=[$t5], MGR=[$t6], HIREDATE=[$t7], SAL=[$t8], COMM=[$t9], DEPTNO=[$t10],
X=[$t22])
EnumerableJoin(condition=[true], joinType=[inner])
EnumerableAggregate(group=[{}], m=[MAX($6)], c=[COUNT()], d=[COUNT($6)])
EnumerableTableScan(table=[[scott, EMP]])
diff --git a/core/src/test/resources/sql/sub-query.iq
b/core/src/test/resources/sql/sub-query.iq
index e75a690..b9f6b3f 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -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=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[null:INTEGER], expr#9=[IS
NULL($t8)], expr#10=[IS NOT NULL($t2)], expr#11=[true], expr#12=[CASE($t4, $t5,
$t6, $t7, $t9, $t7, $t10, $t11, $t5)], expr#13=[NOT($t12)], SAL=[$t1],
EXPR$1=[$t13])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)],
expr#5=[null:BOOLEAN], expr#6=[OR($t4, $t5)], SAL=[$t1], EXPR$1=[$t6])
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=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[IS NOT NULL($t2)],
expr#9=[true], expr#10=[CASE($t4, $t5, $t6, $t7, $t8, $t9, $t5)],
expr#11=[NOT($t10)], SAL=[$t1], EXPR$1=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false],
expr#6=[=($t2, $t5)], expr#7=[IS TRUE($t6)], expr#8=[null:BOOLEAN],
expr#9=[AND($t7, $t8)], expr#10=[IS NOT TRUE($t6)], expr#11=[IS NULL($t2)],
expr#12=[AND($t10, $t11)], expr#13=[OR($t4, $t9, $t12)], SAL=[$t1],
EXPR$1=[$t13])
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=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[null:INTEGER], expr#9=[IS
NULL($t8)], expr#10=[IS NOT NULL($t2)], expr#11=[true], expr#12=[CASE($t4, $t5,
$t6, $t7, $t9, $t7, $t10, $t11, $t5)], expr#13=[NOT($t12)], SAL=[$t1],
EXPR$1=[$t13])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)],
expr#5=[null:BOOLEAN], expr#6=[OR($t4, $t5)], SAL=[$t1], EXPR$1=[$t6])
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=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[null:INTEGER], expr#9=[IS
NULL($t8)], expr#10=[IS NOT NULL($t2)], expr#11=[true], expr#12=[CASE($t4, $t5,
$t6, $t7, $t9, $t7, $t10, $t11, $t5)], expr#13=[NOT($t12)], SAL=[$t1],
EXPR$1=[$t13])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)],
expr#5=[null:BOOLEAN], expr#6=[OR($t4, $t5)], SAL=[$t1], EXPR$1=[$t6])
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=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[null:INTEGER], expr#9=[IS
NULL($t8)], expr#10=[IS NOT NULL($t2)], expr#11=[true], expr#12=[CASE($t4, $t5,
$t6, $t7, $t9, $t7, $t10, $t11, $t5)], expr#13=[NOT($t12)], SAL=[$t1],
EXPR$1=[$t13])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)],
expr#5=[null:BOOLEAN], expr#6=[OR($t4, $t5)], SAL=[$t1], EXPR$1=[$t6])
EnumerableJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
@@ -1218,7 +1218,7 @@ from "scott".emp;
(14 rows)
!ok
-EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT NULL($t2)], expr#4=[true],
expr#5=[false], expr#6=[CASE($t3, $t4, $t5)], expr#7=[NOT($t6)], SAL=[$t1],
EXPR$1=[$t7])
+EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NULL($t2)], SAL=[$t1],
EXPR$1=[$t3])
EnumerableJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
@@ -1252,7 +1252,7 @@ from "scott".emp;
(14 rows)
!ok
-EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false],
expr#6=[=($t2, $t5)], expr#7=[null:NULL], expr#8=[IS NOT NULL($t2)],
expr#9=[true], expr#10=[CASE($t4, $t5, $t6, $t7, $t8, $t9, $t5)],
expr#11=[NOT($t10)], SAL=[$t1], EXPR$1=[$t11])
+EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false],
expr#6=[=($t2, $t5)], expr#7=[IS TRUE($t6)], expr#8=[null:BOOLEAN],
expr#9=[AND($t7, $t8)], expr#10=[IS NOT TRUE($t6)], expr#11=[IS NULL($t2)],
expr#12=[AND($t10, $t11)], expr#13=[OR($t4, $t9, $t12)], SAL=[$t1],
EXPR$1=[$t13])
EnumerableJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])