From 150bc7fb1e9eacaee5d46852fa464e83e7930aca Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 22 Nov 2016 20:15:37 -0800
Subject: [PATCH 2/3] Signal when a master backend is doing parallel work.

---
 src/backend/access/transam/parallel.c | 14 ++++++++------
 src/backend/executor/nodeGather.c     |  6 ++++++
 src/include/access/parallel.h         | 20 +++++++++++++++++++-
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 59dc394..c038ea1 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -88,12 +88,14 @@ typedef struct FixedParallelState
 } FixedParallelState;
 
 /*
- * Our parallel worker number.  We initialize this to -1, meaning that we are
- * not a parallel worker.  In parallel workers, it will be set to a value >= 0
- * and < the number of workers before any user code is invoked; each parallel
- * worker will get a different parallel worker number.
+ * Our parallel worker number.  We initialize this to PARALLEL_WORKER_MASTER,
+ * meaning that we are not a parallel worker.  In parallel workers, it will be
+ * set to a value >= 0 and < the number of workers before any user code is
+ * invoked; each parallel worker will get a different parallel worker number.
+ * If the master backend performs parallel work, this will temporarily be set
+ * to PARALLEL_WORKER_MASTER_PARALLEL while doing so.
  */
-int			ParallelWorkerNumber = -1;
+int			ParallelWorkerNumber = PARALLEL_WORKER_MASTER;
 
 /* Is there a parallel message pending which we need to receive? */
 volatile bool ParallelMessagePending = false;
@@ -955,7 +957,7 @@ ParallelWorkerMain(Datum main_arg)
 	BackgroundWorkerUnblockSignals();
 
 	/* Determine and set our parallel worker number. */
-	Assert(ParallelWorkerNumber == -1);
+	Assert(ParallelWorkerNumber == PARALLEL_WORKER_MASTER);
 	memcpy(&ParallelWorkerNumber, MyBgworkerEntry->bgw_extra, sizeof(int));
 
 	/* Set up a memory context and resource owner. */
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index 880ca62..c292610 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -305,7 +305,13 @@ gather_getnext(GatherState *gatherstate)
 
 		if (gatherstate->need_to_scan_locally)
 		{
+			/*
+			 * Signal that the master backend temparily is doing parallel
+			 * work.
+			 */
+			ParallelWorkerNumber = PARALLEL_WORKER_MASTER_PARALLEL;
 			outerTupleSlot = ExecProcNode(outerPlan);
+			ParallelWorkerNumber = PARALLEL_WORKER_MASTER;
 
 			if (!TupIsNull(outerTupleSlot))
 				return outerTupleSlot;
diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h
index 2f8f36f..ce8b6b6 100644
--- a/src/include/access/parallel.h
+++ b/src/include/access/parallel.h
@@ -50,7 +50,25 @@ extern volatile bool ParallelMessagePending;
 extern int	ParallelWorkerNumber;
 extern bool InitializingParallelWorker;
 
-#define		IsParallelWorker()		(ParallelWorkerNumber >= 0)
+/*
+ * Values for ParallelWorkerNumber, values >= 0 are workers backends.
+ */
+/* master backend */
+#define PARALLEL_WORKER_MASTER			-2
+/* master backend, performing parallel work */
+#define PARALLEL_WORKER_MASTER_PARALLEL	-1
+
+/* Is the process a parallel worker? */
+#define		IsParallelWorker() \
+	(ParallelWorkerNumber > PARALLEL_WORKER_MASTER_PARALLEL)
+
+/*
+ * Is the process performing parallelized work? This can be a the case in a
+ * worker (in which case IsParallelWorker() would be true), or it can be the
+ * master backend performing parallel work itself.
+ */
+#define		PerformingParallelWork() \
+	(ParallelWorkerNumber > PARALLEL_WORKER_MASTER)
 
 extern ParallelContext *CreateParallelContext(parallel_worker_main_type entrypoint, int nworkers);
 extern ParallelContext *CreateParallelContextForExternalFunction(char *library_name, char *function_name, int nworkers);
-- 
2.10.2

