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>

Reply via email to