This is an automated email from the ASF dual-hosted git repository. jcamacho pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit b8546979e18294d756462d46c35a053f9fdcfb77 Author: Zoltan Haindrich <k...@rxd.hu> AuthorDate: Fri Feb 15 12:14:22 2019 +0100 [CALCITE-2852] RexNode simplification does not traverse unknown functions Earlier simplification was not attempted below arithmetic operators. Expressions like: 1 + CASE WHEN TRUE THEN 1 ELSE 2 END were not simplified. Close apache/calcite#1053 --- .../main/java/org/apache/calcite/rex/RexSimplify.java | 16 ++++++++++++++++ .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 5 ++--- .../java/org/apache/calcite/test/RexProgramTest.java | 10 ++++++++++ .../org/apache/calcite/test/RelOptRulesTest.xml | 4 ++-- .../org/apache/calcite/test/SqlToRelConverterTest.xml | 17 ++++++++++------- 5 files changed, 40 insertions(+), 12 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 fb98d8d..d9f4cc2 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -284,8 +284,24 @@ public class RexSimplify { case NOT_EQUALS: return simplifyComparison((RexCall) e, unknownAs); default: + if (e.getClass() == RexCall.class) { + return simplifyGenericNode((RexCall) e); + } else { + return e; + } + } + } + + /** + * Runs simplification inside a non-specialized node. + */ + private RexNode simplifyGenericNode(RexCall e) { + final List<RexNode> operands = new ArrayList<>(e.operands); + simplifyList(operands, UNKNOWN); + if (e.operands.equals(operands)) { return e; } + return rexBuilder.makeCall(e.getType(), e.getOperator(), operands); } // e must be a comparison (=, >, >=, <, <=, !=) diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index 304787e..b5afdf5 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -323,10 +323,9 @@ public class RelToSqlConverterTest { + "from \"foodmart\".\"product\""; final String expectedPostgresql = "SELECT CASE WHEN (COUNT(\"net_weight\")" + " OVER (ORDER BY \"product_id\" ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)) > 0 " - + "THEN CAST(COALESCE(SUM(\"net_weight\")" + + "THEN COALESCE(SUM(\"net_weight\")" + " OVER (ORDER BY \"product_id\" ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), 0)" - + " AS DOUBLE PRECISION) " - + "ELSE NULL END / (COUNT(\"net_weight\")" + + " ELSE NULL END / (COUNT(\"net_weight\")" + " OVER (ORDER BY \"product_id\" ROWS BETWEEN 3 PRECEDING AND CURRENT ROW))\n" + "FROM \"foodmart\".\"product\""; sql(query) 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 9e4ebf9..724b0a6 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java @@ -1772,6 +1772,16 @@ public class RexProgramTest extends RexProgramBuilderBase { assertThat(result, is(condition)); } + @Test public void testSimplifyRecurseIntoArithmetics() { + checkSimplify( + plus(literal(1), + case_( + falseLiteral, literal(1), + trueLiteral, literal(2), + literal(3))), + "+(1, 2)"); + } + @Test public void testSimplifyCaseBranchesCollapse() { // case when x is true then 1 when x is not true then 1 else 2 end // => case when x is true or x is not true then 1 else 2 end 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 4844d8e..2cd7546 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -6949,7 +6949,7 @@ LogicalProject(NEWCOL=[+($0, CASE(=('a', 'a'), 1, null:INTEGER))]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalProject(NEWCOL=[+($0, CAST(1):INTEGER)]) +LogicalProject(NEWCOL=[+($0, 1)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -6968,7 +6968,7 @@ LogicalProject(NEWCOL=[+($0, CASE(=('a', 'a'), 1, null:INTEGER))]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalProject(NEWCOL=[+($0, CAST(1):INTEGER)]) +LogicalProject(NEWCOL=[+($0, 1)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> 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 bd617d1..7642f98 100644 --- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml @@ -775,7 +775,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), $SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null:INTEGER)], 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:INTEGER), COUNT($5) OVER (PARTITION BY $2 ORDER B [...] +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:INTEGER)], EXPR$1=[CAST(/(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:INTEGER), COUNT($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETW [...] LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -819,7 +819,7 @@ from emp]]> </Resource> <Resource name="plan"> <![CDATA[ -LogicalProject(EXPR$0=[*(CAST($0):INTEGER NOT NULL, 13:INTERVAL YEAR TO MONTH)]) +LogicalProject(EXPR$0=[*($0, 13:INTERVAL YEAR TO MONTH)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -832,7 +832,7 @@ from emp]]> </Resource> <Resource name="plan"> <![CDATA[ -LogicalProject(EXPR$0=[*(CAST($0):INTEGER NOT NULL, 3660000:INTERVAL HOUR TO MINUTE)]) +LogicalProject(EXPR$0=[*($0, 3660000:INTERVAL HOUR TO MINUTE)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -1267,7 +1267,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), $SUM0($5) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null:INTEGER)], 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:REAL), COUNT(CAST [...] +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:INTEGER)], EXPR$1=[/(CASE(>(COUNT(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 0), $SUM0(CAST($5):REAL NOT NULL) OVER (PARTITION BY $2 ORDER BY $4 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), null:REAL), COUNT(CAST($5):REAL N [...] LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -5475,7 +5475,8 @@ LogicalAggregate(group=[{0}], EXPR$1=[COLLECT($1) WITHIN GROUP ([2])], EXPR$2=[C </TestCase> <TestCase name="testOrderByRemoval1"> <Resource name="sql"> - <![CDATA[select * from (select empno from emp order by deptno offset 0) t + <![CDATA[select * from ( + select empno from emp order by deptno offset 0) t order by empno desc]]> </Resource> <Resource name="plan"> @@ -5488,7 +5489,8 @@ LogicalSort(sort0=[$0], dir0=[DESC]) </TestCase> <TestCase name="testOrderByRemoval2"> <Resource name="sql"> - <![CDATA[select * from (select empno from emp order by deptno offset 1) t + <![CDATA[select * from ( + select empno from emp order by deptno offset 1) t order by empno desc]]> </Resource> <Resource name="plan"> @@ -5503,7 +5505,8 @@ LogicalSort(sort0=[$0], dir0=[DESC]) </TestCase> <TestCase name="testOrderByRemoval3"> <Resource name="sql"> - <![CDATA[select * from (select empno from emp order by deptno limit 10) t + <![CDATA[select * from ( + select empno from emp order by deptno limit 10) t order by empno]]> </Resource> <Resource name="plan">