This is an automated email from the ASF dual-hosted git repository.

asolimando 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 c425a5fa09 [CALCITE-7843] RelMdExpressionLineage should support Window
c425a5fa09 is described below

commit c425a5fa096c723a8c669df1c7cf2d92aa6bfd61
Author: Alessandro Solimando <[email protected]>
AuthorDate: Thu Oct 8 16:52:09 2026 +0200

    [CALCITE-7843] RelMdExpressionLineage should support Window
---
 .../rel/metadata/RelMdExpressionLineage.java       | 17 ++++++++++++
 .../org/apache/calcite/test/RelMetadataTest.java   | 30 ++++++++++++++++++++++
 ...GeneratedMetadata_ExpressionLineageHandler.java |  2 ++
 3 files changed, 49 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
index 3025ee1d4a..7ff467d1a7 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
@@ -32,6 +32,7 @@
 import org.apache.calcite.rel.core.TableModify;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Union;
+import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
@@ -440,6 +441,22 @@ protected RelMdExpressionLineage() {}
     return mq.getExpressionLineage(rel.getInput(), outputExpression);
   }
 
+  /**
+   * Expression lineage from {@link Window}.
+   *
+   * <p>If the expression references window function results, we cannot extract
+   * the lineage and we return null.
+   */
+  public @Nullable Set<RexNode> getExpressionLineage(Window rel,
+      RelMetadataQuery mq, RexNode outputExpression) {
+    final int inputFieldCount = rel.getInput().getRowType().getFieldCount();
+    final ImmutableBitSet inputFieldsUsed = extractInputRefs(outputExpression);
+    if (inputFieldsUsed.nextSetBit(inputFieldCount) >= 0) {
+      return null;
+    }
+    return mq.getExpressionLineage(rel.getInput(), outputExpression);
+  }
+
   /**
    * Expression lineage from Calc.
    */
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java 
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 76ad8bf50e..daa4fc66c7 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -59,6 +59,7 @@
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Union;
 import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.logical.LogicalAggregate;
 import org.apache.calcite.rel.logical.LogicalExchange;
@@ -95,6 +96,7 @@
 import org.apache.calcite.rel.rules.CoreRules;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexCorrelVariable;
@@ -4574,6 +4576,34 @@ private void assertExpressionLineage(
     assertThat(resultString, is("+([CATALOG, SALES, EMP].#0.$5, 1)"));
   }
 
+  /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-7843";>[CALCITE-7843]
+   * RelMdExpressionLineage should support Window</a>. */
+  @Test void testExpressionLineageWindow() {
+    final RelNode rel =
+        sql("select empno, row_number() over (order by sal) from emp").toRel();
+    final HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(CoreRules.PROJECT_TO_LOGICAL_PROJECT_AND_WINDOW)
+        .build();
+    final HepPlanner planner = new HepPlanner(program);
+    planner.setRoot(rel);
+    final RelNode window = planner.findBestExp().getInput(0);
+    assertThat(window, instanceOf(Window.class));
+    final RelMetadataQuery mq = window.getCluster().getMetadataQuery();
+    final List<RelDataTypeField> fields = window.getRowType().getFieldList();
+
+    // empno is column 0 of the Window input
+    final Set<RexNode> r1 =
+        mq.getExpressionLineage(window, RexInputRef.of(0, fields));
+    assertThat(r1, hasSize(1));
+    final String resultString = r1.iterator().next().toString();
+    assertThat(resultString, is("[CATALOG, SALES, EMP].#0.$0"));
+
+    // row_number() is the last column, computed by the Window
+    final Set<RexNode> r2 =
+        mq.getExpressionLineage(window, RexInputRef.of(fields.size() - 1, 
fields));
+    assertNull(r2);
+  }
+
   /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-7070";>[CALCITE-7070]
    * FILTER_REDUCE_EXPRESSIONS crashes on expression BETWEEN ( NULL) AND 
X</a>. */
   @Test void testJoinCrash() {
diff --git 
a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExpressionLineageHandler.java
 
b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExpressionLineageHandler.java
index 5e0c668348..e56f3c6c60 100644
--- 
a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExpressionLineageHandler.java
+++ 
b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExpressionLineageHandler.java
@@ -88,6 +88,8 @@ private java.util.Set getExpressionLineage_(
       return 
provider0.getExpressionLineage((org.apache.calcite.rel.core.TableScan) r, mq, 
a2);
     } else if (r instanceof org.apache.calcite.rel.core.Union) {
       return 
provider0.getExpressionLineage((org.apache.calcite.rel.core.Union) r, mq, a2);
+    } else if (r instanceof org.apache.calcite.rel.core.Window) {
+      return 
provider0.getExpressionLineage((org.apache.calcite.rel.core.Window) r, mq, a2);
     } else if (r instanceof org.apache.calcite.rel.RelNode) {
       return provider0.getExpressionLineage((org.apache.calcite.rel.RelNode) 
r, mq, a2);
     } else {

Reply via email to