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