This is an automated email from the ASF dual-hosted git repository.
silun 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 3e8a082445 [CALCITE-7372] TopDownGeneralDecorrelator will throw an
error when the JOIN condition has correlation
3e8a082445 is described below
commit 3e8a082445090d529b12742183a3f9a14af3b685
Author: Zhen Chen <[email protected]>
AuthorDate: Wed Jan 14 11:14:48 2026 +0800
[CALCITE-7372] TopDownGeneralDecorrelator will throw an error when the JOIN
condition has correlation
---
.../sql2rel/TopDownGeneralDecorrelator.java | 15 ++++++--
core/src/test/resources/sql/new-decorr.iq | 45 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 3 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
b/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
index d3ccaa334d..10b9a411ff 100644
---
a/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
+++
b/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
@@ -680,11 +680,13 @@ public RelNode unnestInternal(Join join, boolean
allowEmptyOutputFromRewrite) {
UnnestedQuery rightInfo;
if (!leftHasCorrelation && !join.getJoinType().generatesNullsOnRight()
- && join.getJoinType().projectsRight()) {
- // there is no need to push down domain D to left side when both
following conditions
+ && join.getJoinType().projectsRight()
+ && rightHasCorrelation) {
+ // there is no need to push down domain D to left side when all
following conditions
// are satisfied:
// 1. there is no correlation on left side
// 2. join type will not generate NULL values on right side and will
project right
+ // 3. there is correlation on right side to carry domain D
// In this case, the left side will start a decorrelation independently
newLeft = decorrelateQuery(join.getLeft(), builder);
Map<Integer, Integer> leftOldToNewOutputs = new HashMap<>();
@@ -692,16 +694,23 @@ public RelNode unnestInternal(Join join, boolean
allowEmptyOutputFromRewrite) {
.forEach(i -> leftOldToNewOutputs.put(i, i));
leftInfo = new UnnestedQuery(join.getLeft(), newLeft, new TreeMap<>(),
leftOldToNewOutputs);
} else {
+ // when neither the left nor the right side has correlation,
+ // but the join condition has correlation, domain D is pushed down to
the left by default.
newLeft = unnest(join.getLeft(), allowEmptyOutputFromRewrite);
pushDownToLeft = true;
leftInfo = requireNonNull(mapRelToUnnestedQuery.get(join.getLeft()));
}
if (!rightHasCorrelation && !join.getJoinType().generatesNullsOnLeft()) {
- // there is no need to push down domain D to right side when both
following conditions
+ // there is no need to push down domain D to right side when all
following conditions
// are satisfied:
// 1. there is no correlation on right side
// 2. join type will not generate NULL values on left side
+ // 3. there is domain D pushed down to left side
// In this case, the right side will start a decorrelation independently
+
+ // either the left or the right side must carry domain D,
+ // and rightHasCorrelation is false, pushDownToLeft must be true here
+ assert pushDownToLeft;
newRight = decorrelateQuery(join.getRight(), builder);
Map<Integer, Integer> rightOldToNewOutputs = new HashMap<>();
IntStream.range(0, newRight.getRowType().getFieldCount())
diff --git a/core/src/test/resources/sql/new-decorr.iq
b/core/src/test/resources/sql/new-decorr.iq
new file mode 100644
index 0000000000..148d4721ac
--- /dev/null
+++ b/core/src/test/resources/sql/new-decorr.iq
@@ -0,0 +1,45 @@
+# new-decorr.iq
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is used to test for bugs associated with new decorrelator.
+# Most of the test cases here come from the .iq file removed in
CoreQuidemTest2.
+# This file maybe can be deleted after these .iq files are made available.
+
+!use post
+!set outputformat mysql
+
+# [CALCITE-7372] TopDownGeneralDecorrelator will throw an error when the JOIN
condition has correlation
+# This case comes from sub-query.iq [CALCITE-7257]
+WITH t0(t0a, t0b) AS (VALUES (1, 1), (2, 0)),
+ t1(t1a, t1b, t1c) AS (VALUES (1, 1, 3)),
+ t2(t2a, t2b, t2c) AS (VALUES (1, 1, 5), (2, 2, 7))
+SELECT * FROM t0 WHERE t0a <
+(SELECT sum(t1c) FROM
+ (SELECT t1c
+ FROM t1 JOIN t2 ON (t1a < t0a AND t2b >= t1b))
+);
++-----+-----+
+| T0A | T0B |
++-----+-----+
+| 2 | 0 |
++-----+-----+
+(1 row)
+
+!ok
+
+# End new-decorr.iq