From: Tom Lane Date: Sun, 23 May 2010 16:34:38 +0000 (+0000) Subject: Fix oversight in join removal patch: we have to delete the removed relation X-Git-Tag: REL9_0_BETA2~82 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7df4cf7fd3aff6a3ebc4a223bb98c768e9bbe821;p=postgresql Fix oversight in join removal patch: we have to delete the removed relation from SpecialJoinInfo relid sets as well. Per example from Vaclav Novotny. --- diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index da6482b4c3..a06e647f4b 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -16,7 +16,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/analyzejoins.c,v 1.1 2010/03/28 22:59:32 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/analyzejoins.c,v 1.2 2010/05/23 16:34:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -343,6 +343,24 @@ remove_rel_from_query(PlannerInfo *root, int relid) } } + /* + * Likewise remove references from SpecialJoinInfo data structures. + * + * This is relevant in case the outer join we're deleting is nested + * inside other outer joins: the upper joins' relid sets have to be + * adjusted. The RHS of the target outer join will be made empty here, + * but that's OK since caller will delete that SpecialJoinInfo entirely. + */ + foreach(l, root->join_info_list) + { + SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); + + sjinfo->min_lefthand = bms_del_member(sjinfo->min_lefthand, relid); + sjinfo->min_righthand = bms_del_member(sjinfo->min_righthand, relid); + sjinfo->syn_lefthand = bms_del_member(sjinfo->syn_lefthand, relid); + sjinfo->syn_righthand = bms_del_member(sjinfo->syn_righthand, relid); + } + /* * Likewise remove references from PlaceHolderVar data structures. * diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 5fd7d79b45..6dfc710be0 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -2525,6 +2525,20 @@ explain (costs off) Seq Scan on a (1 row) +-- check optimization of outer join within another special join +explain (costs off) +select id from a where id in ( + select b.id from b left join c on b.id = c.id +); + QUERY PLAN +---------------------------- + Hash Semi Join + Hash Cond: (a.id = b.id) + -> Seq Scan on a + -> Hash + -> Seq Scan on b +(5 rows) + rollback; create temp table parent (k int primary key, pd int); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "parent_pkey" for table "parent" diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index d627973a09..8657636757 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -588,6 +588,12 @@ explain (costs off) SELECT a.* FROM a LEFT JOIN (b left join c on b.c_id = c.id) ON (a.b_id = b.id); +-- check optimization of outer join within another special join +explain (costs off) +select id from a where id in ( + select b.id from b left join c on b.id = c.id +); + rollback; create temp table parent (k int primary key, pd int);