diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 255f56b827..544afa2781 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1296,19 +1296,17 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 {
 	List	   *subpaths = NIL;
 	bool		subpaths_valid = true;
-	List	   *partial_subpaths = NIL;
-	List	   *pa_partial_subpaths = NIL;
-	List	   *pa_nonpartial_subpaths = NIL;
-	bool		partial_subpaths_valid = true;
-	bool		pa_subpaths_valid;
+	List	   *parallel_partial_subpaths = NIL;
+	List	   *parallel_nonpartial_subpaths = NIL;
+	bool		parallel_subpaths_valid = true;
 	List	   *all_child_pathkeys = NIL;
 	List	   *all_child_outers = NIL;
 	ListCell   *l;
 	List	   *partitioned_rels = NIL;
 	double		partial_rows = -1;
+	bool		allow_parallel_append;
 
-	/* If appropriate, consider parallel append */
-	pa_subpaths_valid = enable_parallel_append && rel->consider_parallel;
+	allow_parallel_append = enable_parallel_append && rel->consider_parallel;
 
 	/*
 	 * AppendPath generated for partitioned tables must record the RT indexes
@@ -1366,7 +1364,6 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 	{
 		RelOptInfo *childrel = lfirst(l);
 		ListCell   *lcp;
-		Path	   *cheapest_partial_path = NULL;
 
 		/*
 		 * For UNION ALLs with non-empty partitioned_child_rels, accumulate
@@ -1391,31 +1388,31 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 		else
 			subpaths_valid = false;
 
-		/* Same idea, but for a partial plan. */
-		if (childrel->partial_pathlist != NIL)
-		{
-			cheapest_partial_path = linitial(childrel->partial_pathlist);
-			accumulate_append_subpath(cheapest_partial_path,
-									  &partial_subpaths, NULL);
-		}
-		else
-			partial_subpaths_valid = false;
-
 		/*
-		 * Same idea, but for a parallel append mixing partial and non-partial
-		 * paths.
+		 * We also build a set of paths for each child by trying to use the
+		 * cheapest partial path, or the cheapest parallel safe normal path
+		 * either when that is cheaper, or if parallel append is not allowed.
 		 */
-		if (pa_subpaths_valid)
+		if (parallel_subpaths_valid)
 		{
 			Path	   *nppath = NULL;
+			Path	   *cheapest_partial_path = NULL;
 
-			nppath =
-				get_cheapest_parallel_safe_total_inner(childrel->pathlist);
+			/*
+			 * Only attempt to use a parallel safe subplan when parallel
+			 * append is allowed.
+			 */
+			if (allow_parallel_append)
+				nppath =
+					get_cheapest_parallel_safe_total_inner(childrel->pathlist);
+
+			if (childrel->partial_pathlist != NIL)
+				cheapest_partial_path = linitial(childrel->partial_pathlist);
 
 			if (cheapest_partial_path == NULL && nppath == NULL)
 			{
 				/* Neither a partial nor a parallel-safe path?  Forget it. */
-				pa_subpaths_valid = false;
+				parallel_subpaths_valid = false;
 			}
 			else if (nppath == NULL ||
 					 (cheapest_partial_path != NULL &&
@@ -1424,8 +1421,8 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 				/* Partial path is cheaper or the only option. */
 				Assert(cheapest_partial_path != NULL);
 				accumulate_append_subpath(cheapest_partial_path,
-										  &pa_partial_subpaths,
-										  &pa_nonpartial_subpaths);
+										  &parallel_partial_subpaths,
+										  &parallel_nonpartial_subpaths);
 
 			}
 			else
@@ -1444,7 +1441,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 				 * figure that out.
 				 */
 				accumulate_append_subpath(nppath,
-										  &pa_nonpartial_subpaths,
+										  &parallel_nonpartial_subpaths,
 										  NULL);
 			}
 		}
@@ -1525,23 +1522,28 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 												  partitioned_rels, -1));
 
 	/*
-	 * Consider an append of unordered, unparameterized partial paths.  Make
-	 * it parallel-aware if possible.
+	 * Add a partial append path for the list of partial and parallel-safe
+	 * subpaths that we collected above.  We perform a parallel append on
+	 * these, when allowed.  We don't attempt to consider both a parallel and
+	 * non-parallel append as we assume a parallel append will always come out
+	 * the cheaper of the two partial path options.
 	 */
-	if (partial_subpaths_valid && partial_subpaths != NIL)
+	if (parallel_subpaths_valid)
 	{
 		AppendPath *appendpath;
 		ListCell   *lc;
 		int			parallel_workers = 0;
 
-		/* Find the highest number of workers requested for any subpath. */
-		foreach(lc, partial_subpaths)
+		/*
+		 * Find the highest number of workers requested for any partial
+		 * subpath.
+		 */
+		foreach(lc, parallel_partial_subpaths)
 		{
 			Path	   *path = lfirst(lc);
 
 			parallel_workers = Max(parallel_workers, path->parallel_workers);
 		}
-		Assert(parallel_workers > 0);
 
 		/*
 		 * If the use of parallel append is permitted, always request at least
@@ -1552,19 +1554,20 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 		 * partitions vs. an unpartitioned table with the same data, so the
 		 * use of some kind of log-scaling here seems to make some sense.
 		 */
-		if (enable_parallel_append)
+		if (allow_parallel_append)
 		{
 			parallel_workers = Max(parallel_workers,
 								   fls(list_length(live_childrels)));
 			parallel_workers = Min(parallel_workers,
 								   max_parallel_workers_per_gather);
+			Assert(parallel_workers > 0);
 		}
-		Assert(parallel_workers > 0);
 
-		/* Generate a partial append path. */
-		appendpath = create_append_path(root, rel, NIL, partial_subpaths,
+		appendpath = create_append_path(root, rel,
+										parallel_nonpartial_subpaths,
+										parallel_partial_subpaths,
 										NIL, NULL, parallel_workers,
-										enable_parallel_append,
+										allow_parallel_append,
 										partitioned_rels, -1);
 
 		/*
@@ -1573,48 +1576,6 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
 		 */
 		partial_rows = appendpath->path.rows;
 
-		/* Add the path. */
-		add_partial_path(rel, (Path *) appendpath);
-	}
-
-	/*
-	 * Consider a parallel-aware append using a mix of partial and non-partial
-	 * paths.  (This only makes sense if there's at least one child which has
-	 * a non-partial path that is substantially cheaper than any partial path;
-	 * otherwise, we should use the append path added in the previous step.)
-	 */
-	if (pa_subpaths_valid && pa_nonpartial_subpaths != NIL)
-	{
-		AppendPath *appendpath;
-		ListCell   *lc;
-		int			parallel_workers = 0;
-
-		/*
-		 * Find the highest number of workers requested for any partial
-		 * subpath.
-		 */
-		foreach(lc, pa_partial_subpaths)
-		{
-			Path	   *path = lfirst(lc);
-
-			parallel_workers = Max(parallel_workers, path->parallel_workers);
-		}
-
-		/*
-		 * Same formula here as above.  It's even more important in this
-		 * instance because the non-partial paths won't contribute anything to
-		 * the planned number of parallel workers.
-		 */
-		parallel_workers = Max(parallel_workers,
-							   fls(list_length(live_childrels)));
-		parallel_workers = Min(parallel_workers,
-							   max_parallel_workers_per_gather);
-		Assert(parallel_workers > 0);
-
-		appendpath = create_append_path(root, rel, pa_nonpartial_subpaths,
-										pa_partial_subpaths,
-										NIL, NULL, parallel_workers, true,
-										partitioned_rels, partial_rows);
 		add_partial_path(rel, (Path *) appendpath);
 	}
 
