Fix possible crash in add_paths_to_append_rel()

While working on a8a968a82, I failed to consider that
cheapest_startup_path can be NULL when there is no non-parameterized
path in the pathlist.  This is well documented in set_cheapest(), I just
failed to notice.

Here we adjust the code to just check if the RelOptInfo has a
cheapest_startup_path set before adding it to the startup_subpaths list.

Reported-by: Richard Guo
Author: Richard Guo
Discussion: https://postgr.es/m/CAMbWs49w3t03V69XhdCuw+GDwivny4uQUxrkVp6Gejaspt0wMQ@mail.gmail.com
This commit is contained in:
David Rowley 2023-10-10 16:50:03 +13:00
parent 4f3b56eea2
commit fc4089f3c6
3 changed files with 31 additions and 5 deletions

View File

@ -1350,14 +1350,17 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
/*
* When the planner is considering cheap startup plans, we'll also
* collect all the cheapest_startup_paths and build an AppendPath
* containing those as subpaths.
* collect all the cheapest_startup_paths (if set) and build an
* AppendPath containing those as subpaths.
*/
if (rel->consider_startup && childrel->pathlist != NIL &&
childrel->cheapest_startup_path->param_info == NULL)
if (rel->consider_startup && childrel->cheapest_startup_path != NULL)
{
/* cheapest_startup_path must not be a parameterized path. */
Assert(childrel->cheapest_startup_path->param_info == NULL);
accumulate_append_subpath(childrel->cheapest_startup_path,
&startup_subpaths,
NULL);
}
else
startup_subpaths_valid = false;

View File

@ -1453,3 +1453,19 @@ inner join tenk2 t2 on t1.tenthous = t2.tenthous
-> Result
(8 rows)
-- Ensure there is no problem if cheapest_startup_path is NULL
explain (costs off)
select * from tenk1 t1
left join lateral
(select t1.tenthous from tenk2 t2 union all (values(1)))
on true limit 1;
QUERY PLAN
-------------------------------------------------------------------
Limit
-> Nested Loop Left Join
-> Seq Scan on tenk1 t1
-> Append
-> Index Only Scan using tenk2_hundred on tenk2 t2
-> Result
(6 rows)

View File

@ -550,4 +550,11 @@ explain (costs off)
select t1.unique1 from tenk1 t1
inner join tenk2 t2 on t1.tenthous = t2.tenthous
union all
(values(1)) limit 1;
(values(1)) limit 1;
-- Ensure there is no problem if cheapest_startup_path is NULL
explain (costs off)
select * from tenk1 t1
left join lateral
(select t1.tenthous from tenk2 t2 union all (values(1)))
on true limit 1;