I was curious when create_gather_path() sets single_copy, but could not find
any place in the tree where a path with num_workers==0 is added to
partial_pathlist. This patch removes the field.

-- 
Antonin Houska
Web: https://www.cybertec-postgresql.com

>From 3f434cfb8b7eb70049650d1f324fe8cbaf1267cb Mon Sep 17 00:00:00 2001
From: Antonin Houska <a...@cybertec.at>
Date: Thu, 12 Dec 2024 10:22:40 +0100
Subject: [PATCH] Remove the single_copy field from GatherPath.

While single_copy is useful in the Gather plan, it's set regardless the value
in GatherPath: standard_planner() sets the flag on a new instance of Gather,
for which there is no corresponding GatherPath. Furthermore, the field is
never set in GatherPath anyway because parial paths always have
parallel_workers > 0.
---
 src/backend/optimizer/plan/createplan.c | 6 ++----
 src/backend/optimizer/util/pathnode.c   | 9 +--------
 src/include/nodes/pathnodes.h           | 4 +---
 3 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 178c572b02..dfceb3e615 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -300,7 +300,7 @@ static Unique *make_unique_from_sortclauses(Plan *lefttree, List *distinctList);
 static Unique *make_unique_from_pathkeys(Plan *lefttree,
 										 List *pathkeys, int numCols);
 static Gather *make_gather(List *qptlist, List *qpqual,
-						   int nworkers, int rescan_param, bool single_copy, Plan *subplan);
+						   int nworkers, int rescan_param, Plan *subplan);
 static SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
 						 List *distinctList, AttrNumber flagColIdx, int firstFlag,
 						 long numGroups);
@@ -1940,7 +1940,6 @@ create_gather_plan(PlannerInfo *root, GatherPath *best_path)
 							  NIL,
 							  best_path->num_workers,
 							  assign_special_exec_param(root),
-							  best_path->single_copy,
 							  subplan);
 
 	copy_generic_path_info(&gather_plan->plan, &best_path->path);
@@ -6930,7 +6929,6 @@ make_gather(List *qptlist,
 			List *qpqual,
 			int nworkers,
 			int rescan_param,
-			bool single_copy,
 			Plan *subplan)
 {
 	Gather	   *node = makeNode(Gather);
@@ -6942,7 +6940,7 @@ make_gather(List *qptlist,
 	plan->righttree = NULL;
 	node->num_workers = nworkers;
 	node->rescan_param = rescan_param;
-	node->single_copy = single_copy;
+	node->single_copy = false;
 	node->invisible = false;
 	node->initParam = NULL;
 
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index fc97bf6ee2..f03240c77a 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -2059,15 +2059,8 @@ create_gather_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
 	pathnode->path.pathkeys = NIL;	/* Gather has unordered result */
 
 	pathnode->subpath = subpath;
+	Assert(subpath->parallel_workers > 0);
 	pathnode->num_workers = subpath->parallel_workers;
-	pathnode->single_copy = false;
-
-	if (pathnode->num_workers == 0)
-	{
-		pathnode->path.pathkeys = subpath->pathkeys;
-		pathnode->num_workers = 1;
-		pathnode->single_copy = true;
-	}
 
 	cost_gather(pathnode, root, rel, pathnode->path.param_info, rows);
 
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 0759e00e96..0c7df1e6fa 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -2045,14 +2045,12 @@ typedef struct UniquePath
 
 /*
  * GatherPath runs several copies of a plan in parallel and collects the
- * results.  The parallel leader may also execute the plan, unless the
- * single_copy flag is set.
+ * results.
  */
 typedef struct GatherPath
 {
 	Path		path;
 	Path	   *subpath;		/* path for each worker */
-	bool		single_copy;	/* don't execute path more than once */
 	int			num_workers;	/* number of workers sought to help */
 } GatherPath;
 
-- 
2.45.2

Reply via email to