This is an automated email from the ASF dual-hosted git repository.
xiong 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 637047900f [CALCITE-5156] Support implicit integer types cast for IN
Sub-query
637047900f is described below
commit 637047900ff06425b70a515d290666b3db9a0dc3
Author: Xiong Duan <[email protected]>
AuthorDate: Mon Oct 21 16:14:11 2024 +0800
[CALCITE-5156] Support implicit integer types cast for IN Sub-query
---
babel/src/test/resources/sql/redshift.iq | 2 +-
.../java/org/apache/calcite/plan/RelOptRules.java | 1 +
.../validate/implicit/AbstractTypeCoercion.java | 9 -
.../calcite/rel/rel2sql/RelToSqlConverterTest.java | 18 +-
.../org/apache/calcite/test/JdbcAdapterTest.java | 20 +-
.../java/org/apache/calcite/test/JdbcTest.java | 2 +-
.../apache/calcite/test/SqlToRelConverterTest.java | 19 +-
.../java/org/apache/calcite/test/StreamTest.java | 2 +-
.../calcite/test/TypeCoercionConverterTest.java | 20 ++
.../apache/calcite/test/SqlToRelConverterTest.xml | 51 ++++-
.../calcite/test/TypeCoercionConverterTest.xml | 42 ++++
core/src/test/resources/sql/agg.iq | 6 +-
core/src/test/resources/sql/conditions.iq | 2 +-
core/src/test/resources/sql/sub-query.iq | 255 +++++++++++++++------
.../calcite/adapter/kafka/KafkaAdapterTest.java | 2 +-
.../org/apache/calcite/test/SparkAdapterTest.java | 10 +-
16 files changed, 341 insertions(+), 120 deletions(-)
diff --git a/babel/src/test/resources/sql/redshift.iq
b/babel/src/test/resources/sql/redshift.iq
index d5d9f255f3..f706ecb164 100755
--- a/babel/src/test/resources/sql/redshift.iq
+++ b/babel/src/test/resources/sql/redshift.iq
@@ -921,7 +921,7 @@ EXPR$0
select nvl2(comm, sal, sal + 10) from emp where deptno = 30;
SELECT "NVL2"("EMP"."COMM", "EMP"."SAL", "EMP"."SAL" + 10)
FROM "scott"."EMP" AS "EMP"
-WHERE "EMP"."DEPTNO" = 30
+WHERE CAST("EMP"."DEPTNO" AS INTEGER) = 30
!explain-validated-on calcite
# NULLIF
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptRules.java
b/core/src/main/java/org/apache/calcite/plan/RelOptRules.java
index 8b513de0fb..65b9e54897 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptRules.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptRules.java
@@ -131,6 +131,7 @@ public class RelOptRules {
CoreRules.JOIN_TO_SEMI_JOIN,
CoreRules.AGGREGATE_REMOVE,
CoreRules.UNION_TO_DISTINCT,
+ CoreRules.UNION_TO_VALUES,
CoreRules.PROJECT_REMOVE,
CoreRules.PROJECT_AGGREGATE_MERGE,
CoreRules.AGGREGATE_JOIN_TRANSPOSE,
diff --git
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
index f80c6eb9b7..6d8d6f0415 100644
---
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
+++
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
@@ -280,15 +280,6 @@ public abstract class AbstractTypeCoercion implements
TypeCoercion {
return false;
}
- // No need to cast if the source type precedence list
- // contains target type. i.e. do not cast from
- // tinyint to int or int to bigint.
- if (fromType.getPrecedenceList().containsType(toType)
- && SqlTypeUtil.isIntType(fromType)
- && SqlTypeUtil.isIntType(toType)) {
- return false;
- }
-
// No casts to binary except from strings
if (SqlTypeUtil.isBinary(fromType) && !SqlTypeUtil.isString(toType)) {
return false;
diff --git
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 259af4b156..85a39de8fd 100644
---
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -3814,7 +3814,7 @@ class RelToSqlConverterTest {
+ "group by \"product_id\", \"units_per_case\" order by
\"units_per_case\" desc";
final String expected = "SELECT COUNT(*), \"units_per_case\"\n"
+ "FROM \"foodmart\".\"product\"\n"
- + "WHERE \"cases_per_pallet\" > 100\n"
+ + "WHERE CAST(\"cases_per_pallet\" AS INTEGER) > 100\n"
+ "GROUP BY \"product_id\", \"units_per_case\"\n"
+ "ORDER BY \"units_per_case\" DESC";
sql(query).ok(expected);
@@ -4160,7 +4160,7 @@ class RelToSqlConverterTest {
+ "order by \"units_per_case\" desc";
final String expected = "SELECT COUNT(*), product.units_per_case\n"
+ "FROM foodmart.product AS product\n"
- + "WHERE product.cases_per_pallet > 100\n"
+ + "WHERE CAST(product.cases_per_pallet AS INTEGER) > 100\n"
+ "GROUP BY product.product_id, product.units_per_case\n"
+ "ORDER BY product.units_per_case DESC";
sql(query).withDb2().ok(expected);
@@ -4181,7 +4181,7 @@ class RelToSqlConverterTest {
+ "FROM (SELECT product.units_per_case, product.cases_per_pallet, "
+ "product.product_id, 1 AS FOO\n"
+ "FROM foodmart.product AS product) AS t\n"
- + "WHERE t.cases_per_pallet > 100\n"
+ + "WHERE CAST(t.cases_per_pallet AS INTEGER) > 100\n"
+ "GROUP BY t.product_id, t.units_per_case\n"
+ "ORDER BY t.units_per_case DESC";
sql(query).withDb2().ok(expected);
@@ -4205,13 +4205,13 @@ class RelToSqlConverterTest {
+ "FROM (SELECT product.units_per_case, product.cases_per_pallet, "
+ "product.product_id, 1 AS FOO\n"
+ "FROM foodmart.product AS product\n"
- + "WHERE product.cases_per_pallet > 100\n"
+ + "WHERE CAST(product.cases_per_pallet AS INTEGER) > 100\n"
+ "UNION ALL\n"
+ "SELECT product0.units_per_case, product0.cases_per_pallet, "
+ "product0.product_id, 1 AS FOO\n"
+ "FROM foodmart.product AS product0\n"
- + "WHERE product0.cases_per_pallet < 100) AS t3\n"
- + "WHERE t3.cases_per_pallet > 100\n"
+ + "WHERE CAST(product0.cases_per_pallet AS INTEGER) < 100) AS t3\n"
+ + "WHERE CAST(t3.cases_per_pallet AS INTEGER) > 100\n"
+ "GROUP BY t3.product_id, t3.units_per_case\n"
+ "ORDER BY t3.units_per_case DESC";
sql(query).withDb2().ok(expected);
@@ -4308,8 +4308,8 @@ class RelToSqlConverterTest {
+ "FROM \"SCOTT\".\"DEPT\"\n"
+ "LEFT JOIN \"SCOTT\".\"EMP\" "
+ "ON \"DEPT\".\"DEPTNO\" = \"EMP\".\"DEPTNO\" "
- + "AND (\"DEPT\".\"DEPTNO\" > 10"
- + " AND \"DEPT\".\"DEPTNO\" < 15)\n"
+ + "AND (CAST(\"DEPT\".\"DEPTNO\" AS INTEGER) > 10"
+ + " AND CAST(\"DEPT\".\"DEPTNO\" AS INTEGER) < 15)\n"
+ "WHERE \"EMP\".\"JOB\" LIKE 'PRESIDENT'";
sql(sql)
.schema(CalciteAssert.SchemaSpec.JDBC_SCOTT)
@@ -8263,7 +8263,7 @@ class RelToSqlConverterTest {
+ "FROM (SELECT DEPTNO\n"
+ "FROM SCOTT.EMP\n"
+ "GROUP BY DEPTNO\n"
- + "HAVING DEPTNO > 0) AS t1";
+ + "HAVING CAST(DEPTNO AS INT64) > 0) AS t1";
// Parse the input SQL with PostgreSQL dialect,
// in which "isHavingAlias" is false.
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index cfa3e0c443..49b30e832b 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -122,22 +122,22 @@ class JdbcAdapterTest {
+ "union all\n"
+ "select ename from SCOTT.emp where empno > 10")
.explainContains("PLAN=EnumerableUnion(all=[true])\n"
- + " JdbcToEnumerableConverter\n"
- + " JdbcProject(store_name=[$3])\n"
- + " JdbcFilter(condition=[<($0, 10)])\n"
- + " JdbcTableScan(table=[[foodmart, store]])\n"
- + " JdbcToEnumerableConverter\n"
- + " JdbcProject(ENAME=[$1])\n"
- + " JdbcFilter(condition=[>($0, 10)])\n"
- + " JdbcTableScan(table=[[SCOTT, EMP]])")
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcProject(store_name=[$3])\n"
+ + " JdbcFilter(condition=[<($0, 10)])\n"
+ + " JdbcTableScan(table=[[foodmart, store]])\n"
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcProject(ENAME=[$1])\n"
+ + " JdbcFilter(condition=[>(CAST($0):INTEGER NOT NULL,
10)])\n"
+ + " JdbcTableScan(table=[[SCOTT, EMP]])")
.runs()
.enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
.planHasSql("SELECT \"store_name\"\n"
+ "FROM \"foodmart\".\"store\"\n"
+ "WHERE \"store_id\" < 10")
.planHasSql("SELECT \"ENAME\"\n"
- + "FROM \"SCOTT\".\"EMP\"\n"
- + "WHERE \"EMPNO\" > 10");
+ + "FROM \"SCOTT\".\"EMP\"\n"
+ + "WHERE CAST(\"EMPNO\" AS INTEGER) > 10");
}
/** Test case for
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 7aaef4cf77..ec681ef601 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -5017,7 +5017,7 @@ public class JdbcTest {
+ "group by grouping sets (deptno, deptno, deptno, (), ())\n"
+ "having group_id() > 0")
.explainContains("EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1],
expr#4=[+($t1, $t3)], "
- + "expr#5=[0], expr#6=[>($t1, $t5)], DEPTNO=[$t0], G=[$t4],
C=[$t2], $condition=[$t6])\n"
+ + "expr#5=[0:BIGINT], expr#6=[>($t1, $t5)], DEPTNO=[$t0], G=[$t4],
C=[$t2], $condition=[$t6])\n"
+ " EnumerableUnion(all=[true])\n"
+ " EnumerableCalc(expr#0..1=[{inputs}], expr#2=[0:BIGINT],
DEPTNO=[$t0], $f1=[$t2], C=[$t1])\n"
+ " EnumerableAggregate(group=[{7}], groups=[[{7}, {}]],
C=[COUNT()])\n"
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 345db9eb62..a568964de8 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -290,7 +290,7 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
*/
@Test void testAsOfCast() {
final String sql = "SELECT * "
- + "FROM (SELECT deptno % 10 as m, CAST(deptno AS BIGINT) as deptno
FROM dept) D\n"
+ + "FROM (SELECT CAST(deptno % 10 AS BIGINT) as m, CAST(deptno AS
BIGINT) as deptno FROM dept) D\n"
+ "LEFT ASOF JOIN (SELECT CAST(empno as BIGINT) as empno, CAST(deptno
AS BIGINT) AS deptno FROM emp) E\n"
+ "MATCH_CONDITION D.deptno >= E.deptno\n"
+ "ON D.m = E.empno";
@@ -4142,6 +4142,23 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
sql(sql).withDynamicTable().ok();
}
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-5156">[CALCITE-5156]
+ * Support implicit integer types cast for IN Sub-query</a>. */
+ @Test void testInSubQueryWithTypeCast() {
+ final String sql = "select *\n"
+ + "from dept\n"
+ + "where cast(deptno + 20 as bigint) in (select deptno from dept)";
+ sql(sql).withExpand(false).ok();
+ }
+
+ @Test void testInSubQueryWithTypeCast2() {
+ final String sql = "select *\n"
+ + "from dept\n"
+ + "where cast(deptno as bigint) in (select deptno + 20 from dept)";
+ sql(sql).withExpand(false).ok();
+ }
+
/** Test case for
* <a
href="https://issues.apache.org/jira/browse/CALCITE-1321">[CALCITE-1321]
* Configurable IN list size when converting IN clause to join</a>. */
diff --git a/core/src/test/java/org/apache/calcite/test/StreamTest.java
b/core/src/test/java/org/apache/calcite/test/StreamTest.java
index d2bf27f372..cbff9d6c13 100644
--- a/core/src/test/java/org/apache/calcite/test/StreamTest.java
+++ b/core/src/test/java/org/apache/calcite/test/StreamTest.java
@@ -142,7 +142,7 @@ public class StreamTest {
+ " LogicalProject(ROWTIME=[FLOOR($0, FLAG(HOUR))],
PRODUCT=[$2])\n"
+ " LogicalTableScan(table=[[STREAMS, ORDERS]])\n")
.explainContains(
- "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1], expr#4=[>($t2,
$t3)], proj#0..2=[{exprs}], $condition=[$t4])\n"
+ "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1:BIGINT],
expr#4=[>($t2, $t3)], proj#0..2=[{exprs}], $condition=[$t4])\n"
+ " EnumerableAggregate(group=[{0, 1}], C=[COUNT()])\n"
+ " EnumerableCalc(expr#0..3=[{inputs}],
expr#4=[FLAG(HOUR)], expr#5=[FLOOR($t0, $t4)], ROWTIME=[$t5], PRODUCT=[$t2])\n"
+ " EnumerableInterpreter\n"
diff --git
a/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
b/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
index 228b569062..538588ec9e 100644
--- a/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
@@ -155,6 +155,26 @@ class TypeCoercionConverterTest extends SqlToRelTestBase {
.ok();
}
+ @Test void testIntegerImplicitTypeCast1() {
+ sql("with\n"
+ + "t1(x) as (select * from (values (cast(1 as bigint)),(cast(2 as
bigint))) as t1),\n"
+ + "t2(x) as (select * from (values (3),(4)) as t2)\n"
+ + "select *\n"
+ + "from t1\n"
+ + "where t1.x in (select t2.x from t2)")
+ .ok();
+ }
+
+ @Test void testIntegerImplicitTypeCast2() {
+ sql("with\n"
+ + "t1(x) as (select * from (values (cast(1 as tinyint)),(cast(2 as
tinyint))) as t1),\n"
+ + "t2(x) as (select * from (values (3),(4)) as t2)\n"
+ + "select *\n"
+ + "from t1\n"
+ + "where t1.x in (select t2.x from t2)")
+ .ok();
+ }
+
@Test void testSetOperation() {
// int decimal smallint double
// char decimal float bigint
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 3feb6be58a..80ec5f83ad 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -204,7 +204,7 @@ having e > 10 or count(empno) < 5]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalFilter(condition=[SEARCH($0, Sarg[(-∞..5), (10..+∞)])])
+LogicalFilter(condition=[SEARCH($0, Sarg[(-∞..5L:BIGINT),
(10L:BIGINT..+∞)]:BIGINT)])
LogicalAggregate(group=[{}], E=[COUNT()])
LogicalProject(EMPNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -526,16 +526,16 @@ LogicalProject(EXPR$0=[ITEM(ITEM($3, 1).DETAIL.SKILLS,
+(2, 3)).DESC])
</TestCase>
<TestCase name="testAsOfCast">
<Resource name="sql">
- <![CDATA[SELECT * FROM (SELECT deptno % 10 as m, CAST(deptno AS BIGINT)
as deptno FROM dept) D
+ <![CDATA[SELECT * FROM (SELECT CAST(deptno % 10 AS BIGINT) as m,
CAST(deptno AS BIGINT) as deptno FROM dept) D
LEFT ASOF JOIN (SELECT CAST(empno as BIGINT) as empno, CAST(deptno AS BIGINT)
AS deptno FROM emp) E
MATCH_CONDITION D.deptno >= E.deptno
ON D.m = E.empno]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(M=[$0], DEPTNO=[$1], EMPNO=[$3], DEPTNO0=[$4])
- LogicalAsofJoin(condition=[=($2, $3)], joinType=[left_asof],
matchCondition=[>=($1, $4)])
- LogicalProject(M=[MOD($0, 10)], DEPTNO=[CAST($0):BIGINT NOT NULL],
$f2=[CAST(MOD($0, 10)):BIGINT NOT NULL])
+LogicalProject(M=[$0], DEPTNO=[$1], EMPNO=[$2], DEPTNO0=[$3])
+ LogicalAsofJoin(condition=[=($0, $2)], joinType=[left_asof],
matchCondition=[>=($1, $3)])
+ LogicalProject(M=[CAST(MOD($0, 10)):BIGINT NOT NULL],
DEPTNO=[CAST($0):BIGINT NOT NULL])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalProject(EMPNO=[CAST($0):BIGINT NOT NULL], DEPTNO=[CAST($7):BIGINT
NOT NULL])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -2905,6 +2905,40 @@ FROM dept, emp WHERE emp.deptno = dept.deptno AND
emp.sal < (
)]]>
</Resource>
</TestCase>
+ <TestCase name="testInSubQueryWithTypeCast">
+ <Resource name="sql">
+ <![CDATA[select *
+from dept
+where cast(deptno + 20 as bigint) in (select deptno from dept)]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(DEPTNO=[$0], NAME=[$1])
+ LogicalFilter(condition=[IN(CAST(+($0, 20)):BIGINT NOT NULL, {
+LogicalProject(EXPR$0=[CAST($0):BIGINT NOT NULL])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+})])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testInSubQueryWithTypeCast2">
+ <Resource name="sql">
+ <![CDATA[select *
+from dept
+where cast(deptno as bigint) in (select deptno + 20 from dept)]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(DEPTNO=[$0], NAME=[$1])
+ LogicalFilter(condition=[IN(CAST($0):BIGINT NOT NULL, {
+LogicalProject(EXPR$0=[CAST(+($0, 20)):BIGINT NOT NULL])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+})])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testInToSemiJoin">
<Resource name="sql">
<![CDATA[SELECT empno
@@ -2925,7 +2959,12 @@ LogicalProject(EMPNO=[$0])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[CAST($0):BIGINT NOT
NULL])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{0}])
- LogicalValues(tuples=[[{ 130 }, { 131 }, { 132 }, { 133 }, { 134 }]])
+ LogicalUnion(all=[true])
+ LogicalValues(tuples=[[{ 130 }]])
+ LogicalValues(tuples=[[{ 131 }]])
+ LogicalValues(tuples=[[{ 132 }]])
+ LogicalValues(tuples=[[{ 133 }]])
+ LogicalValues(tuples=[[{ 134 }]])
]]>
</Resource>
</TestCase>
diff --git
a/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
b/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
index 4253f0b7e1..37f707b8db 100644
---
a/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
+++
b/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
@@ -174,6 +174,48 @@ LogicalTableModify(table=[[CATALOG, SALES, T1]],
operation=[INSERT], flattened=[
<![CDATA[
LogicalTableModify(table=[[CATALOG, SALES, T1]], operation=[INSERT],
flattened=[false])
LogicalValues(tuples=[[{ 'a', 1, 1, 0, 0.0E0, 0.0E0, 0, 2021-11-28 00:00:00,
2021-11-28, X'0a', false }, { 'b', 2, 2, 0, 0.0E0, 0.0E0, 0, 2021-11-28
00:00:00, 2021-11-28, X'0a', false }, { 'c', 3, 3, 0, 0.0E0, 0.0E0, 0,
2021-11-28 00:00:00, 2021-11-28, X'0a', false }, { 'd', 4, 4, 0, 0.0E0, 0.0E0,
0, 2021-11-28 00:00:00, 2021-11-28, X'0a', false }, { 'e', 5, 5, 0, 0.0E0,
0.0E0, 0, 2021-11-28 00:00:00, 2021-11-28, X'0a', false }]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testIntegerImplicitTypeCast1">
+ <Resource name="sql">
+ <![CDATA[with
+t1(x) as (select * from (values (cast(1 as bigint)),(cast(2 as bigint))) as
t1),
+t2(x) as (select * from (values (3),(4)) as t2)
+select *
+from t1
+where t1.x in (select t2.x from t2)]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(X=[$0])
+ LogicalJoin(condition=[=($0, $1)], joinType=[inner])
+ LogicalProject(T1=[$0])
+ LogicalValues(tuples=[[{ 1 }, { 2 }]])
+ LogicalAggregate(group=[{0}])
+ LogicalProject(EXPR$0=[CAST($0):BIGINT NOT NULL])
+ LogicalValues(tuples=[[{ 3 }, { 4 }]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testIntegerImplicitTypeCast2">
+ <Resource name="sql">
+ <![CDATA[with
+t1(x) as (select * from (values (cast(1 as tinyint)),(cast(2 as tinyint))) as
t1),
+t2(x) as (select * from (values (3),(4)) as t2)
+select *
+from t1
+where t1.x in (select t2.x from t2)]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(X=[$0])
+ LogicalJoin(condition=[=($1, $2)], joinType=[inner])
+ LogicalProject(T1=[$0], EXPR$0=[CAST($0):INTEGER NOT NULL])
+ LogicalValues(tuples=[[{ 1 }, { 2 }]])
+ LogicalAggregate(group=[{0}])
+ LogicalProject(X=[$0])
+ LogicalValues(tuples=[[{ 3 }, { 4 }]])
]]>
</Resource>
</TestCase>
diff --git a/core/src/test/resources/sql/agg.iq
b/core/src/test/resources/sql/agg.iq
index 411cbe38f8..d459e62e74 100644
--- a/core/src/test/resources/sql/agg.iq
+++ b/core/src/test/resources/sql/agg.iq
@@ -1934,9 +1934,9 @@ group by deptno;
EnumerableAggregate(group=[{0}], CF=[COUNT() FILTER $1], C=[COUNT()])
EnumerableCalc(expr#0..1=[{inputs}], expr#2=['CLERK':VARCHAR(9)],
expr#3=[=($t0, $t2)], expr#4=[IS TRUE($t3)], DEPTNO=[$t1], $f1=[$t4])
EnumerableUnion(all=[true])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[<($t7, $t8)],
JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t7):INTEGER],
expr#9=[20], expr#10=[<($t8, $t9)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t10])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[>($t7, $t8)],
JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t7):INTEGER],
expr#9=[20], expr#10=[>($t8, $t9)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t10])
EnumerableTableScan(table=[[scott, EMP]])
!plan
@@ -3079,7 +3079,7 @@ group by deptno;
!ok
EnumerableAggregate(group=[{0}], EMPNOS=[COLLECT($1) WITHIN GROUP ([1 DESC])
FILTER $2])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[7500], expr#9=[>($t0, $t8)],
DEPTNO=[$t7], EMPNO=[$t0], $f2=[$t9])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t0):INTEGER NOT NULL],
expr#9=[7500], expr#10=[>($t8, $t9)], DEPTNO=[$t7], EMPNO=[$t0], $f2=[$t10])
EnumerableTableScan(table=[[scott, EMP]])
!plan
diff --git a/core/src/test/resources/sql/conditions.iq
b/core/src/test/resources/sql/conditions.iq
index 1acf5ecd4b..a9fa54b529 100644
--- a/core/src/test/resources/sql/conditions.iq
+++ b/core/src/test/resources/sql/conditions.iq
@@ -395,7 +395,7 @@ EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t0])
EnumerableNestedLoopJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[0], expr#2=[>($t0, $t1)],
EXPR$0=[$t2])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[0:BIGINT], expr#2=[>($t0,
$t1)], EXPR$0=[$t2])
EnumerableAggregate(group=[{}], agg#0=[COUNT()])
EnumerableTableScan(table=[[scott, EMP]])
!plan
diff --git a/core/src/test/resources/sql/sub-query.iq
b/core/src/test/resources/sql/sub-query.iq
index ace96e5ec6..c32362f778 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -492,8 +492,10 @@ EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])
# Uncorrelated
with t (a, b) as (select * from (values (60, 'b')))
select * from t where a in (select deptno from "scott".dept);
-EnumerableCalc(expr#0..2=[{inputs}], expr#3=[60], expr#4=['b'], expr#5=[=($t3,
$t0)], A=[$t3], B=[$t4], $condition=[$t5])
- EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableCalc(expr#0=[{inputs}], expr#1=[60], expr#2=['b'], A=[$t1], B=[$t2])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):INTEGER NOT NULL],
expr#4=[60], expr#5=[=($t4, $t3)], EXPR$0=[$t3], $condition=[$t5])
+ EnumerableTableScan(table=[[scott, DEPT]])
!plan
+---+---+
| A | B |
@@ -505,8 +507,10 @@ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[60],
expr#4=['b'], expr#5=[=($t3, $
with t (a, b) as (select * from (values (30, 'b')))
select * from t where a in (select deptno from "scott".dept);
-EnumerableCalc(expr#0..2=[{inputs}], expr#3=[30], expr#4=['b'], expr#5=[=($t3,
$t0)], A=[$t3], B=[$t4], $condition=[$t5])
- EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableCalc(expr#0=[{inputs}], expr#1=[30], expr#2=['b'], A=[$t1], B=[$t2])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):INTEGER NOT NULL],
expr#4=[30], expr#5=[=($t4, $t3)], EXPR$0=[$t3], $condition=[$t5])
+ EnumerableTableScan(table=[[scott, DEPT]])
!plan
+----+---+
| A | B |
@@ -734,7 +738,7 @@ EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t1])
EnumerableHashJoin(condition=[AND(=($2, $4), =($0, $3))], joinType=[semi])
EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t2):VARCHAR(14)],
EMPNO=[$t0], SAL=[$t5], JOB0=[$t8])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT NULL($t1)],
proj#0..1=[{exprs}], $condition=[$t3])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):SMALLINT NOT NULL],
expr#4=[IS NOT NULL($t1)], EXPR$0=[$t3], DNAME=[$t1], $condition=[$t4])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1101,8 +1105,9 @@ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT
NULL($t2)], SAL=[$t1], EXPR$
EnumerableNestedLoopJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
- EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER NOT NULL], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
+ EnumerableTableScan(table=[[scott, DEPT]])
!plan
# Test project literal IN nullable
@@ -1137,7 +1142,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS
FALSE($t2)], expr#5=[null:BOOLEA
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t0, $t4)], cs=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT NULL($t0)],
expr#4=[CAST($t0):INTEGER], expr#5=[10], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1350,8 +1355,9 @@ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS
NULL($t2)], SAL=[$t1], EXPR$1=[$
EnumerableNestedLoopJoin(condition=[true], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
- EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER NOT NULL], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
+ EnumerableTableScan(table=[[scott, DEPT]])
!plan
# Test project literal NOT IN nullable
@@ -1386,7 +1392,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS
NULL($t3)], expr#5=[IS FALSE($t2
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t0, $t4)], cs=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT NULL($t0)],
expr#4=[CAST($t0):INTEGER], expr#5=[10], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1519,8 +1525,9 @@ EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t1])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[=($t3, $t0)],
DEPTNO=[$t0], $condition=[$t4])
- EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER NOT NULL], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
+ EnumerableTableScan(table=[[scott, DEPT]])
!plan
# Test filter literal IN nullable
@@ -1552,7 +1559,7 @@ EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t1])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableAggregate(group=[{0}])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER], expr#6=[=($t4, $t5)], cs=[$t3], $condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1678,7 +1685,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS
NULL($t3)], expr#5=[NOT($t2)], e
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER NOT NULL], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1699,7 +1706,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS
NULL($t3)], expr#5=[NOT($t2)], e
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t0, $t4)], cs=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[IS NOT NULL($t0)],
expr#4=[CAST($t0):INTEGER], expr#5=[10], expr#6=[=($t4, $t5)], cs=[$t3],
$condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1841,7 +1848,7 @@ EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t1])
EnumerableHashJoin(condition=[=($2, $3)], joinType=[semi])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[=($t3, $t0)],
DEPTNO=[$t0], $condition=[$t4])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10],
expr#4=[CAST($t0):INTEGER NOT NULL], expr#5=[=($t3, $t4)], DEPTNO=[$t0],
$condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1862,7 +1869,7 @@ EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t1])
EnumerableHashJoin(condition=[=($2, $3)], joinType=[semi])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[=($t3, $t0)],
DEPTNO=[$t0], $condition=[$t4])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10],
expr#4=[CAST($t0):INTEGER], expr#5=[=($t3, $t4)], DEPTNO=[$t0],
$condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1958,12 +1965,12 @@ select sal from "scott".emp e
(11 rows)
!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[NOT($t3)], expr#6=[IS NOT
NULL($t3)], expr#7=[OR($t5, $t6)], expr#8=[IS NOT TRUE($t7)], SAL=[$t1],
$condition=[$t8])
- EnumerableMergeJoin(condition=[=($2, $4)], joinType=[left])
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[NOT($t4)], expr#6=[IS NOT
NULL($t4)], expr#7=[OR($t5, $t6)], expr#8=[IS NOT TRUE($t7)], SAL=[$t1],
$condition=[$t8])
+ EnumerableMergeJoin(condition=[=($2, $3)], joinType=[left])
EnumerableSort(sort0=[$2], dir0=[ASC])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5],
DEPTNO=[$t7])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t4, $t0)], cs=[$t3], DEPTNO1=[$t0], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[CAST($t0):INTEGER NOT NULL], expr#6=[=($t4, $t5)], DEPTNO=[$t0],
$f1=[$t3], $condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -1988,12 +1995,12 @@ select sal from "scott".emp e
(11 rows)
!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[NOT($t4)], expr#6=[IS NOT
NULL($t4)], expr#7=[OR($t5, $t6)], expr#8=[IS NOT TRUE($t7)], SAL=[$t1],
$condition=[$t8])
- EnumerableMergeJoin(condition=[=($2, $3)], joinType=[left])
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[NOT($t3)], expr#6=[IS NOT
NULL($t3)], expr#7=[OR($t5, $t6)], expr#8=[IS NOT TRUE($t7)], SAL=[$t1],
$condition=[$t8])
+ EnumerableMergeJoin(condition=[=($2, $4)], joinType=[left])
EnumerableSort(sort0=[$2], dir0=[ASC])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5],
DEPTNO=[$t7])
EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10],
expr#5=[=($t0, $t4)], DEPTNO=[$t0], $f1=[$t3], $condition=[$t5])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true],
expr#4=[CAST($t0):INTEGER], expr#5=[10], expr#6=[=($t4, $t5)], cs=[$t3],
DEPTNO=[$t0], $condition=[$t6])
EnumerableTableScan(table=[[scott, DEPT]])
!plan
@@ -3439,14 +3446,15 @@ select * from "scott".emp where empno not in (null,
7782);
EnumerableCalc(expr#0..12=[{inputs}], expr#13=[0:BIGINT], expr#14=[=($t8,
$t13)], expr#15=[IS NULL($t12)], expr#16=[>=($t9, $t8)], expr#17=[AND($t15,
$t16)], expr#18=[OR($t14, $t17)], proj#0..7=[{exprs}], $condition=[$t18])
EnumerableMergeJoin(condition=[=($10, $11)], joinType=[left])
EnumerableSort(sort0=[$10], dir0=[ASC])
- EnumerableCalc(expr#0..9=[{inputs}], proj#0..9=[{exprs}], EMPNO0=[$t0])
+ EnumerableCalc(expr#0..9=[{inputs}], expr#10=[CAST($t0):INTEGER NOT
NULL], proj#0..10=[{exprs}])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)])
EnumerableValues(tuples=[[{ null }, { 7782 }]])
EnumerableSort(sort0=[$0], dir0=[ASC])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
- EnumerableValues(tuples=[[{ null }, { 7782 }]])
+ EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
+ EnumerableValues(tuples=[[{ null }, { 7782 }]])
!plan
select * from "scott".emp where (empno, deptno) not in ((1, 2), (3, null));
@@ -3461,14 +3469,15 @@ select * from "scott".emp where (empno, deptno) not in
((1, 2), (3, null));
EnumerableCalc(expr#0..14=[{inputs}], expr#15=[0:BIGINT], expr#16=[=($t8,
$t15)], expr#17=[IS NULL($t14)], expr#18=[>=($t9, $t8)], expr#19=[IS NOT
NULL($t11)], expr#20=[AND($t17, $t18, $t19)], expr#21=[OR($t16, $t20)],
proj#0..7=[{exprs}], $condition=[$t21])
EnumerableMergeJoin(condition=[AND(=($10, $12), =($11, $13))],
joinType=[left])
EnumerableSort(sort0=[$10], sort1=[$11], dir0=[ASC], dir1=[ASC])
- EnumerableCalc(expr#0..9=[{inputs}], proj#0..9=[{exprs}], EMPNO0=[$t0],
DEPTNO0=[$t7])
+ EnumerableCalc(expr#0..9=[{inputs}], expr#10=[CAST($t0):INTEGER NOT
NULL], expr#11=[CAST($t7):INTEGER], proj#0..11=[{exprs}])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($1)])
- EnumerableValues(tuples=[[{ 1, 2 }, { 3, null }]])
+ EnumerableValues(tuples=[[{ 3, null }, { 1, 2 }]])
EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
- EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}])
- EnumerableValues(tuples=[[{ 1, 2 }, { 3, null }]])
+ EnumerableAggregate(group=[{0, 1}], agg#0=[MIN($2)])
+ EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true],
proj#0..2=[{exprs}])
+ EnumerableValues(tuples=[[{ 3, null }, { 1, 2 }]])
!plan
select * from "scott".emp where (empno, deptno) not in ((7369, 20), (7499,
30));
@@ -3495,7 +3504,7 @@ select * from "scott".emp where (empno, deptno) not in
((7369, 20), (7499, 30));
EnumerableCalc(expr#0..12=[{inputs}], expr#13=[IS NOT TRUE($t12)], expr#14=[IS
NULL($t9)], expr#15=[OR($t13, $t14)], proj#0..7=[{exprs}], $condition=[$t15])
EnumerableMergeJoin(condition=[AND(=($8, $10), =($9, $11))], joinType=[left])
EnumerableSort(sort0=[$8], sort1=[$9], dir0=[ASC], dir1=[ASC])
- EnumerableCalc(expr#0..7=[{inputs}], proj#0..7=[{exprs}], EMPNO0=[$t0],
DEPTNO0=[$t7])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t0):INTEGER NOT
NULL], expr#9=[CAST($t7):INTEGER], proj#0..9=[{exprs}])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}])
@@ -3889,7 +3898,7 @@ select empno, empno in (7369, 7499, 7521) from emp;
EnumerableCalc(expr#0..5=[{inputs}], expr#6=[IS NOT NULL($t5)],
expr#7=[0:BIGINT], expr#8=[<>($t1, $t7)], expr#9=[AND($t6, $t8)],
expr#10=[<($t2, $t1)], expr#11=[null:BOOLEAN], expr#12=[IS NULL($t5)],
expr#13=[AND($t10, $t11, $t8, $t12)], expr#14=[OR($t9, $t13)],
expr#15=[CAST($t14):BOOLEAN NOT NULL], EMPNO=[$t0], EXPR$1=[$t15])
EnumerableMergeJoin(condition=[=($3, $4)], joinType=[left])
EnumerableSort(sort0=[$3], dir0=[ASC])
- EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t2], $f0=[$t0], $f1=[$t1],
EMPNO0=[$t2])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t2):INTEGER NOT
NULL], EMPNO=[$t2], $f0=[$t0], $f1=[$t1], EMPNO0=[$t3])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableCalc(expr#0=[{inputs}], $f0=[$t0], $f00=[$t0])
EnumerableAggregate(group=[{}], agg#0=[COUNT()])
@@ -3933,17 +3942,11 @@ EnumerableCalc(expr#0..5=[{inputs}], expr#6=[IS NOT
NULL($t5)], expr#7=[0:BIGINT
EnumerableTableScan(table=[[scott, EMP]])
EnumerableCalc(expr#0=[{inputs}], $f0=[$t0], $f00=[$t0])
EnumerableAggregate(group=[{}], agg#0=[COUNT()])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00 }]])
+ EnumerableValues(tuples=[[{ 500.00 }, { 300.00 }, { 0.00 }]])
EnumerableSort(sort0=[$0], dir0=[ASC])
EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00 }]])
+ EnumerableValues(tuples=[[{ 500.00 }, { 300.00 }, { 0.00 }]])
!plan
# Test LHS is nullable and RHS is nullable
@@ -3979,19 +3982,11 @@ EnumerableCalc(expr#0..5=[{inputs}], expr#6=[IS NOT
NULL($t5)], expr#7=[0:BIGINT
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], COMM=[$t6])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00 }]])
- EnumerableValues(tuples=[[{ null }]])
+ EnumerableValues(tuples=[[{ 500.00 }, { 300.00 }, { 0.00 }, { null
}]])
EnumerableSort(sort0=[$0], dir0=[ASC])
EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00 }]])
- EnumerableValues(tuples=[[{ null }]])
+ EnumerableValues(tuples=[[{ 500.00 }, { 300.00 }, { 0.00 }, { null
}]])
!plan
# Test LHS is (not nullable, not nullable) and RHS is (not nullable, not
nullable)
@@ -4022,7 +4017,7 @@ select empno, (empno, empno) in ((7369, 7369), (7499,
7499), (7521, 7521)) from
EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t7)],
expr#9=[0:BIGINT], expr#10=[<>($t1, $t9)], expr#11=[AND($t8, $t10)],
expr#12=[<($t2, $t1)], expr#13=[null:BOOLEAN], expr#14=[IS NULL($t7)],
expr#15=[AND($t12, $t13, $t10, $t14)], expr#16=[OR($t11, $t15)],
expr#17=[CAST($t16):BOOLEAN NOT NULL], EMPNO=[$t0], EXPR$1=[$t17])
EnumerableMergeJoin(condition=[AND(=($3, $5), =($4, $6))], joinType=[left])
EnumerableSort(sort0=[$3], sort1=[$4], dir0=[ASC], dir1=[ASC])
- EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t2], $f0=[$t0], $f1=[$t1],
EMPNO0=[$t2], EMPNO1=[$t2])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t2):INTEGER NOT
NULL], EMPNO=[$t2], $f0=[$t0], $f1=[$t1], EMPNO0=[$t3], EMPNO1=[$t3])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableCalc(expr#0=[{inputs}], $f0=[$t0], $f00=[$t0])
EnumerableAggregate(group=[{}], agg#0=[COUNT()])
@@ -4068,17 +4063,11 @@ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT
NULL($t7)], expr#9=[0:BIGINT
EnumerableTableScan(table=[[scott, EMP]])
EnumerableCalc(expr#0=[{inputs}], $f0=[$t0], $f00=[$t0])
EnumerableAggregate(group=[{}], agg#0=[COUNT()])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00, 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00, 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00, 0.00 }]])
+ EnumerableValues(tuples=[[{ 500.00, 500.00 }, { 300.00, 300.00
}, { 0.00, 0.00 }]])
EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
EnumerableAggregate(group=[{0, 1}], agg#0=[MIN($2)])
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true],
proj#0..2=[{exprs}])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00, 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00, 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00, 0.00 }]])
+ EnumerableValues(tuples=[[{ 500.00, 500.00 }, { 300.00, 300.00 }, {
0.00, 0.00 }]])
!plan
# Test LHS is (nullable, nullable) and RHS is (nullable, nullable)
@@ -4114,19 +4103,145 @@ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT
NULL($t7)], expr#9=[0:BIGINT
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], COMM=[$t6])
EnumerableTableScan(table=[[scott, EMP]])
EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0,
$1)])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00, 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00, 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00, 0.00 }]])
- EnumerableValues(tuples=[[{ null, null }]])
+ EnumerableValues(tuples=[[{ 500.00, 500.00 }, { 300.00, 300.00 },
{ 0.00, 0.00 }, { null, null }]])
EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
EnumerableAggregate(group=[{0, 1}], agg#0=[MIN($2)])
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true],
proj#0..2=[{exprs}])
- EnumerableUnion(all=[true])
- EnumerableValues(tuples=[[{ 500.00, 500.00 }]])
- EnumerableValues(tuples=[[{ 300.00, 300.00 }]])
- EnumerableValues(tuples=[[{ 0.00, 0.00 }]])
- EnumerableValues(tuples=[[{ null, null }]])
+ EnumerableValues(tuples=[[{ 500.00, 500.00 }, { 300.00, 300.00 }, {
0.00, 0.00 }, { null, null }]])
+!plan
+
+# [CALCITE-5156] Support implicit integer types cast for IN Sub-query
+
+# Test case about the IN sub-query left operand type is INTEGER and right
operand type is TINYINT
+select *
+from dept
+where deptno + 20 in (select deptno from dept);
++--------+------------+----------+
+| DEPTNO | DNAME | LOC |
++--------+------------+----------+
+| 10 | ACCOUNTING | NEW YORK |
+| 20 | RESEARCH | DALLAS |
++--------+------------+----------+
+(2 rows)
+
+!ok
+
+EnumerableCalc(expr#0..3=[{inputs}], proj#0..2=[{exprs}])
+ EnumerableHashJoin(condition=[=($3, $4)], joinType=[semi])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[20], expr#4=[+($t0, $t3)],
proj#0..2=[{exprs}], $f3=[$t4])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):INTEGER NOT NULL],
EXPR$0=[$t3])
+ EnumerableTableScan(table=[[scott, DEPT]])
+!plan
+
+# Test case about the IN sub-query left operand type is BIGINT and right
operand type is TINYINT
+select *
+from dept
+where cast(deptno as bigint) in (select deptno from dept);
++--------+------------+----------+
+| DEPTNO | DNAME | LOC |
++--------+------------+----------+
+| 10 | ACCOUNTING | NEW YORK |
+| 20 | RESEARCH | DALLAS |
+| 30 | SALES | CHICAGO |
+| 40 | OPERATIONS | BOSTON |
++--------+------------+----------+
+(4 rows)
+
+!ok
+
+EnumerableCalc(expr#0..3=[{inputs}], proj#0..2=[{exprs}])
+ EnumerableHashJoin(condition=[=($3, $4)], joinType=[semi])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):BIGINT NOT NULL],
proj#0..3=[{exprs}])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t0):BIGINT NOT NULL],
EXPR$0=[$t3])
+ EnumerableTableScan(table=[[scott, DEPT]])
+!plan
+
+# Test case about the IN sub-query left operand type is INTEGER and right
operand type is BIGINT
+select *
+from dept
+where deptno + 10 in (select count(*) + 10 from emp where comm is null);
++--------+------------+----------+
+| DEPTNO | DNAME | LOC |
++--------+------------+----------+
+| 10 | ACCOUNTING | NEW YORK |
++--------+------------+----------+
+(1 row)
+
+!ok
+
+EnumerableCalc(expr#0..3=[{inputs}], proj#0..2=[{exprs}])
+ EnumerableHashJoin(condition=[=($3, $4)], joinType=[semi])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[10], expr#4=[+($t0, $t3)],
expr#5=[CAST($t4):BIGINT NOT NULL], proj#0..2=[{exprs}], $f3=[$t5])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[10], expr#2=[+($t0, $t1)],
EXPR$0=[$t2])
+ EnumerableAggregate(group=[{}], agg#0=[COUNT()])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NULL($t6)],
proj#0..7=[{exprs}], $condition=[$t8])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Test case about the IN sub-query left operand type is SMALLINT and right
operand type is TINYINT
+select *
+from emp
+where cast(empno - 7349 as smallint) in (select deptno from emp) and ename =
'SMITH';
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+
+EnumerableCalc(expr#0..8=[{inputs}], proj#0..7=[{exprs}])
+ EnumerableHashJoin(condition=[=($8, $9)], joinType=[semi])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[7349], expr#9=[-($t0, $t8)],
expr#10=[CAST($t9):SMALLINT NOT NULL], expr#11=['SMITH':VARCHAR(10)],
expr#12=[=($t1, $t11)], proj#0..7=[{exprs}], $f8=[$t10], $condition=[$t12])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t7):SMALLINT],
EXPR$0=[$t8])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Test case about the IN sub-query left operand type is SMALLINT and right
operand type is INTEGER
+select *
+from emp
+where empno in (select deptno + 7349 from emp);
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+
+EnumerableCalc(expr#0..8=[{inputs}], proj#0..7=[{exprs}])
+ EnumerableHashJoin(condition=[=($8, $9)], joinType=[semi])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t0):INTEGER NOT NULL],
proj#0..8=[{exprs}])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[7349], expr#9=[+($t7, $t8)],
EXPR$0=[$t9])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Test case about the IN sub-query left operand type is SMALLINT and right
operand type is BIGINT
+select *
+from emp
+where empno in (select cast(deptno + 7349 as bigint) from emp);
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+
+EnumerableCalc(expr#0..8=[{inputs}], proj#0..7=[{exprs}])
+ EnumerableHashJoin(condition=[=($8, $9)], joinType=[semi])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t0):BIGINT NOT NULL],
proj#0..8=[{exprs}])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[7349], expr#9=[+($t7, $t8)],
expr#10=[CAST($t9):BIGINT], EXPR$0=[$t10])
+ EnumerableTableScan(table=[[scott, EMP]])
!plan
# End sub-query.iq
diff --git
a/kafka/src/test/java/org/apache/calcite/adapter/kafka/KafkaAdapterTest.java
b/kafka/src/test/java/org/apache/calcite/adapter/kafka/KafkaAdapterTest.java
index 13088474cc..7ed08f0ab0 100644
--- a/kafka/src/test/java/org/apache/calcite/adapter/kafka/KafkaAdapterTest.java
+++ b/kafka/src/test/java/org/apache/calcite/adapter/kafka/KafkaAdapterTest.java
@@ -84,7 +84,7 @@ class KafkaAdapterTest {
.returnsUnordered(
"MSG_PARTITION=0; MSG_OFFSET=1; MSG_VALUE_BYTES=myvalue1")
.explainContains(
- "PLAN=EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0],
expr#6=[>($t2, $t5)], MSG_PARTITION=[$t0], MSG_OFFSET=[$t2],
MSG_VALUE_BYTES=[$t4], $condition=[$t6])\n"
+ "PLAN=EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0:BIGINT],
expr#6=[>($t2, $t5)], MSG_PARTITION=[$t0], MSG_OFFSET=[$t2],
MSG_VALUE_BYTES=[$t4], $condition=[$t6])\n"
+ " EnumerableInterpreter\n"
+ " BindableTableScan(table=[[KAFKA, MOCKTABLE,
(STREAM)]])");
}
diff --git a/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
b/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
index 10448b118f..1f57407683 100644
--- a/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
+++ b/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
@@ -220,7 +220,7 @@ class SparkAdapterTest {
+ "having count(*) > 2";
final String plan = "PLAN="
- + "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[2], expr#3=[>($t1,
$t2)], X=[$t0], $condition=[$t3])\n"
+ + "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[2:BIGINT],
expr#3=[>($t1, $t2)], X=[$t0], $condition=[$t3])\n"
+ " EnumerableAggregate(group=[{0}], agg#0=[COUNT()])\n"
+ " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, {
2, 'c' }, { 2, 'c' }]])\n\n";
@@ -240,9 +240,7 @@ class SparkAdapterTest {
+ "from " + VALUES2;
final String plan = "PLAN="
- + "EnumerableUnion(all=[true])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }]])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, {
2, 'c' }, { 2, 'c' }]])\n";
+ + "EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'a' }, { 2,
'b' }, { 1, 'b' }, { 2, 'c' }, { 2, 'c' }]])\n\n";
final String[] expectedResult = {
"X=1; Y=a",
@@ -266,9 +264,7 @@ class SparkAdapterTest {
+ "from " + VALUES2;
final String plan = "PLAN="
- + "EnumerableUnion(all=[false])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }]])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, {
2, 'c' }, { 2, 'c' }]])\n";
+ + "EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, { 2,
'c' }]])\n\n";
final String[] expectedResult = {
"X=1; Y=a",