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 891ffc41e0 [CALCITE-6744] RelMetadataQuery.getColumnOrigins should 
return null when column origin includes correlation variables
891ffc41e0 is described below

commit 891ffc41e0b0cee3e2eea8e1c01b4bbc920a70e3
Author: suibianwanwan <[email protected]>
AuthorDate: Fri Jan 17 10:29:28 2025 +0800

    [CALCITE-6744] RelMetadataQuery.getColumnOrigins should return null when 
column origin includes correlation variables
---
 .../calcite/rel/metadata/RelMdColumnOrigins.java   | 23 ++++++++++++---
 .../org/apache/calcite/test/RelMetadataTest.java   | 34 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
index cbf48990ff..a5e6da109a 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
@@ -32,12 +32,15 @@ import org.apache.calcite.rel.core.Sort;
 import org.apache.calcite.rel.core.TableFunctionScan;
 import org.apache.calcite.rel.core.TableModify;
 import org.apache.calcite.rel.core.TableScan;
+import org.apache.calcite.rex.RexCorrelVariable;
+import org.apache.calcite.rex.RexFieldAccess;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLocalRef;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexShuttle;
 import org.apache.calcite.rex.RexVisitor;
 import org.apache.calcite.rex.RexVisitorImpl;
+import org.apache.calcite.util.Util;
 
 import org.checkerframework.checker.nullness.qual.Nullable;
 import org.checkerframework.checker.nullness.qual.PolyNull;
@@ -84,9 +87,10 @@ public class RelMdColumnOrigins
       Set<RelColumnOrigin> inputSet =
           mq.getColumnOrigins(rel.getInput(), iInput);
       inputSet = createDerivedColumnOrigins(inputSet);
-      if (inputSet != null) {
-        set.addAll(inputSet);
+      if (inputSet == null) {
+        return null;
       }
+      set.addAll(inputSet);
     }
     return set;
   }
@@ -290,7 +294,7 @@ public class RelMdColumnOrigins
     return set;
   }
 
-  private static Set<RelColumnOrigin> getMultipleColumns(RexNode rexNode, 
RelNode input,
+  private static @Nullable Set<RelColumnOrigin> getMultipleColumns(RexNode 
rexNode, RelNode input,
       final RelMetadataQuery mq) {
     final Set<RelColumnOrigin> set = new HashSet<>();
     final RexVisitor<Void> visitor =
@@ -303,8 +307,19 @@ public class RelMdColumnOrigins
             }
             return null;
           }
+
+          @Override public Void visitFieldAccess(RexFieldAccess fieldAccess) {
+            if (fieldAccess.getReferenceExpr() instanceof RexCorrelVariable) {
+              throw Util.FoundOne.NULL;
+            }
+            return null;
+          }
         };
-    rexNode.accept(visitor);
+    try {
+      rexNode.accept(visitor);
+    } catch (Util.FoundOne one) {
+      return null;
+    }
     return set;
   }
 }
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 3610516ec6..ea5fd08046 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -143,6 +143,7 @@ import java.util.stream.IntStream;
 import static com.google.common.collect.ImmutableList.toImmutableList;
 
 import static org.apache.calcite.test.Matchers.hasFieldNames;
+import static org.apache.calcite.test.Matchers.hasTree;
 import static org.apache.calcite.test.Matchers.isAlmost;
 import static org.apache.calcite.test.Matchers.sortsAs;
 
@@ -458,6 +459,39 @@ public class RelMetadataTest {
         equalTo("SAL"));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6744";>[CALCITE-6744]
+   * RelMetadataQuery.getColumnOrigins should return null when column origin
+   * includes correlation variables</a>. */
+  @Test void testColumnOriginsForCorrelate() {
+    final String sql = "select (select max(dept.name || '_' || emp.ename)"
+        + "from dept where emp.deptno = dept.deptno) from emp";
+    final RelMetadataFixture fixture = sql(sql);
+
+    final HepProgramBuilder programBuilder = HepProgram.builder();
+    programBuilder.addRuleInstance(CoreRules.PROJECT_SUB_QUERY_TO_CORRELATE);
+    final HepPlanner planner = new HepPlanner(programBuilder.build());
+    planner.setRoot(fixture.toRel());
+    final RelNode relNode = planner.findBestExp();
+
+    String expect = "LogicalProject(EXPR$0=[$9])\n"
+        + "  LogicalCorrelate(correlation=[$cor1], joinType=[left], 
requiredColumns=[{1, 7}])\n"
+        + "    LogicalTableScan(table=[[CATALOG, SALES, EMP]])\n"
+        + "    LogicalAggregate(group=[{}], EXPR$0=[MAX($0)])\n"
+        + "      LogicalProject($f0=[||(||($1, '_'), $cor1.ENAME)])\n"
+        + "        LogicalFilter(condition=[=($cor1.DEPTNO, $0)])\n"
+        + "          LogicalTableScan(table=[[CATALOG, SALES, DEPT]])\n";
+    assertThat(relNode, hasTree(expect));
+
+    // check correlate input column origins
+    final RelMetadataFixture.MetadataConfig metadataConfig = 
fixture.metadataConfig;
+    final RelMetadataQuery mq =
+        new RelMetadataQuery(metadataConfig.getDefaultHandlerProvider());
+    Aggregate aggregate = (Aggregate) relNode.getInput(0).getInput(1);
+    Set<RelColumnOrigin> origins = mq.getColumnOrigins(aggregate, 0);
+    assertNull(origins);
+  }
+
   // ----------------------------------------------------------------------
   // Tests for getRowCount, getMinRowCount, getMaxRowCount
   // ----------------------------------------------------------------------

Reply via email to