From b8f851e8385d98a581fb49ed458d3b68d451158d Mon Sep 17 00:00:00 2001
From: Andy Fan <zhihui.fan1213@gmail.com>
Date: Mon, 10 Apr 2023 15:59:27 +0800
Subject: [PATCH v1] Considering root->tuple_fraction during create_append_path

---
 src/backend/optimizer/path/allpaths.c | 10 ++++++++-
 src/test/regress/expected/join.out    | 29 +++++++++++++++++++++++++++
 src/test/regress/sql/join.sql         |  9 +++++++++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 244957a2483..aa891157f10 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1330,7 +1330,12 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 		RelOptInfo *childrel = lfirst(l);
 		ListCell   *lcp;
 		Path	   *cheapest_partial_path = NULL;
+		Path	   *cheapest_startup_path = NULL;
 
+		if (childrel->pathlist != NIL && childrel->consider_startup)
+		{
+			cheapest_startup_path = get_cheapest_fractional_path(childrel, root->tuple_fraction);
+		}
 		/*
 		 * If child has an unparameterized cheapest-total path, add that to
 		 * the unparameterized Append path we are constructing for the parent.
@@ -1339,7 +1344,10 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 		 * With partitionwise aggregates, the child rel's pathlist may be
 		 * empty, so don't assume that a path exists here.
 		 */
-		if (childrel->pathlist != NIL &&
+		if (cheapest_startup_path && cheapest_startup_path->param_info == NULL)
+			accumulate_append_subpath(cheapest_startup_path,
+									  &subpaths, NULL);
+			else if (childrel->pathlist != NIL &&
 			childrel->cheapest_total_path->param_info == NULL)
 			accumulate_append_subpath(childrel->cheapest_total_path,
 									  &subpaths, NULL);
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 5d59ed7890f..717ec9551dc 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -7368,3 +7368,32 @@ where exists (select 1 from j3
 (13 rows)
 
 drop table j3;
+explain (costs off)
+(select * from tenk1 order by hundred)  union all (select * from tenk2 order by hundred)
+limit 3;
+                     QUERY PLAN                      
+-----------------------------------------------------
+ Limit
+   ->  Append
+         ->  Index Scan using tenk1_hundred on tenk1
+         ->  Index Scan using tenk2_hundred on tenk2
+(4 rows)
+
+explain (costs off)
+SELECT * FROM tenk1 t1 join tenk2 t2 using (unique2)
+union all
+SELECT * FROM tenk1 t1 join tenk2 t2 using (unique2) limit 3;
+                           QUERY PLAN                           
+----------------------------------------------------------------
+ Limit
+   ->  Append
+         ->  Merge Join
+               Merge Cond: (t1.unique2 = t2.unique2)
+               ->  Index Scan using tenk1_unique2 on tenk1 t1
+               ->  Index Scan using tenk2_unique2 on tenk2 t2
+         ->  Merge Join
+               Merge Cond: (t1_1.unique2 = t2_1.unique2)
+               ->  Index Scan using tenk1_unique2 on tenk1 t1_1
+               ->  Index Scan using tenk2_unique2 on tenk2 t2_1
+(10 rows)
+
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index a630f58b571..42cbd922d0d 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -2666,3 +2666,12 @@ where exists (select 1 from j3
       and t1.unique1 < 1;
 
 drop table j3;
+
+explain (costs off)
+(select * from tenk1 order by hundred)  union all (select * from tenk2 order by hundred)
+limit 3;
+
+explain (costs off)
+SELECT * FROM tenk1 t1 join tenk2 t2 using (unique2)
+union all
+SELECT * FROM tenk1 t1 join tenk2 t2 using (unique2) limit 3;
-- 
2.21.0

