diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-22 13:57:16 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-22 13:57:16 +0000 |
commit | 8d3c4aa614e20375daeff0bb1b9f640b115f363e (patch) | |
tree | b455eb7bb9acd7510dfb51a6931de638596d0111 /src/backend/optimizer/path/joinpath.c | |
parent | ecac5e6bfc3b236b41ea282f5625203d5ee90b55 (diff) |
Fix an oversight in join-removal optimization: we have to check not only for
plain Vars that are generated in the inner rel and used above the join, but
also for PlaceHolderVars. Per report from Oleg K.
Diffstat (limited to 'src/backend/optimizer/path/joinpath.c')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 35c9353d2e2..f069f13fefb 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.130 2010/02/26 02:00:44 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.131 2010/03/22 13:57:15 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -192,7 +192,9 @@ clause_sides_match_join(RestrictInfo *rinfo, RelOptInfo *outerrel, * * This is true for a left join for which the join condition cannot match * more than one inner-side row. (There are other possibly interesting - * cases, but we don't have the infrastructure to prove them.) + * cases, but we don't have the infrastructure to prove them.) We also + * have to check that the inner side doesn't generate any variables needed + * above the join. * * Note: there is no need to consider the symmetrical case of duplicating the * right input, because add_paths_to_joinrel() will be called with each rel @@ -246,6 +248,19 @@ join_is_removable(PlannerInfo *root, } /* + * Similarly check that the inner rel doesn't produce any PlaceHolderVars + * that will be used above the join. + */ + foreach(l, root->placeholder_list) + { + PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); + + if (bms_is_subset(phinfo->ph_eval_at, innerrel->relids) && + !bms_is_subset(phinfo->ph_needed, joinrel->relids)) + return false; + } + + /* * Search for mergejoinable clauses that constrain the inner rel against * either the outer rel or a pseudoconstant. If an operator is * mergejoinable then it behaves like equality for some btree opclass, so |