From d1c9c864fc042412e9b674d79a0e70972053ce15 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 8 Feb 2023 14:45:36 -0500 Subject: [PATCH] Further tighten nullingrel marking rules in build_joinrel_tlist(). The code I added in fee7b77b9 could misbehave if commute_above_r contains multiple relids. While adding too many relids here is probably harmless (pre-fee7b77b9, we did it all the time), it's not very expensive to be accurate: we just have to intersect commute_above_r with the join's relids. Discussion: https://postgr.es/m/17781-c0405c8b3cd5e072@postgresql.org --- src/backend/optimizer/util/relnode.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 29da78b62e..a70a16238a 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -1051,9 +1051,9 @@ min_join_parameterization(PlannerInfo *root, * A leftjoin (B leftjoin C on (Pbc)) on (Pab) * Here the now-upper A/B join must not mark C columns as nulled by itself. * - * Second, if sjinfo->commute_above_r is already part of the joinrel then - * it is added to the nulling bitmaps of nullable Vars. This takes care of - * the reverse case where we implement + * Second, any relid in sjinfo->commute_above_r that is already part of + * the joinrel is added to the nulling bitmaps of nullable Vars and PHVs. + * This takes care of the reverse case where we implement * A leftjoin (B leftjoin C on (Pbc)) on (Pab) * as * (A leftjoin B on (Pab)) leftjoin C on (Pbc) @@ -1100,9 +1100,10 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, bms_is_subset(phv->phrels, sjinfo->syn_lefthand)))) phv->phnullingrels = bms_add_member(phv->phnullingrels, sjinfo->ojrelid); - if (bms_overlap(sjinfo->commute_above_r, joinrel->relids)) - phv->phnullingrels = bms_add_members(phv->phnullingrels, - sjinfo->commute_above_r); + phv->phnullingrels = + bms_join(phv->phnullingrels, + bms_intersect(sjinfo->commute_above_r, + relids)); } joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, @@ -1164,9 +1165,10 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, bms_is_member(var->varno, sjinfo->syn_lefthand)))) var->varnullingrels = bms_add_member(var->varnullingrels, sjinfo->ojrelid); - if (bms_overlap(sjinfo->commute_above_r, joinrel->relids)) - var->varnullingrels = bms_add_members(var->varnullingrels, - sjinfo->commute_above_r); + var->varnullingrels = + bms_join(var->varnullingrels, + bms_intersect(sjinfo->commute_above_r, + relids)); } joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,