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
This commit is contained in:
parent
798c017634
commit
d1c9c864fc
|
@ -1051,9 +1051,9 @@ min_join_parameterization(PlannerInfo *root,
|
||||||
* A leftjoin (B leftjoin C on (Pbc)) on (Pab)
|
* 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.
|
* 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
|
* Second, any relid in sjinfo->commute_above_r that is already part of
|
||||||
* it is added to the nulling bitmaps of nullable Vars. This takes care of
|
* the joinrel is added to the nulling bitmaps of nullable Vars and PHVs.
|
||||||
* the reverse case where we implement
|
* This takes care of the reverse case where we implement
|
||||||
* A leftjoin (B leftjoin C on (Pbc)) on (Pab)
|
* A leftjoin (B leftjoin C on (Pbc)) on (Pab)
|
||||||
* as
|
* as
|
||||||
* (A leftjoin B on (Pab)) leftjoin C on (Pbc)
|
* (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))))
|
bms_is_subset(phv->phrels, sjinfo->syn_lefthand))))
|
||||||
phv->phnullingrels = bms_add_member(phv->phnullingrels,
|
phv->phnullingrels = bms_add_member(phv->phnullingrels,
|
||||||
sjinfo->ojrelid);
|
sjinfo->ojrelid);
|
||||||
if (bms_overlap(sjinfo->commute_above_r, joinrel->relids))
|
phv->phnullingrels =
|
||||||
phv->phnullingrels = bms_add_members(phv->phnullingrels,
|
bms_join(phv->phnullingrels,
|
||||||
sjinfo->commute_above_r);
|
bms_intersect(sjinfo->commute_above_r,
|
||||||
|
relids));
|
||||||
}
|
}
|
||||||
|
|
||||||
joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,
|
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))))
|
bms_is_member(var->varno, sjinfo->syn_lefthand))))
|
||||||
var->varnullingrels = bms_add_member(var->varnullingrels,
|
var->varnullingrels = bms_add_member(var->varnullingrels,
|
||||||
sjinfo->ojrelid);
|
sjinfo->ojrelid);
|
||||||
if (bms_overlap(sjinfo->commute_above_r, joinrel->relids))
|
var->varnullingrels =
|
||||||
var->varnullingrels = bms_add_members(var->varnullingrels,
|
bms_join(var->varnullingrels,
|
||||||
sjinfo->commute_above_r);
|
bms_intersect(sjinfo->commute_above_r,
|
||||||
|
relids));
|
||||||
}
|
}
|
||||||
|
|
||||||
joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,
|
joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,
|
||||||
|
|
Loading…
Reference in New Issue