diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 9628479..93d9ed2 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -3752,8 +3752,7 @@ create_grouping_paths(PlannerInfo *root,
 															   gmpath,
 															   NULL,
 															   root->group_pathkeys,
-															   NULL,
-															   &total_groups);
+															   NULL);
 
 					if (parse->hasAggs)
 						add_path(grouped_rel, (Path *)
@@ -4224,7 +4223,6 @@ create_distinct_paths(PlannerInfo *root,
 		foreach(lc, input_rel->partial_pathlist)
 		{
 			Path	   *path = (Path *) lfirst(lc);
-			double		total_groups = path->rows * path->parallel_workers;
 
 			if (!pathkeys_contained_in(needed_pathkeys, path->pathkeys))
 			{
@@ -4240,8 +4238,7 @@ create_distinct_paths(PlannerInfo *root,
 													 path,
 													 NULL,
 													 needed_pathkeys,
-													 NULL,
-													 &total_groups);
+													 NULL);
 			add_path(distinct_rel, (Path *)
 					 create_upper_unique_path(root,
 											  distinct_rel,
@@ -4398,7 +4395,6 @@ create_ordered_paths(PlannerInfo *root,
 	{
 		Path	   *path = (Path *) lfirst(lc);
 		bool		is_sorted;
-		double		total_rows = path->rows * path->parallel_workers;
 
 		is_sorted = pathkeys_contained_in(root->sort_pathkeys,
 										  path->pathkeys);
@@ -4418,8 +4414,7 @@ create_ordered_paths(PlannerInfo *root,
 												 path,
 												 target,
 												 root->sort_pathkeys,
-												 NULL,
-												 &total_rows);
+												 NULL);
 
 		/* Add projection step if needed */
 		if (path->pathtarget != target)
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 07e1532..eb40e24 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -1638,11 +1638,14 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
 GatherMergePath *
 create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
 						 PathTarget *target, List *pathkeys,
-						 Relids required_outer, double *rows)
+						 Relids required_outer)
 {
 	GatherMergePath *pathnode = makeNode(GatherMergePath);
 	Cost			 input_startup_cost = 0;
 	Cost			 input_total_cost = 0;
+	double			 total_rows;
+	double			 parallel_divisor = subpath->parallel_workers;
+	double			 leader_contribution;
 
 	Assert(subpath->parallel_safe);
 	Assert(pathkeys);
@@ -1657,7 +1660,16 @@ create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
 	pathnode->num_workers = subpath->parallel_workers;
 	pathnode->path.pathkeys = pathkeys;
 	pathnode->path.pathtarget = target ? target : rel->reltarget;
-	pathnode->path.rows += subpath->rows;
+
+	/*
+	 * Calculate the total_rows for gather merge, by considering the leader
+	 * contribution to the execution. This is similar to how cost_seqscan
+	 * estimate the rows for the partial path.
+	 */
+	leader_contribution = 1.0 - (0.3 * subpath->parallel_workers);
+	if (leader_contribution > 0)
+		parallel_divisor += leader_contribution;
+	total_rows = clamp_row_est(subpath->rows * parallel_divisor);
 
 	if (pathkeys_contained_in(pathkeys, subpath->pathkeys))
 	{
@@ -1684,7 +1696,7 @@ create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
 	}
 
 	cost_gather_merge(pathnode, root, rel, pathnode->path.param_info,
-					  input_startup_cost, input_total_cost, rows);
+					  input_startup_cost, input_total_cost, &total_rows);
 
 	return pathnode;
 }
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 1df5861..3dbe9fc 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -271,7 +271,6 @@ extern GatherMergePath *create_gather_merge_path(PlannerInfo *root,
 												 RelOptInfo *rel, Path *subpath,
 												 PathTarget *target,
 												 List *pathkeys,
-												 Relids required_outer,
-												 double *rows);
+												 Relids required_outer);
 
 #endif   /* PATHNODE_H */
