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">

Reply via email to