From 4b707221bee693476452d3a0960ad963f35cee1b Mon Sep 17 00:00:00 2001
From: Rushabh Lathia <rushabh.lathia@enterprisedb.com>
Date: Tue, 12 Dec 2017 14:43:12 +0530
Subject: [PATCH 3/3] Adjust planner code to consider
 parallel_leader_participation.

---
 src/backend/access/nbtree/nbtsort.c  | 9 +++++----
 src/backend/optimizer/plan/planner.c | 7 +++++--
 src/include/optimizer/planner.h      | 3 ++-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 52265ac..7868481 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -273,7 +273,6 @@ static void _bt_end_parallel(BTLeader *btleader);
 static void _bt_leader_sort_as_worker(BTBuildState *buildstate);
 static double _bt_leader_wait_for_workers(BTBuildState *buildstate);
 
-/* static void _bt_worker_main(dsm_segment *seg, shm_toc *toc); */
 static Size _bt_parallel_estimate_shared(Snapshot snapshot);
 static void _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2,
 						   BTShared * btshared, Sharedsort *sharedsort,
@@ -371,6 +370,7 @@ _bt_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
 	BTSpool    *btspool = (BTSpool *) palloc0(sizeof(BTSpool));
 	SortCoordinate coordinate = NULL;
 	double		reltuples = 0;
+	bool        leaderasworker = parallel_leader_participation;
 
 	/*
 	 * We size the sort area as maintenance_work_mem rather than work_mem to
@@ -397,14 +397,14 @@ _bt_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
 		int			request;
 
 		/* Determine optimal number of worker processes, and attempt launch */
-		request = plan_create_index_workers(table, index);
+		request = plan_create_index_workers(table, index, leaderasworker);
 
 		if (request > 0)
 		{
 			buildstate->btleader = _bt_begin_parallel(btspool,
 													  indexInfo->ii_Concurrent,
 													  request,
-													  parallel_leader_participation);
+													  leaderasworker);
 		}
 	}
 
@@ -500,7 +500,8 @@ _bt_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
 	else
 	{
 		/* Parallel scans are underway by now.  Join as worker. */
-		_bt_leader_sort_as_worker(buildstate);
+		if (leaderasworker)
+			_bt_leader_sort_as_worker(buildstate);
 
 		/* Wait on worker processes to finish (should be almost instant) */
 		reltuples = _bt_leader_wait_for_workers(buildstate);
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 8ff32bd..dfeb2ef 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -6210,6 +6210,8 @@ get_partitioned_child_rels_for_join(PlannerInfo *root, Relids join_relids)
  *
  * tableOid is the table that index is to be built on.  indexOid is the OID
  * of a index to be created or reindexed (which must be a btree index).
+ * leaderasworker indicates whether leader going to participate as worker or
+ * not.
  *
  * Return value is the number of parallel workers to use, which can often be
  * treated as a suggestion.  However, a return value of 0 may be due to it
@@ -6220,7 +6222,7 @@ get_partitioned_child_rels_for_join(PlannerInfo *root, Relids join_relids)
  * index.
  */
 int
-plan_create_index_workers(Oid tableOid, Oid indexOid)
+plan_create_index_workers(Oid tableOid, Oid indexOid, const bool leaderasworker)
 {
 	PlannerInfo *root;
 	Query	   *query;
@@ -6236,6 +6238,7 @@ plan_create_index_workers(Oid tableOid, Oid indexOid)
 	BlockNumber heap_blocks;
 	double		reltuples;
 	double		allvisfrac;
+	int			leader_as_worker = leaderasworker ? 1 : 0;
 
 	/*
 	 * Fast-path:  Return immediately when parallelism disabled.  Note that we
@@ -6326,7 +6329,7 @@ plan_create_index_workers(Oid tableOid, Oid indexOid)
 	sort_mem_blocks = (maintenance_work_mem * 1024L) / BLCKSZ;
 	min_sort_mem_blocks = (32768L * 1024L) / BLCKSZ;
 	while (parallel_workers > min_parallel_workers &&
-		   sort_mem_blocks / (parallel_workers + 1) < min_sort_mem_blocks)
+		   sort_mem_blocks / (parallel_workers + leader_as_worker) < min_sort_mem_blocks)
 		parallel_workers--;
 
 done:
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 1603b67..884d502 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -61,6 +61,7 @@ extern List *get_partitioned_child_rels(PlannerInfo *root, Index rti);
 extern List *get_partitioned_child_rels_for_join(PlannerInfo *root,
 									Relids join_relids);
 
-extern int	plan_create_index_workers(Oid tableOid, Oid indexOid);
+extern int plan_create_index_workers(Oid tableOid, Oid indexOid,
+						  const bool leaderasworker);
 
 #endif							/* PLANNER_H */
-- 
1.8.3.1

