aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2023-12-25 01:24:25 +0200
committerAlexander Korotkov <akorotkov@postgresql.org>2023-12-25 01:33:26 +0200
commitb5fb6736ed3b6875e2a4ca39d33325147f535137 (patch)
tree3d5e2ebf0170d00316542ad5da52bc08cad19643 /src/backend/optimizer
parent8a8ed916f73f4f16e8eb3e0e30ac1201a7642fda (diff)
downloadpostgresql-b5fb6736ed3b6875e2a4ca39d33325147f535137.tar.gz
postgresql-b5fb6736ed3b6875e2a4ca39d33325147f535137.zip
Don't constrain self-join removal due to PHVs
Self-join removal appears to be safe to apply with placeholder variables as long as we handle PlaceHolderVar in replace_varno_walker() and replace relid in phinfo->ph_lateral. Discussion: https://postgr.es/m/18187-831da249cbd2ff8e%40postgresql.org Author: Richard Guo Reviewed-by: Andrei Lepikhov
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/analyzejoins.c18
1 files changed, 4 insertions, 14 deletions
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 00404a8beb0..c328cbdb8d3 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -453,7 +453,7 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
{
PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
- Assert(!bms_is_member(relid, phinfo->ph_lateral));
+ Assert(sjinfo == NULL || !bms_is_member(relid, phinfo->ph_lateral));
if (bms_is_subset(phinfo->ph_needed, joinrelids) &&
bms_is_member(relid, phinfo->ph_eval_at) &&
!bms_is_member(ojrelid, phinfo->ph_eval_at))
@@ -472,6 +472,8 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
phinfo->ph_needed = replace_relid(phinfo->ph_needed, relid, subst);
phinfo->ph_needed = replace_relid(phinfo->ph_needed, ojrelid, subst);
/* ph_needed might or might not become empty */
+ phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
+ /* ph_lateral might or might not be empty */
phv->phrels = replace_relid(phv->phrels, relid, subst);
phv->phrels = replace_relid(phv->phrels, ojrelid, subst);
Assert(!bms_is_empty(phv->phrels));
@@ -2115,20 +2117,8 @@ remove_self_joins_one_group(PlannerInfo *root, Relids relids)
joinrelids = bms_add_member(joinrelids, k);
/*
- * Be safe to do not remove tables participated in complicated PH
+ * PHVs should not impose any constraints on removing self joins.
*/
- foreach(lc, root->placeholder_list)
- {
- PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
-
- /* there isn't any other place to eval PHV */
- if (bms_is_subset(phinfo->ph_eval_at, joinrelids) ||
- bms_is_subset(phinfo->ph_needed, joinrelids) ||
- bms_is_member(r, phinfo->ph_lateral))
- break;
- }
- if (lc)
- continue;
/*
* At this stage, joininfo lists of inner and outer can contain