Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,29 @@ private void handleOffsetFetch(@Nullable SqlNode offset, @Nullable SqlNode fetch
if (node instanceof SqlMerge) {
validatingSqlMerge = true;
}
if (node instanceof SqlJoin) {
// select * from "scott".dept,
// lateral (select count(cast(deptno as integer)) from "scott".emp
// where emp.deptno = dept.deptno);
// ==》
// select * from "scott".dept left join
// lateral (select count(cast(deptno as integer)) from "scott".emp
// where emp.deptno = dept.deptno) on true;
SqlJoin sqlJoin = (SqlJoin) node;
if (sqlJoin.getJoinType() == JoinType.COMMA && sqlJoin.getRight() instanceof SqlCall) {
SqlCall sqlCall = (SqlCall) sqlJoin.getRight();
if (sqlCall.getOperator() == SqlStdOperatorTable.LATERAL
&& sqlCall.operand(0) instanceof SqlSelect
&& isAggregate(sqlCall.operand(0))) {
return performUnconditionalRewrites(
new SqlJoin(sqlJoin.getParserPosition(),
sqlJoin.getLeft(), sqlJoin.isNaturalNode(),
JoinType.LEFT.symbol(node.getParserPosition()),
sqlJoin.getRight(), JoinConditionType.ON.symbol(node.getParserPosition()),
SqlLiteral.createBoolean(true, node.getParserPosition())), underFrom);
}
}
}
SqlCall call = (SqlCall) node;
final SqlKind kind = call.getKind();
final List<SqlNode> operands = call.getOperandList();
Expand Down
95 changes: 95 additions & 0 deletions core/src/test/resources/sql/lateral.iq
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,99 @@ where job = 'MANAGER';

!ok

# [CALCITE-4693] Query with Lateral Join should converted to Left Join When sub-query is aggregate query

select * from "scott".dept, lateral (select count(cast(deptno as integer)) from "scott".emp where emp.deptno = dept.deptno);

SELECT "DEPT"."DEPTNO", "DEPT"."DNAME", "DEPT"."LOC", "EXPR$0"."EXPR$0"
FROM "scott"."DEPT" AS "DEPT"
LEFT JOIN (SELECT COUNT(CAST("EMP"."DEPTNO" AS INTEGER))
FROM "scott"."EMP" AS "EMP"
WHERE "EMP"."DEPTNO" = "DEPT"."DEPTNO") AS "EXPR$0" ON TRUE
!explain-validated-on calcite
+--------+------------+----------+--------+
| DEPTNO | DNAME | LOC | EXPR$0 |
+--------+------------+----------+--------+
| 10 | ACCOUNTING | NEW YORK | 3 |
| 20 | RESEARCH | DALLAS | 5 |
| 30 | SALES | CHICAGO | 6 |
| 40 | OPERATIONS | BOSTON | 0 |
+--------+------------+----------+--------+
(4 rows)

!ok

select * from "scott".dept, lateral (select count(cast(deptno as integer)) from "scott".emp where emp.deptno = dept.deptno having count(cast(deptno as integer)) > 0);

+--------+------------+----------+--------+
| DEPTNO | DNAME | LOC | EXPR$0 |
+--------+------------+----------+--------+
| 10 | ACCOUNTING | NEW YORK | 3 |
| 20 | RESEARCH | DALLAS | 5 |
| 30 | SALES | CHICAGO | 6 |
+--------+------------+----------+--------+
(4 rows)

!ok

select * from "scott".dept, lateral (select count(cast(deptno as integer)) from "scott".emp where emp.deptno = dept.deptno + 10);

SELECT "DEPT"."DEPTNO", "DEPT"."DNAME", "DEPT"."LOC", "EXPR$0"."EXPR$0"
FROM "scott"."DEPT" AS "DEPT"
LEFT JOIN (SELECT COUNT(CAST("EMP"."DEPTNO" AS INTEGER))
FROM "scott"."EMP" AS "EMP"
WHERE CAST("EMP"."DEPTNO" AS INTEGER) = "DEPT"."DEPTNO" + 10) AS "EXPR$0" ON TRUE
!explain-validated-on calcite
+--------+------------+----------+--------+
| DEPTNO | DNAME | LOC | EXPR$0 |
+--------+------------+----------+--------+
| 10 | ACCOUNTING | NEW YORK | 5 |
| 20 | RESEARCH | DALLAS | 6 |
| 30 | SALES | CHICAGO | 0 |
| 40 | OPERATIONS | BOSTON | 0 |
+--------+------------+----------+--------+
(4 rows)

!ok

select * from "scott".dept, lateral (select sum(cast(deptno as integer)) from "scott".emp where emp.deptno = dept.deptno);

SELECT "DEPT"."DEPTNO", "DEPT"."DNAME", "DEPT"."LOC", "EXPR$0"."EXPR$0"
FROM "scott"."DEPT" AS "DEPT"
LEFT JOIN (SELECT SUM(CAST("EMP"."DEPTNO" AS INTEGER))
FROM "scott"."EMP" AS "EMP"
WHERE "EMP"."DEPTNO" = "DEPT"."DEPTNO") AS "EXPR$0" ON TRUE
!explain-validated-on calcite
+--------+------------+----------+--------+
| DEPTNO | DNAME | LOC | EXPR$0 |
+--------+------------+----------+--------+
| 10 | ACCOUNTING | NEW YORK | 30 |
| 20 | RESEARCH | DALLAS | 100 |
| 30 | SALES | CHICAGO | 180 |
| 40 | OPERATIONS | BOSTON | |
+--------+------------+----------+--------+
(4 rows)

!ok

select * from "scott".dept, lateral (select sum(cast(deptno as integer)) from "scott".emp where emp.deptno = dept.deptno + 10);

SELECT "DEPT"."DEPTNO", "DEPT"."DNAME", "DEPT"."LOC", "EXPR$0"."EXPR$0"
FROM "scott"."DEPT" AS "DEPT"
LEFT JOIN (SELECT SUM(CAST("EMP"."DEPTNO" AS INTEGER))
FROM "scott"."EMP" AS "EMP"
WHERE CAST("EMP"."DEPTNO" AS INTEGER) = "DEPT"."DEPTNO" + 10) AS "EXPR$0" ON TRUE
!explain-validated-on calcite
+--------+------------+----------+--------+
| DEPTNO | DNAME | LOC | EXPR$0 |
+--------+------------+----------+--------+
| 10 | ACCOUNTING | NEW YORK | 100 |
| 20 | RESEARCH | DALLAS | 180 |
| 30 | SALES | CHICAGO | |
| 40 | OPERATIONS | BOSTON | |
+--------+------------+----------+--------+
(4 rows)

!ok

# End lateral.iq
Loading