@@ -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