Commit 639c1a6b authored by Robert Haas's avatar Robert Haas

Fix mistaken failure to allow parallelism in corner case.

If we try to run a parallel plan in serial mode because, for example,
it's going to be scanned via a cursor, but for some reason we're
already in parallel mode (for example because an outer query is
running in parallel), we'd incorrectly try to launch workers.
Fix by adding a flag to the EState, so that we can be certain that
ExecutePlan() and ExecGather()/ExecGatherMerge() will have the same
idea about whether we are executing serially or in parallel.

Report and fix by Amit Kapila with help from Kuntal Ghosh.  A few
tweaks by me.

Discussion: http://postgr.es/m/CAA4eK1+_BuZrmVCeua5Eqnm4Co9DAXdM5HPAOE2J19ePbR912Q@mail.gmail.com
parent 820c0305
...@@ -1702,6 +1702,7 @@ ExecutePlan(EState *estate, ...@@ -1702,6 +1702,7 @@ ExecutePlan(EState *estate,
if (!execute_once) if (!execute_once)
use_parallel_mode = false; use_parallel_mode = false;
estate->es_use_parallel_mode = use_parallel_mode;
if (use_parallel_mode) if (use_parallel_mode)
EnterParallelMode(); EnterParallelMode();
......
...@@ -156,6 +156,8 @@ CreateExecutorState(void) ...@@ -156,6 +156,8 @@ CreateExecutorState(void)
estate->es_epqScanDone = NULL; estate->es_epqScanDone = NULL;
estate->es_sourceText = NULL; estate->es_sourceText = NULL;
estate->es_use_parallel_mode = false;
/* /*
* Return the executor state structure * Return the executor state structure
*/ */
......
...@@ -150,7 +150,7 @@ ExecGather(PlanState *pstate) ...@@ -150,7 +150,7 @@ ExecGather(PlanState *pstate)
* Sometimes we might have to run without parallelism; but if parallel * Sometimes we might have to run without parallelism; but if parallel
* mode is active then we can try to fire up some workers. * mode is active then we can try to fire up some workers.
*/ */
if (gather->num_workers > 0 && IsInParallelMode()) if (gather->num_workers > 0 && estate->es_use_parallel_mode)
{ {
ParallelContext *pcxt; ParallelContext *pcxt;
......
...@@ -194,7 +194,7 @@ ExecGatherMerge(PlanState *pstate) ...@@ -194,7 +194,7 @@ ExecGatherMerge(PlanState *pstate)
* Sometimes we might have to run without parallelism; but if parallel * Sometimes we might have to run without parallelism; but if parallel
* mode is active then we can try to fire up some workers. * mode is active then we can try to fire up some workers.
*/ */
if (gm->num_workers > 0 && IsInParallelMode()) if (gm->num_workers > 0 && estate->es_use_parallel_mode)
{ {
ParallelContext *pcxt; ParallelContext *pcxt;
......
...@@ -507,6 +507,8 @@ typedef struct EState ...@@ -507,6 +507,8 @@ typedef struct EState
bool *es_epqTupleSet; /* true if EPQ tuple is provided */ bool *es_epqTupleSet; /* true if EPQ tuple is provided */
bool *es_epqScanDone; /* true if EPQ tuple has been fetched */ bool *es_epqScanDone; /* true if EPQ tuple has been fetched */
bool es_use_parallel_mode; /* can we use parallel workers? */
/* The per-query shared memory area to use for parallel execution. */ /* The per-query shared memory area to use for parallel execution. */
struct dsa_area *es_query_dsa; struct dsa_area *es_query_dsa;
} EState; } EState;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment