aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2023-10-10 16:50:03 +1300
committerDavid Rowley <drowley@postgresql.org>2023-10-10 16:50:03 +1300
commitfc4089f3c65a5f1b413a3299ba02b66a8e5e37d0 (patch)
tree17b74aeb967a5a0296a8cd642e3ce88c44b2a50b /src
parent4f3b56eea23554e1756a26080db273156f23f4f2 (diff)
downloadpostgresql-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.c11
-rw-r--r--src/test/regress/expected/union.out16
-rw-r--r--src/test/regress/sql/union.sql9
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;