Skip to content

Commit

Permalink
[CALCITE-5156] Support implicit integer types cast for IN Sub-query
Browse files Browse the repository at this point in the history
  • Loading branch information
NobiGo authored and tanclary committed Oct 22, 2024
1 parent 9aeadd0 commit 6f1cbad
Show file tree
Hide file tree
Showing 16 changed files with 341 additions and 120 deletions.
2 changes: 1 addition & 1 deletion babel/src/test/resources/sql/redshift.iq
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ private 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,6 @@ protected boolean needToCast(SqlValidatorScope scope, SqlNode node,
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3854,7 +3854,7 @@ private SqlDialect nonOrdinalDialect() {
+ "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);
Expand Down Expand Up @@ -4200,7 +4200,7 @@ private SqlDialect nonOrdinalDialect() {
+ "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);
Expand All @@ -4221,7 +4221,7 @@ private SqlDialect nonOrdinalDialect() {
+ "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);
Expand All @@ -4245,13 +4245,13 @@ private SqlDialect nonOrdinalDialect() {
+ "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);
Expand Down Expand Up @@ -4348,8 +4348,8 @@ private SqlDialect nonOrdinalDialect() {
+ "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)
Expand Down Expand Up @@ -8303,7 +8303,7 @@ private void checkLiteral2(String expression, String expected) {
+ "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.
Expand Down
20 changes: 10 additions & 10 deletions core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/org/apache/calcite/test/JdbcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5017,7 +5017,7 @@ private void startOfGroupStep3(String startOfGroup) {
+ "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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public static void checkActualAndReferenceFiles() {
*/
@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";
Expand Down Expand Up @@ -4142,6 +4142,23 @@ void checkCorrelatedMapSubQuery(boolean expand) {
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>. */
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/org/apache/calcite/test/StreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private static String schemaFor(String name, Class<? extends TableFactory> clazz
+ " 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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,26 @@ public static void checkActualAndReferenceFiles() {
.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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]])
Expand Down Expand Up @@ -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]])
Expand Down Expand Up @@ -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
Expand All @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
6 changes: 3 additions & 3 deletions core/src/test/resources/sql/agg.iq
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion core/src/test/resources/sql/conditions.iq
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 6f1cbad

Please sign in to comment.