diff options
author | David Rowley <drowley@postgresql.org> | 2023-10-10 16:50:03 +1300 |
---|---|---|
committer | David Rowley <drowley@postgresql.org> | 2023-10-10 16:50:03 +1300 |
commit | fc4089f3c65a5f1b413a3299ba02b66a8e5e37d0 (patch) | |
tree | 17b74aeb967a5a0296a8cd642e3ce88c44b2a50b /src | |
parent | 4f3b56eea23554e1756a26080db273156f23f4f2 (diff) | |
download | postgresql-fc4089f3c65a5f1b413a3299ba02b66a8e5e37d0.tar.gz postgresql-fc4089f3c65a5f1b413a3299ba02b66a8e5e37d0.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/path/allpaths.c | 11 | ||||
-rw-r--r-- | src/test/regress/expected/union.out | 16 | ||||
-rw-r--r-- | src/test/regress/sql/union.sql | 9 |
3 files changed, 31 insertions, 5 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 7af001feaac..eea49cca7bb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -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; diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out index f046e522dea..64cebe48336 100644 --- a/src/test/regress/expected/union.out +++ b/src/test/regress/expected/union.out @@ -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) + diff --git a/src/test/regress/sql/union.sql b/src/test/regress/sql/union.sql index d65ca9f86de..599013e7c9d 100644 --- a/src/test/regress/sql/union.sql +++ b/src/test/regress/sql/union.sql @@ -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;
\ No newline at end of file +(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; |