From 2bf0941296d5a472ba101543a9752ef928b588f8 Mon Sep 17 00:00:00 2001 From: Mihai Budiu Date: Thu, 26 Dec 2024 18:28:04 -0800 Subject: [PATCH] [CALCITE-6746] Optimization rule ProjectWindowTranspose is unsound Signed-off-by: Mihai Budiu --- .../rel/rules/ProjectWindowTransposeRule.java | 3 +++ .../org/apache/calcite/test/RelOptRulesTest.java | 16 ++++++++++++++++ .../org/apache/calcite/test/RelOptRulesTest.xml | 15 +++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java index 1576bda75a7b..b2c366f14d55 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java @@ -217,6 +217,9 @@ private static ImmutableBitSet findReference(final Project project, } } + group.lowerBound.accept(referenceFinder); + group.upperBound.accept(referenceFinder); + // Reference in Order-By for (RelFieldCollation relFieldCollation : group.orderKeys.getFieldCollations()) { if (relFieldCollation.getFieldIndex() < windowInputColumn) { 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 8fd418224cc1..e7d33252634c 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -346,6 +346,22 @@ private static boolean skipItem(RexNode expr) { .check(); } + /** + * Test case for + * [CALCITE-6746] Optimization rule ProjectWindowTranspose is unsound. */ + @Test void testConstantWindow() { + final String sql = "with empsalary(dept, empno, salary, enroll_date) as " + + "(VALUES ('x', 10, 5200, DATE '2007-08-01'), (NULL, NULL, NULL, NULL))\n" + + "select sum(salary) " + + "OVER (order by enroll_date range between INTERVAL 365 DAYS preceding and " + + "INTERVAL 365 DAYS following),\n" + + "salary, enroll_date FROM empsalary"; + sql(sql) + .withPreRule(CoreRules.PROJECT_TO_LOGICAL_PROJECT_AND_WINDOW) + .withRule(CoreRules.PROJECT_WINDOW_TRANSPOSE) + .checkUnchanged(); + } + /** * Test case for * [CALCITE-5813] 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 90f22fee1236..1b2b8950322a 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -1644,6 +1644,21 @@ case when cast(ename as double) < 5 then 0.0 ($1, 'abc'), $1, null:VARCHAR(20))):DOUBLE, 5.0E0), 0.0E0:DOUBLE, CASE(IS NOT NULL(CAST(CASE(>($1, 'abc'), $1, null:VARCHAR(20))):DOUBLE), CAST(CAST(CASE(>($1, 'abc'), $1, null:VARCHAR(20))):DOUBLE):DOUBLE NOT NULL, 1.0E0:DOUBLE))]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) +]]> + + + + + + + + ($3, 0), $4, null:INTEGER)], SALARY=[$0], ENROLL_DATE=[$1]) + LogicalWindow(window#0=[window(order by [1] range between $2 PRECEDING and $2 FOLLOWING aggs [COUNT($0), SUM($0)])]) + LogicalProject(EXPR$2=[$2], EXPR$3=[$3], $2=[*(365, 86400000:INTERVAL DAY)]) + LogicalValues(tuples=[[{ 'x', 10, 5200, 2007-08-01 }, { null, null, null, null }]]) ]]>