mirror of
https://github.com/postgres/postgres.git
synced 2025-05-28 05:21:27 +03:00
Don't include outer join relids in lateral_relids bitmapsets.
This avoids an assertion failure when outer joins are rearranged per identity 3. Listing only the baserels from a PlaceHolderVar's ph_lateral set should be enough to ensure that the required values are available when we need to compute the PHV --- it's what we did before inventing nullingrel sets, after all. It's a bit unsatisfying; but with beta2 hard upon us, there's not time to look for an aesthetically cleaner fix. Richard Guo and Tom Lane Discussion: https://postgr.es/m/CAMbWs48Jcw-NvnxT23WiHP324wG44DvzcH1j4hc0Zn+3sR9cfg@mail.gmail.com
This commit is contained in:
parent
0655c03ef9
commit
efeb12ef0b
@ -580,6 +580,7 @@ create_lateral_join_info(PlannerInfo *root)
|
|||||||
{
|
{
|
||||||
PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
|
PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
|
||||||
Relids eval_at = phinfo->ph_eval_at;
|
Relids eval_at = phinfo->ph_eval_at;
|
||||||
|
Relids lateral_refs;
|
||||||
int varno;
|
int varno;
|
||||||
|
|
||||||
if (phinfo->ph_lateral == NULL)
|
if (phinfo->ph_lateral == NULL)
|
||||||
@ -587,6 +588,15 @@ create_lateral_join_info(PlannerInfo *root)
|
|||||||
|
|
||||||
found_laterals = true;
|
found_laterals = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include only baserels not outer joins in the evaluation sites'
|
||||||
|
* lateral relids. This avoids problems when outer join order gets
|
||||||
|
* rearranged, and it should still ensure that the lateral values are
|
||||||
|
* available when needed.
|
||||||
|
*/
|
||||||
|
lateral_refs = bms_intersect(phinfo->ph_lateral, root->all_baserels);
|
||||||
|
Assert(!bms_is_empty(lateral_refs));
|
||||||
|
|
||||||
if (bms_get_singleton_member(eval_at, &varno))
|
if (bms_get_singleton_member(eval_at, &varno))
|
||||||
{
|
{
|
||||||
/* Evaluation site is a baserel */
|
/* Evaluation site is a baserel */
|
||||||
@ -594,10 +604,10 @@ create_lateral_join_info(PlannerInfo *root)
|
|||||||
|
|
||||||
brel->direct_lateral_relids =
|
brel->direct_lateral_relids =
|
||||||
bms_add_members(brel->direct_lateral_relids,
|
bms_add_members(brel->direct_lateral_relids,
|
||||||
phinfo->ph_lateral);
|
lateral_refs);
|
||||||
brel->lateral_relids =
|
brel->lateral_relids =
|
||||||
bms_add_members(brel->lateral_relids,
|
bms_add_members(brel->lateral_relids,
|
||||||
phinfo->ph_lateral);
|
lateral_refs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -610,7 +620,7 @@ create_lateral_join_info(PlannerInfo *root)
|
|||||||
if (brel == NULL)
|
if (brel == NULL)
|
||||||
continue; /* ignore outer joins in eval_at */
|
continue; /* ignore outer joins in eval_at */
|
||||||
brel->lateral_relids = bms_add_members(brel->lateral_relids,
|
brel->lateral_relids = bms_add_members(brel->lateral_relids,
|
||||||
phinfo->ph_lateral);
|
lateral_refs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2624,6 +2624,23 @@ select * from int8_tbl t1
|
|||||||
-> Function Scan on generate_series
|
-> Function Scan on generate_series
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
|
explain (costs off)
|
||||||
|
select * from int8_tbl t1
|
||||||
|
left join int8_tbl t2 on true
|
||||||
|
left join lateral
|
||||||
|
(select t2.q1 from int8_tbl t3) s
|
||||||
|
on t2.q1 = 1;
|
||||||
|
QUERY PLAN
|
||||||
|
-------------------------------------------
|
||||||
|
Nested Loop Left Join
|
||||||
|
-> Seq Scan on int8_tbl t1
|
||||||
|
-> Materialize
|
||||||
|
-> Nested Loop Left Join
|
||||||
|
Join Filter: (t2.q1 = 1)
|
||||||
|
-> Seq Scan on int8_tbl t2
|
||||||
|
-> Seq Scan on int8_tbl t3
|
||||||
|
(7 rows)
|
||||||
|
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
select * from onek t1
|
select * from onek t1
|
||||||
left join onek t2 on true
|
left join onek t2 on true
|
||||||
|
@ -528,6 +528,13 @@ select * from int8_tbl t1
|
|||||||
(select * from generate_series(t2.q1, 100)) s
|
(select * from generate_series(t2.q1, 100)) s
|
||||||
on t2.q1 = 1;
|
on t2.q1 = 1;
|
||||||
|
|
||||||
|
explain (costs off)
|
||||||
|
select * from int8_tbl t1
|
||||||
|
left join int8_tbl t2 on true
|
||||||
|
left join lateral
|
||||||
|
(select t2.q1 from int8_tbl t3) s
|
||||||
|
on t2.q1 = 1;
|
||||||
|
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
select * from onek t1
|
select * from onek t1
|
||||||
left join onek t2 on true
|
left join onek t2 on true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user