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
// ----------------------------------------------------------------------