Skip to content

Commit 8b2924a

Browse files
[CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree when using correlated sub-query in on clause of equi-join
1 parent f451b2a commit 8b2924a

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

core/src/test/resources/sql/sub-query.iq

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8467,5 +8467,284 @@ ON t2.a = foo.a
84678467
+---+---+---+
84688468
(1 row)
84698469

8470+
!ok
8471+
8472+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8473+
# when using correlated sub-query in on clause of equi-join
8474+
# Case 1: Correlated scalar subquery in ON clause of INNER JOIN
8475+
#
8476+
# before fix return wrong result 0 rows and the wrong plan after SubQueryRemoveRule is:
8477+
# LogicalProject(ID=[$0], ID0=[$1])
8478+
# LogicalProject(id=[$0], id0=[$1])
8479+
# LogicalJoin(condition=[=($2, $1)], joinType=[inner])
8480+
# LogicalTableScan(table=[[a]])
8481+
# LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{0}])
8482+
# LogicalTableScan(table=[[c]])
8483+
# LogicalAggregate(group=[{}], EXPR$0=[MIN($0)])
8484+
# LogicalProject(fk_c=[$2])
8485+
# LogicalFilter(condition=[=($cor0.id, $1)])
8486+
# LogicalTableScan(table=[[b]])
8487+
#
8488+
# after fix the plan after SubQueryRemoveRule is:
8489+
# LogicalProject(ID=[$0], ID0=[$1])
8490+
# LogicalProject(id=[$0], id0=[$2])
8491+
# LogicalJoin(condition=[=($1, $2)], joinType=[inner])
8492+
# LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{0}])
8493+
# LogicalTableScan(table=[[a]])
8494+
# LogicalAggregate(group=[{}], EXPR$0=[MIN($0)])
8495+
# LogicalProject(fk_c=[$2])
8496+
# LogicalFilter(condition=[=($cor0.id, $1)])
8497+
# LogicalTableScan(table=[[b]])
8498+
# LogicalTableScan(table=[[c]])
8499+
WITH
8500+
A(id) AS (VALUES (101), (102)),
8501+
C(id) AS (VALUES (301), (302)),
8502+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8503+
SELECT A.id, C.id
8504+
FROM A
8505+
INNER JOIN C
8506+
ON (
8507+
SELECT min(B.fk_C)
8508+
FROM B
8509+
WHERE A.id = B.fk_A
8510+
) = C.id;
8511+
+-----+-----+
8512+
| ID | ID |
8513+
+-----+-----+
8514+
| 101 | 301 |
8515+
+-----+-----+
8516+
(1 row)
8517+
8518+
!ok
8519+
8520+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8521+
# when using correlated sub-query in on clause of equi-join
8522+
# Case 1 (Verification): Manual rewrite of Case 1 using a derived table
8523+
WITH
8524+
A(id) AS (VALUES (101), (102)),
8525+
C(id) AS (VALUES (301), (302)),
8526+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8527+
SELECT A.id, C.id
8528+
FROM (
8529+
SELECT
8530+
*,
8531+
(SELECT min(B.fk_C) FROM B WHERE A.id = B.fk_A) AS fk_C
8532+
FROM A
8533+
) AS A
8534+
INNER JOIN C
8535+
ON fk_c = C.id;
8536+
+-----+-----+
8537+
| ID | ID |
8538+
+-----+-----+
8539+
| 101 | 301 |
8540+
+-----+-----+
8541+
(1 row)
8542+
8543+
!ok
8544+
8545+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8546+
# when using correlated sub-query in on clause of equi-join
8547+
# Case 2: Correlated scalar subquery in ON clause of LEFT JOIN
8548+
WITH
8549+
A(id) AS (VALUES (101), (102)),
8550+
C(id) AS (VALUES (301), (302)),
8551+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8552+
SELECT A.id, C.id
8553+
FROM A
8554+
LEFT JOIN C
8555+
ON (
8556+
SELECT min(B.fk_C)
8557+
FROM B
8558+
WHERE A.id = B.fk_A
8559+
) = C.id;
8560+
+-----+-----+
8561+
| ID | ID |
8562+
+-----+-----+
8563+
| 101 | 301 |
8564+
| 102 | |
8565+
+-----+-----+
8566+
(2 rows)
8567+
8568+
!ok
8569+
8570+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8571+
# when using correlated sub-query in on clause of equi-join
8572+
# Case 2 (Verification): Manual rewrite of Case 2 using a derived table
8573+
WITH
8574+
A(id) AS (VALUES (101), (102)),
8575+
C(id) AS (VALUES (301), (302)),
8576+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8577+
SELECT A.id, C.id
8578+
FROM (
8579+
SELECT
8580+
*,
8581+
(SELECT min(B.fk_C) FROM B WHERE A.id = B.fk_A) AS fk_C
8582+
FROM A
8583+
) AS A
8584+
LEFT JOIN C
8585+
ON fk_c = C.id;
8586+
+-----+-----+
8587+
| ID | ID |
8588+
+-----+-----+
8589+
| 101 | 301 |
8590+
| 102 | |
8591+
+-----+-----+
8592+
(2 rows)
8593+
8594+
!ok
8595+
8596+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8597+
# when using correlated sub-query in on clause of equi-join
8598+
# Case 3: Correlated scalar subquery in ON clause of RIGHT JOIN.
8599+
# The subquery correlates to the RHS table (A), which is the PRESERVED side.
8600+
WITH
8601+
A(id) AS (VALUES (101), (102)),
8602+
C(id) AS (VALUES (301), (302)),
8603+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8604+
SELECT A.id, C.id
8605+
FROM C
8606+
RIGHT JOIN A
8607+
ON (
8608+
SELECT min(B.fk_C)
8609+
FROM B
8610+
WHERE A.id = B.fk_A
8611+
) = C.id;
8612+
+-----+-----+
8613+
| ID | ID |
8614+
+-----+-----+
8615+
| 101 | 301 |
8616+
| 102 | |
8617+
+-----+-----+
8618+
(2 rows)
8619+
8620+
!ok
8621+
8622+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8623+
# when using correlated sub-query in on clause of equi-join
8624+
# Case 3 (Verification): Manual rewrite of Case 3 using a derived table.
8625+
# Projects the scalar subquery on the RHS (preserved side).
8626+
WITH
8627+
A(id) AS (VALUES (101), (102)),
8628+
C(id) AS (VALUES (301), (302)),
8629+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8630+
SELECT A.id, C.id
8631+
FROM C
8632+
RIGHT JOIN (
8633+
SELECT
8634+
*,
8635+
(SELECT min(B.fk_C) FROM B WHERE A.id = B.fk_A) AS fk_C
8636+
FROM A
8637+
) AS A
8638+
ON fk_c = C.id;
8639+
+-----+-----+
8640+
| ID | ID |
8641+
+-----+-----+
8642+
| 101 | 301 |
8643+
| 102 | |
8644+
+-----+-----+
8645+
(2 rows)
8646+
8647+
!ok
8648+
8649+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8650+
# when using correlated sub-query in on clause of equi-join
8651+
# Case 4: Correlated scalar subquery in ON clause of LEFT JOIN
8652+
WITH
8653+
A(id) AS (VALUES (101), (102)),
8654+
C(id) AS (VALUES (301), (302)),
8655+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8656+
SELECT A.id, C.id
8657+
FROM C
8658+
LEFT JOIN A
8659+
ON (
8660+
SELECT min(B.fk_C)
8661+
FROM B
8662+
WHERE A.id = B.fk_A
8663+
) = C.id;
8664+
+-----+-----+
8665+
| ID | ID |
8666+
+-----+-----+
8667+
| 101 | 301 |
8668+
| | 302 |
8669+
+-----+-----+
8670+
(2 rows)
8671+
8672+
!ok
8673+
8674+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8675+
# when using correlated sub-query in on clause of equi-join
8676+
# Case 4 (Verification): Manual rewrite of Case 4 using a derived table
8677+
WITH
8678+
A(id) AS (VALUES (101), (102)),
8679+
C(id) AS (VALUES (301), (302)),
8680+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8681+
SELECT A.id, C.id
8682+
FROM C
8683+
LEFT JOIN (
8684+
SELECT
8685+
*,
8686+
(SELECT min(B.fk_C) FROM B WHERE A.id = B.fk_A) AS fk_C
8687+
FROM A
8688+
) AS A
8689+
ON fk_c = C.id;
8690+
+-----+-----+
8691+
| ID | ID |
8692+
+-----+-----+
8693+
| 101 | 301 |
8694+
| | 302 |
8695+
+-----+-----+
8696+
(2 rows)
8697+
8698+
!ok
8699+
8700+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8701+
# when using correlated sub-query in on clause of equi-join
8702+
# Case 5: Correlated scalar subquery in ON clause of RIGHT JOIN
8703+
WITH
8704+
A(id) AS (VALUES (101), (102)),
8705+
C(id) AS (VALUES (301), (302)),
8706+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8707+
SELECT A.id, C.id
8708+
FROM A
8709+
RIGHT JOIN C
8710+
ON (
8711+
SELECT min(B.fk_C)
8712+
FROM B
8713+
WHERE A.id = B.fk_A
8714+
) = C.id;
8715+
+-----+-----+
8716+
| ID | ID |
8717+
+-----+-----+
8718+
| 101 | 301 |
8719+
| | 302 |
8720+
+-----+-----+
8721+
(2 rows)
8722+
8723+
!ok
8724+
8725+
# [CALCITE-6504] JOIN_SUB_QUERY_TO_CORRELATE/Join SubQueryRemoveRule produces incorrect tree
8726+
# when using correlated sub-query in on clause of equi-join
8727+
# Case 5 (Verification): Manual rewrite of Case 5 using a derived table
8728+
WITH
8729+
A(id) AS (VALUES (101), (102)),
8730+
C(id) AS (VALUES (301), (302)),
8731+
B(id, fk_A, fk_C) AS (VALUES (201, 101, 301), (202, 101, 999), (203, 999, 301), (204, 999, 999))
8732+
SELECT A.id, C.id
8733+
FROM (
8734+
SELECT
8735+
*,
8736+
(SELECT min(B.fk_C) FROM B WHERE A.id = B.fk_A) AS fk_C
8737+
FROM A
8738+
) AS A
8739+
RIGHT JOIN C
8740+
ON fk_c = C.id;
8741+
+-----+-----+
8742+
| ID | ID |
8743+
+-----+-----+
8744+
| 101 | 301 |
8745+
| | 302 |
8746+
+-----+-----+
8747+
(2 rows)
8748+
84708749
!ok
84718750
# End sub-query.iq

0 commit comments

Comments
 (0)