summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2023-02-08 19:45:36 +0000
committerTom Lane2023-02-08 19:45:36 +0000
commitd1c9c864fc042412e9b674d79a0e70972053ce15 (patch)
tree0fa342f9b8e01d48c38156771e590313e80738b2
parent798c0176342150c8fe1404b0007b299db2e73ce0 (diff)
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/[email protected]
-rw-r--r--src/backend/optimizer/util/relnode.c20
1 files 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,