aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/allpaths.c21
-rw-r--r--src/test/regress/expected/union.out21
-rw-r--r--src/test/regress/sql/union.sql11
3 files changed, 53 insertions, 0 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index b11b9399891..40129016260 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1307,6 +1307,8 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
{
List *subpaths = NIL;
bool subpaths_valid = true;
+ List *startup_subpaths = NIL;
+ bool startup_subpaths_valid = true;
List *partial_subpaths = NIL;
List *pa_partial_subpaths = NIL;
List *pa_nonpartial_subpaths = NIL;
@@ -1346,6 +1348,20 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
else
subpaths_valid = false;
+ /*
+ * 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.
+ */
+ if (rel->consider_startup && childrel->pathlist != NIL &&
+ childrel->cheapest_startup_path->param_info == NULL)
+ accumulate_append_subpath(childrel->cheapest_startup_path,
+ &startup_subpaths,
+ NULL);
+ else
+ startup_subpaths_valid = false;
+
+
/* Same idea, but for a partial plan. */
if (childrel->partial_pathlist != NIL)
{
@@ -1478,6 +1494,11 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
NIL, NULL, 0, false,
-1));
+ /* build an AppendPath for the cheap startup paths, if valid */
+ if (startup_subpaths_valid)
+ add_path(rel, (Path *) create_append_path(root, rel, startup_subpaths,
+ NIL, NIL, NULL, 0, false, -1));
+
/*
* Consider an append of unordered, unparameterized partial paths. Make
* it parallel-aware if possible.
diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out
index e2613d6777e..f046e522dea 100644
--- a/src/test/regress/expected/union.out
+++ b/src/test/regress/expected/union.out
@@ -1432,3 +1432,24 @@ where (x = 0) or (q1 >= q2 and q1 <= q2);
4567890123456789 | 4567890123456789 | 1
(6 rows)
+--
+-- Test the planner's ability to produce cheap startup plans with Append nodes
+--
+-- Ensure we get a Nested Loop join between tenk1 and tenk2
+explain (costs off)
+select t1.unique1 from tenk1 t1
+inner join tenk2 t2 on t1.tenthous = t2.tenthous
+ union all
+(values(1)) limit 1;
+ QUERY PLAN
+--------------------------------------------------------
+ Limit
+ -> Append
+ -> Nested Loop
+ Join Filter: (t1.tenthous = t2.tenthous)
+ -> Seq Scan on tenk1 t1
+ -> Materialize
+ -> Seq Scan on tenk2 t2
+ -> Result
+(8 rows)
+
diff --git a/src/test/regress/sql/union.sql b/src/test/regress/sql/union.sql
index ca8c9b4d128..d65ca9f86de 100644
--- a/src/test/regress/sql/union.sql
+++ b/src/test/regress/sql/union.sql
@@ -540,3 +540,14 @@ select * from
union all
select *, 1 as x from int8_tbl b) ss
where (x = 0) or (q1 >= q2 and q1 <= q2);
+
+--
+-- Test the planner's ability to produce cheap startup plans with Append nodes
+--
+
+-- Ensure we get a Nested Loop join between tenk1 and tenk2
+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