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 ea08b43db6 [CALCITE-7391] FILTER_REDUCE_EXPRESSIONS crashes on 
expression where 123 in (SELECT NULL FROM emps)
ea08b43db6 is described below

commit ea08b43db6bc83ea76678bd77873e110083c0edc
Author: Dongsheng He <[email protected]>
AuthorDate: Thu Jan 22 10:43:50 2026 +0800

    [CALCITE-7391] FILTER_REDUCE_EXPRESSIONS crashes on expression where 123 in 
(SELECT NULL FROM emps)
---
 .../rel/rules/FilterProjectTransposeRule.java      |  9 +++++++
 .../org/apache/calcite/test/RelOptRulesTest.java   | 11 +++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml    | 28 ++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
 
b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
index 3e3cf46a11..3c365222cd 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
@@ -28,6 +28,7 @@
 import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexSimplify;
 import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.tools.RelBuilderFactory;
@@ -35,7 +36,9 @@
 import org.immutables.value.Value;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 /**
  * Planner rule that pushes
@@ -170,6 +173,12 @@ protected FilterProjectTransposeRule(
     }
 
     final RelBuilder relBuilder = call.builder();
+    List<RexNode> conjuncts = RelOptUtil.conjunctions(newCondition);
+    List<RexNode> simplified = conjuncts.stream()
+        .map(e -> RexSimplify.simplifyComparisonWithNull(e, 
relBuilder.getRexBuilder()))
+        .collect(Collectors.toList());
+    newCondition = RexUtil.composeConjunction(relBuilder.getRexBuilder(), 
simplified);
+
     RelNode newFilterRel;
     if (config.isCopyFilter()) {
       final RelNode input = project.getInput();
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 2c8c5eab43..94bb87651f 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -9593,6 +9593,17 @@ private void checkSemiJoinRuleOnAntiJoin(RelOptRule 
rule) {
     sql(sql).withRule(subQueryFilterRule).withLateDecorrelate(true).check();
   }
 
+  /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-7391";>[CALCITE-7391]
+   * FILTER_REDUCE_EXPRESSIONS crashes on expression where 123 in (SELECT NULL 
FROM emps)</a>. */
+  @Test void testNullSelect2() {
+    final String sql = "SELECT * from emp where 123 in (select null from 
dept)";
+    sql(sql)
+        .withRule(CoreRules.FILTER_SUB_QUERY_TO_CORRELATE,
+            CoreRules.FILTER_PROJECT_TRANSPOSE,
+            CoreRules.PROJECT_REDUCE_EXPRESSIONS)
+        .check();
+  }
+
   /** Test case for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6652";>[CALCITE-6652]
    * RelDecorrelator can't decorrelate query with limit 1</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 5fa2ddc3eb..67e86d45b6 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -11062,6 +11062,34 @@ LogicalProject(EXPR$0=[1])
       LogicalTableScan(table=[[CATALOG, SALES, EMP]])
       LogicalProject(cs=[true])
         LogicalValues(tuples=[[]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testNullSelect2">
+    <Resource name="sql">
+      <![CDATA[SELECT * from emp where 123 in (select null from dept)]]>
+    </Resource>
+    <Resource name="planBefore">
+      <![CDATA[
+LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
+  LogicalFilter(condition=[IN(123, {
+LogicalProject(EXPR$0=[null:INTEGER])
+  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+})])
+    LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+    <Resource name="planAfter">
+      <![CDATA[
+LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
+  LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
+    LogicalJoin(condition=[true], joinType=[inner])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+      LogicalAggregate(group=[{0}])
+        LogicalProject(cs=[true])
+          LogicalProject(EXPR$0=[null:INTEGER])
+            LogicalFilter(condition=[false])
+              LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
 ]]>
     </Resource>
   </TestCase>

Reply via email to