From 55d4ae98a3e5e0baddd19c73baf8e40d547f8d2d Mon Sep 17 00:00:00 2001 From: Andy Fan Date: Tue, 21 Mar 2023 08:49:18 +0800 Subject: [PATCH v1] test case and comments to help understand why we have to pull_up_sublinks_qual_recurse to either LHS or RHS. --- src/backend/optimizer/prep/prepjointree.c | 4 +++- src/test/regress/expected/subselect.out | 23 +++++++++++++++++++++++ src/test/regress/sql/subselect.sql | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 870d84b29d7..1b73512e32e 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -503,7 +503,9 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, /* * Now recursively process the pulled-up quals. Any inserted * joins can get stacked onto either j->larg or j->rarg, - * depending on which rels they reference. + * depending on which rels they reference. We shouldn't get + * stacked into the JoinExpr since the we want to scan all the + * rows in j->rarg to matches the j->quals. */ j->quals = pull_up_sublinks_qual_recurse(root, j->quals, diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 22af8fafa17..fe17ea32f6c 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -1926,3 +1926,26 @@ select * from x for update; Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 (2 rows) +CREATE TEMP TABLE tt1 (a int, b int, c int) ON COMMIT DELETE ROWS; +CREATE TEMP TABLE tt2 (a int, b int, c int) ON COMMIT DELETE ROWS; +CREATE TEMP TABLE tt3 (a int, b int, c int) ON COMMIT DELETE ROWS; +BEGIN; +insert into tt1 select 1, 1, 2; +insert into tt2 select 1, 2, 1; +insert into tt2 select 1, 1, 2; +insert into tt3 select 1, 1, 2; +-- the exist clause about tt3 should not be pull-up as a semi join since +-- it references to both tt1 and tt2. +select * from tt1 +where exists (select 1 from tt2 + where exists (select 1 from tt3 + where tt1.c = tt2.c + and tt2.b = tt3.b) +and tt1.a = tt2.a); + a | b | c +---+---+--- + 1 | 1 | 2 +(1 row) + +COMMIT; + diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 40276708c99..49509b60b01 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -968,3 +968,25 @@ select * from (with x as (select 2 as y) select * from x) ss; explain (verbose, costs off) with x as (select * from subselect_tbl) select * from x for update; + + +CREATE TEMP TABLE tt1 (a int, b int, c int) ON COMMIT DELETE ROWS; +CREATE TEMP TABLE tt2 (a int, b int, c int) ON COMMIT DELETE ROWS; +CREATE TEMP TABLE tt3 (a int, b int, c int) ON COMMIT DELETE ROWS; + +BEGIN; +insert into tt1 select 1, 1, 2; +insert into tt2 select 1, 2, 1; +insert into tt2 select 1, 1, 2; +insert into tt3 select 1, 1, 2; + +-- the exist clause about tt3 should not be pull-up as a semi join since +-- it references to both tt1 and tt2. +select * from tt1 +where exists (select 1 from tt2 + where exists (select 1 from tt3 + where tt1.c = tt2.c + and tt2.b = tt3.b) +and tt1.a = tt2.a); +COMMIT; + -- 2.21.0