diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 070ad31..2a68920 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -3448,6 +3448,43 @@ create_grouping_paths(PlannerInfo *root,
 				grouping_is_hashable(parse->groupClause));
 
 	/*
+	 * Build target list for partial aggregate paths.  These paths cannot
+	 * just emit the same tlist as regular aggregate paths, because (1) we
+	 * must include Vars and Aggrefs needed in HAVING, which might not
+	 * appear in the result tlist, and (2) the Aggrefs must be set in
+	 * partial mode.
+	 */
+	partial_grouping_target = make_partial_grouping_target(root, target);
+
+	/* Estimate number of partial groups. */
+	dNumPartialGroups = get_number_of_groups(root,
+												cheapest_path->rows,
+												NIL,
+												NIL);
+
+	/*
+	 * Collect statistics about aggregates for estimating costs of
+	 * performing aggregation in parallel.
+	 */
+	MemSet(&agg_partial_costs, 0, sizeof(AggClauseCosts));
+	MemSet(&agg_final_costs, 0, sizeof(AggClauseCosts));
+	if (parse->hasAggs)
+	{
+		/* partial phase */
+		get_agg_clause_costs(root, (Node *) partial_grouping_target->exprs,
+								AGGSPLIT_INITIAL_SERIAL,
+								&agg_partial_costs);
+
+		/* final phase */
+		get_agg_clause_costs(root, (Node *) target->exprs,
+								AGGSPLIT_FINAL_DESERIAL,
+								&agg_final_costs);
+		get_agg_clause_costs(root, parse->havingQual,
+								AGGSPLIT_FINAL_DESERIAL,
+								&agg_final_costs);
+	}
+
+	/*
 	 * Before generating paths for grouped_rel, we first generate any possible
 	 * partial paths; that way, later code can easily consider both parallel
 	 * and non-parallel approaches to grouping.  Note that the partial paths
@@ -3459,43 +3496,6 @@ create_grouping_paths(PlannerInfo *root,
 	{
 		Path	   *cheapest_partial_path = linitial(input_rel->partial_pathlist);
 
-		/*
-		 * Build target list for partial aggregate paths.  These paths cannot
-		 * just emit the same tlist as regular aggregate paths, because (1) we
-		 * must include Vars and Aggrefs needed in HAVING, which might not
-		 * appear in the result tlist, and (2) the Aggrefs must be set in
-		 * partial mode.
-		 */
-		partial_grouping_target = make_partial_grouping_target(root, target);
-
-		/* Estimate number of partial groups. */
-		dNumPartialGroups = get_number_of_groups(root,
-												 cheapest_partial_path->rows,
-												 NIL,
-												 NIL);
-
-		/*
-		 * Collect statistics about aggregates for estimating costs of
-		 * performing aggregation in parallel.
-		 */
-		MemSet(&agg_partial_costs, 0, sizeof(AggClauseCosts));
-		MemSet(&agg_final_costs, 0, sizeof(AggClauseCosts));
-		if (parse->hasAggs)
-		{
-			/* partial phase */
-			get_agg_clause_costs(root, (Node *) partial_grouping_target->exprs,
-								 AGGSPLIT_INITIAL_SERIAL,
-								 &agg_partial_costs);
-
-			/* final phase */
-			get_agg_clause_costs(root, (Node *) target->exprs,
-								 AGGSPLIT_FINAL_DESERIAL,
-								 &agg_final_costs);
-			get_agg_clause_costs(root, parse->havingQual,
-								 AGGSPLIT_FINAL_DESERIAL,
-								 &agg_final_costs);
-		}
-
 		if (can_sort)
 		{
 			/* Checked in set_grouped_rel_consider_parallel() */
@@ -3626,17 +3626,47 @@ create_grouping_paths(PlannerInfo *root,
 					 * We have aggregation, possibly with plain GROUP BY. Make
 					 * an AggPath.
 					 */
-					add_path(grouped_rel, (Path *)
-							 create_agg_path(root,
-											 grouped_rel,
-											 path,
-											 target,
-								 parse->groupClause ? AGG_SORTED : AGG_PLAIN,
-											 AGGSPLIT_SIMPLE,
-											 parse->groupClause,
-											 (List *) parse->havingQual,
-											 &agg_costs,
-											 dNumGroups));
+					if (!agg_costs.hasNonPartial)
+					{
+						Path	   *path2;
+
+						path2 = (Path *) create_agg_path(root,
+														grouped_rel,
+														path,
+														partial_grouping_target,
+									 parse->groupClause ? AGG_SORTED : AGG_PLAIN,
+														AGGSPLIT_INITIAL,
+														parse->groupClause,
+														NIL,
+														&agg_costs,
+														dNumGroups);
+
+						add_path(grouped_rel, (Path *)
+								 create_agg_path(root,
+												 grouped_rel,
+												 path2,
+												 target,
+									 parse->groupClause ? AGG_SORTED : AGG_PLAIN,
+												 AGGSPLIT_FINAL,
+												 parse->groupClause,
+												 (List *) parse->havingQual,
+												 &agg_final_costs,
+												 dNumGroups));
+					}
+					else
+					{
+						add_path(grouped_rel, (Path *)
+								 create_agg_path(root,
+												 grouped_rel,
+												 path,
+												 target,
+									 parse->groupClause ? AGG_SORTED : AGG_PLAIN,
+												 AGGSPLIT_SIMPLE,
+												 parse->groupClause,
+												 (List *) parse->havingQual,
+												 &agg_costs,
+												 dNumGroups));
+					}
 				}
 				else if (parse->groupClause)
 				{
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 6b850e4..293a20c 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -715,7 +715,11 @@ typedef enum AggSplit
 	/* Initial phase of partial aggregation, with serialization: */
 	AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE,
 	/* Final phase of partial aggregation, with deserialization: */
-	AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE
+	AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE,
+	/* Initial phase of partial aggregation: */
+	AGGSPLIT_INITIAL = AGGSPLITOP_SKIPFINAL,
+	/* Final phase of partial aggregation */
+	AGGSPLIT_FINAL = AGGSPLITOP_COMBINE
 } AggSplit;
 
 /* Test whether an AggSplit value selects each primitive option: */
