This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 6548b0e6f7 [CALCITE-7375] ProjectWindowTransposeRule does not
correctly adjust column indices in window bounds
6548b0e6f7 is described below
commit 6548b0e6f7f4a622b37d2b34c964d5f90635a046
Author: lincoln.lil <[email protected]>
AuthorDate: Wed Jan 14 20:15:14 2026 +0800
[CALCITE-7375] ProjectWindowTransposeRule does not correctly adjust column
indices in window bounds
---
.../rel/rules/ProjectWindowTransposeRule.java | 9 ++++--
.../org/apache/calcite/test/RelOptRulesTest.java | 26 +++++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 37 ++++++++++++++++++++++
3 files changed, 70 insertions(+), 2 deletions(-)
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 e606fc8b72..2517633615 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
@@ -31,6 +31,7 @@
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.rex.RexWindowBound;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.BitSets;
@@ -166,9 +167,13 @@ public ProjectWindowTransposeRule(RelBuilderFactory
relBuilderFactory) {
++aggCallIndex;
}
+ // Adjust Window Group RexWindowBound
+ RexWindowBound newLowerBound = group.lowerBound.accept(indexAdjustment);
+ RexWindowBound newUpperBound = group.upperBound.accept(indexAdjustment);
+
groups.add(
- new Window.Group(keys.build(), group.isRows, group.lowerBound,
- group.upperBound, group.exclude, RelCollations.of(orderKeys),
aggCalls));
+ new Window.Group(keys.build(), group.isRows, newLowerBound,
+ newUpperBound, group.exclude, RelCollations.of(orderKeys),
aggCalls));
}
final LogicalWindow newLogicalWindow =
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 7de683e9ac..899635c38c 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -502,6 +502,32 @@ private HepProgram createHypergraphProgram() {
.checkUnchanged();
}
+ /**
+ * Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7375">[CALCITE-7375]
+ * ProjectWindowTransposeRule does not correctly adjust column indices in
window bounds</a>. */
+ @Test void testNestedConstantWindow() {
+ final String sql = "WITH t1 AS (\n"
+ + " SELECT *,\n"
+ + " FIRST_VALUE(deptno) OVER (\n"
+ + " ORDER BY empno\n"
+ + " ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING\n"
+ + " ) AS f1\n"
+ + " FROM emp\n"
+ + ")\n"
+ + "SELECT deptno,\n"
+ + " f1,\n"
+ + " LAST_VALUE(deptno) OVER (\n"
+ + " ORDER BY empno\n"
+ + " ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING\n"
+ + " ) AS f2\n"
+ + "FROM t1";
+ sql(sql)
+ .withPreRule(CoreRules.PROJECT_TO_LOGICAL_PROJECT_AND_WINDOW)
+ .withRule(CoreRules.PROJECT_WINDOW_TRANSPOSE)
+ .check();
+ }
+
/**
* Test case for
* <a
href="https://issues.apache.org/jira/browse/CALCITE-5813">[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 7c56417de6..193b7c87db 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -10725,6 +10725,43 @@ LogicalProject(EXPR$0=[CAST(/($2, $3)):INTEGER NOT
NULL])
LogicalAggregate(group=[{0}], agg#0=[SUM($1)], agg#1=[MIN($2)],
agg#2=[AVG($2)])
LogicalProject(DEPTNO=[$7], SAL=[$5], EMPNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testNestedConstantWindow">
+ <Resource name="sql">
+ <![CDATA[WITH t1 AS (
+ SELECT *,
+ FIRST_VALUE(deptno) OVER (
+ ORDER BY empno
+ ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) AS f1
+ FROM emp
+)
+SELECT deptno,
+ f1,
+ LAST_VALUE(deptno) OVER (
+ ORDER BY empno
+ ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) AS f2
+FROM t1]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(DEPTNO=[$1], F1=[$2], F2=[$3])
+ LogicalWindow(window#0=[window(order by [0] rows between $3 PRECEDING and $4
FOLLOWING aggs [LAST_VALUE($1)])], constants=[[2, 1]])
+ LogicalProject(EMPNO=[$0], DEPTNO=[$7], F1=[$9])
+ LogicalWindow(window#0=[window(order by [0] rows between $9 PRECEDING
and $10 FOLLOWING aggs [FIRST_VALUE($7)])], constants=[[2, 1]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(DEPTNO=[$1], F1=[$2], F2=[$3])
+ LogicalWindow(window#0=[window(order by [0] rows between $3 PRECEDING and $4
FOLLOWING aggs [LAST_VALUE($1)])], constants=[[2, 1]])
+ LogicalWindow(window#0=[window(order by [0] rows between $2 PRECEDING and
$3 FOLLOWING aggs [FIRST_VALUE($1)])], constants=[[2, 1]])
+ LogicalProject(EMPNO=[$0], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>