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 7be1fc59b4 [CALCITE-7409] MERGE JOIN condition cannot contain IS NOT
DISTINCT FROM
7be1fc59b4 is described below
commit 7be1fc59b475caa7da0b04a8537ab89e1f374f87
Author: Zhen Chen <[email protected]>
AuthorDate: Thu Feb 5 19:40:19 2026 +0800
[CALCITE-7409] MERGE JOIN condition cannot contain IS NOT DISTINCT FROM
---
.../enumerable/EnumerableMergeJoinRule.java | 8 ++++
core/src/test/resources/sql/sub-query.iq | 46 ++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
index 624db0a604..f78423edbd 100644
---
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
+++
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
@@ -31,6 +31,7 @@
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -60,6 +61,13 @@ protected EnumerableMergeJoinRule(Config config) {
@Override public @Nullable RelNode convert(RelNode rel) {
Join join = (Join) rel;
+ // TODO: support IS NOT DISTINCT FROM condition as join keys of MergeJoin.
+ // MergeJoin cannot handle IS NOT DISTINCT FROM because it stops at NULL
values
+ // while IS NOT DISTINCT FROM treats NULL = NULL as true.
+ if (RexUtil.findOperatorCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+ join.getCondition()) != null) {
+ return null;
+ }
// EnumerableMergeJoin cannot use IS NOT DISTINCT FROM condition as join
keys. More details
// in EnumerableMergeJoin.java.
final JoinInfo info =
diff --git a/core/src/test/resources/sql/sub-query.iq
b/core/src/test/resources/sql/sub-query.iq
index a9440f6f43..20c7f19472 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -8665,4 +8665,50 @@ FROM dept;
(4 rows)
!ok
+
+# [CALCITE-7409] MERGE JOIN condition cannot contain IS NOT DISTINCT FROM
+select e.ename,
+ (select count(*)
+ from emp as f
+ where f.comm is not distinct from e.comm) as c
+from emp as e;
++--------+----+
+| ENAME | C |
++--------+----+
+| ALLEN | 1 |
+| WARD | 1 |
+| MARTIN | 1 |
+| TURNER | 1 |
+| SMITH | 10 |
+| JONES | 10 |
+| BLAKE | 10 |
+| CLARK | 10 |
+| SCOTT | 10 |
+| KING | 10 |
+| ADAMS | 10 |
+| JAMES | 10 |
+| FORD | 10 |
+| MILLER | 10 |
++--------+----+
+(14 rows)
+
+!ok
+EnumerableCalc(expr#0..6=[{inputs}], expr#7=[IS NULL($t6)], expr#8=[0:BIGINT],
expr#9=[CASE($t7, $t8, $t6)], ENAME=[$t1], C=[$t9])
+ EnumerableHashJoin(condition=[AND(IS NOT DISTINCT FROM($2, $4), =($3, $5))],
joinType=[left])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NULL($t6)],
proj#0..1=[{exprs}], COMM=[$t6], $f3=[$t8])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[IS NOT NULL($t4)],
expr#6=[0], expr#7=[CASE($t5, $t4, $t6)], proj#0..1=[{exprs}], EXPR$0=[$t7])
+ EnumerableHashJoin(condition=[AND(IS NOT DISTINCT FROM($0, $2), IS NOT
DISTINCT FROM($1, $3))], joinType=[left])
+ EnumerableAggregate(group=[{0, 1}])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NULL($t6)],
COMM=[$t6], $f3=[$t8])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableAggregate(group=[{0, 1}], EXPR$0=[COUNT()])
+ EnumerableNestedLoopJoin(condition=[OR(AND(IS NULL($3), $1), =($3,
$0))], joinType=[inner])
+ EnumerableAggregate(group=[{0, 1}])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NULL($t6)],
COMM=[$t6], $f3=[$t8])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], COMM=[$t6])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
# End sub-query.iq