Fix possible crash in add_paths_to_append_rel()
authorDavid Rowley <drowley@postgresql.org>
Tue, 10 Oct 2023 03:50:03 +0000 (16:50 +1300)
committerDavid Rowley <drowley@postgresql.org>
Tue, 10 Oct 2023 03:50:03 +0000 (16:50 +1300)
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

src/backend/optimizer/path/allpaths.c
src/test/regress/expected/union.out
src/test/regress/sql/union.sql

index 7af001feaacdca95af331384dd711ecc330ac875..eea49cca7bbb50975f4516abf5121a2beab4541e 100644 (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;
 
index f046e522dea5c8026dd0539b49a0d3e66b59828e..64cebe483367c79b59ee8505e12eb57f2afa2cd4 100644 (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)
+
index d65ca9f86debff8d3899e37dd3e6dc0733b27ed4..599013e7c9d290620626f7656e300e213eb14b6e 100644 (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;
\ 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;