Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain where the discussion in the JIRA is reflected in this code?
I think the consensus there was that a left join is not always right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, @mihaibudiu. The jira cases discusses how converting an inner lateral join to a left join is WRONG. Do not merge this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will recheck this. This repair method does have some issues. I will add more test cases to verify it.

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
82 changes: 82 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,86 @@ 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 + 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