This is an automated email from the ASF dual-hosted git repository.
zhenchen 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 c251de4eca [CALCITE-7395] ProjectMergeRule incorrectly merges PROJECTs
with correlation variables
c251de4eca is described below
commit c251de4eca57bc7fe60a27cd2cdb6a776fad8c1c
Author: Zhen Chen <[email protected]>
AuthorDate: Sat Jan 24 20:25:27 2026 +0800
[CALCITE-7395] ProjectMergeRule incorrectly merges PROJECTs with
correlation variables
---
.../org/apache/calcite/rel/rules/ProjectMergeRule.java | 7 +++++++
.../java/org/apache/calcite/test/CoreQuidemTest2.java | 1 -
.../java/org/apache/calcite/test/RelOptRulesTest.java | 12 ++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 18 ++++++++++++++++++
4 files changed, 37 insertions(+), 1 deletion(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
index 4608a8c8bc..8441699ad4 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMergeRule.java
@@ -92,6 +92,13 @@ public ProjectMergeRule(boolean force, ProjectFactory
projectFactory) {
final Project bottomProject = call.rel(1);
final RelBuilder relBuilder = call.builder();
+ // Do not merge projects if any of them has correlation variables.
+ // Merging would lose the correlation context needed for proper query
execution.
+ if (!topProject.getVariablesSet().isEmpty()
+ || !bottomProject.getVariablesSet().isEmpty()) {
+ return;
+ }
+
// If one or both projects are permutations, short-circuit the complex
logic
// of building a RexProgram.
final Permutation topPermutation = topProject.getPermutation();
diff --git a/core/src/test/java/org/apache/calcite/test/CoreQuidemTest2.java
b/core/src/test/java/org/apache/calcite/test/CoreQuidemTest2.java
index f0887b7189..865aec400a 100644
--- a/core/src/test/java/org/apache/calcite/test/CoreQuidemTest2.java
+++ b/core/src/test/java/org/apache/calcite/test/CoreQuidemTest2.java
@@ -46,7 +46,6 @@ public static void main(String[] args) throws Exception {
// TODO: The following files involves UNNEST and LEFT_MARK JOIN
paths.remove("sql/measure.iq");
- paths.remove("sql/unnest.iq");
paths.remove("sql/some.iq");
paths.remove("sql/sub-query.iq");
paths.remove("sql/measure-paper.iq");
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 94bb87651f..f9cedb9d81 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -12165,6 +12165,18 @@ private void
checkLoptOptimizeJoinRule(LoptOptimizeJoinRule rule) {
.check();
}
+ /** Test case of
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7395">[CALCITE-7395]
+ * ProjectMergeRule incorrectly merges PROJECTs with correlation
variables</a>. */
+ @Test void testProjectMergeRuleWithCorrelation() {
+ final String sql = "SELECT ARRAY(SELECT y + 1 FROM UNNEST(s.x) y)\n"
+ + "FROM (SELECT ARRAY[1,2,3] as x) s";
+
+ sql(sql)
+ .withRule(CoreRules.PROJECT_MERGE)
+ .checkUnchanged();
+ }
+
/** Test case of
* <a
href="https://issues.apache.org/jira/browse/CALCITE-7369">[CALCITE-7369]
* ProjectToWindowRule loses column alias when optimizing OVER window
queries</a>. */
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 67e86d45b6..785bce7839 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -11821,6 +11821,24 @@ LogicalProject(DEPTNO=[$0])
LogicalAggregate(group=[{}], DUMMY=[COUNT()])
LogicalProject(EMPNO=[$0])
LogicalTableScan(table=[[scott, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testProjectMergeRuleWithCorrelation">
+ <Resource name="sql">
+ <![CDATA[SELECT ARRAY(SELECT y + 1 FROM UNNEST(s.x) y)
+FROM (SELECT ARRAY[1,2,3] as x) s]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(variablesSet=[[$cor0]], EXPR$0=[ARRAY({
+LogicalProject(EXPR$0=[+($0, 1)])
+ Uncollect
+ LogicalProject(X=[$cor0.X])
+ LogicalValues(tuples=[[{ 0 }]])
+})])
+ LogicalProject(X=[ARRAY(1, 2, 3)])
+ LogicalValues(tuples=[[{ 0 }]])
]]>
</Resource>
</TestCase>