This is an automated email from the ASF dual-hosted git repository.

rubenql 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 d08b5cf73f [CALCITE-5691] IN sub-query inside FILTER clause throws 
IndexOutOfBoundsException
d08b5cf73f is described below

commit d08b5cf73f9bb438f282d2089dd92f6d380c0c47
Author: Runkang He <hrun...@gmail.com>
AuthorDate: Thu May 11 08:59:29 2023 +0800

    [CALCITE-5691] IN sub-query inside FILTER clause throws 
IndexOutOfBoundsException
---
 .../apache/calcite/plan/RelOptPredicateList.java   | 10 +++---
 .../apache/calcite/test/SqlToRelConverterTest.java | 13 ++++++++
 .../apache/calcite/test/SqlToRelConverterTest.xml  | 32 ++++++++++++++++++
 core/src/test/resources/sql/sub-query.iq           | 38 ++++++++++++++++++++++
 4 files changed, 89 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java 
b/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
index 405ac30b91..d6f1de5ce1 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
@@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableMap;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -236,10 +237,11 @@ public class RelOptPredicateList {
     if (SqlKind.COMPARISON.contains(e.getKind())) {
       // A comparison with a (non-null) literal, such as 'ref < 10', is not 
null if 'ref'
       // is not null.
-      RexCall call = (RexCall) e;
-      if (call.getOperands().get(1) instanceof RexLiteral
-          && !((RexLiteral) call.getOperands().get(1)).isNull()) {
-        return isEffectivelyNotNull(call.getOperands().get(0));
+      List<RexNode> operands = ((RexCall) e).getOperands();
+      // We can have just one operand in case e.g. of a RexSubQuery with IN 
operator.
+      if (operands.size() > 1 && operands.get(1) instanceof RexLiteral
+          && !((RexLiteral) operands.get(1)).isNull()) {
+        return isEffectivelyNotNull(operands.get(0));
       }
     }
     return false;
diff --git 
a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index 3d36135ec6..546b222056 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -667,6 +667,13 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).ok();
   }
 
+  @Test void testAggFilterWithInSubQuery() {
+    final String sql = "select\n"
+        + "  count(*) filter (where empno in (select deptno from 
empnullables))\n"
+        + "from empnullables";
+    sql(sql).withExpand(false).ok();
+  }
+
   @Test void testFakeStar() {
     sql("SELECT * FROM (VALUES (0, 0)) AS T(A, \"*\")").ok();
   }
@@ -4652,6 +4659,12 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).ok();
   }
 
+  @Test void testProjectInSubQueryWithIsTruePredicate() {
+    final String sql = "select deptno in (select deptno from empnullables) is 
true\n"
+        + "from empnullables";
+    sql(sql).withExpand(false).ok();
+  }
+
   @Test void testProjectAggregatesIgnoreNullsAndNot() {
     final String sql = "select lead(sal, 4) IGNORE NULLS, lead(sal, 4) over 
(w)\n"
         + "from emp window w as (order by empno)";
diff --git 
a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml 
b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index d1581c2922..68aeb4885c 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -86,6 +86,23 @@ group by deptno]]>
 LogicalAggregate(group=[{0}], EXPR$1=[SUM($1) FILTER $2], EXPR$2=[COUNT()])
   LogicalProject(DEPTNO=[$7], $f1=[*($5, 2)], $f2=[SEARCH($0, Sarg[(-∞..1), 
(1..2), (2..+∞)])])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testAggFilterWithInSubQuery">
+    <Resource name="sql">
+      <![CDATA[select
+  count(*) filter (where empno in (select deptno from empnullables))
+from empnullables]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalAggregate(group=[{}], EXPR$0=[COUNT() FILTER $0])
+  LogicalProject($f0=[IS TRUE(IN($0, {
+LogicalProject(DEPTNO=[$7])
+  LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
+}))])
+    LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
 ]]>
     </Resource>
   </TestCase>
@@ -5871,6 +5888,21 @@ GROUP BY empno]]>
 LogicalAggregate(group=[{0}], EXPR$1=[COUNT(DISTINCT $1)], 
EXPR$2=[COUNT(APPROXIMATE DISTINCT $1)])
   LogicalProject(EMPNO=[$0], ENAME=[$1])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testProjectInSubQueryWithIsTruePredicate">
+    <Resource name="sql">
+      <![CDATA[select deptno in (select deptno from empnullables) is true
+from empnullables]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(EXPR$0=[IS TRUE(IN($7, {
+LogicalProject(DEPTNO=[$7])
+  LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
+}))])
+  LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
 ]]>
     </Resource>
   </TestCase>
diff --git a/core/src/test/resources/sql/sub-query.iq 
b/core/src/test/resources/sql/sub-query.iq
index 1cd28283c9..007e52cce0 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -3573,4 +3573,42 @@ or 20 in (
 
 !ok
 
+# Test case for [CALCITE-5691] IN sub-query inside FILTER clause throws 
IndexOutOfBoundsException
+select
+  count(*) filter (where empno in (select deptno from emp))
+from emp;
++--------+
+| EXPR$0 |
++--------+
+|      0 |
++--------+
+(1 row)
+
+!ok
+
+# Test case for [CALCITE-5691] IN sub-query inside FILTER clause throws 
IndexOutOfBoundsException
+select deptno in (select deptno from emp) is true
+from emp;
++--------+
+| EXPR$0 |
++--------+
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
+| true   |
++--------+
+(14 rows)
+
+!ok
+
 # End sub-query.iq

Reply via email to