diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index 53c5254..8c53774 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -799,6 +799,19 @@ ExecParallelReinitialize(PlanState *planstate, /* Old workers must already be shut down */ Assert(pei->finished); + /* Clear the instrumentation space from the last round. */ + if (pei->instrumentation) + { + Instrumentation *instrument; + SharedExecutorInstrumentation *sh_instr; + int i; + + sh_instr = pei->instrumentation; + instrument = GetInstrumentationArray(sh_instr); + for (i = 0; i < sh_instr->num_workers * sh_instr->num_plan_nodes; ++i) + InstrInit(&instrument[i], pei->planstate->state->es_instrument); + } + /* Force parameters we're going to pass to workers to be evaluated. */ ExecEvalParamExecParams(sendParams, estate); @@ -919,14 +932,25 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate, * regular instrumentation information, which is the per-query context. * Switch into per-query memory context. */ - oldcontext = MemoryContextSwitchTo(planstate->state->es_query_cxt); - ibytes = mul_size(instrumentation->num_workers, sizeof(Instrumentation)); - planstate->worker_instrument = - palloc(ibytes + offsetof(WorkerInstrumentation, instrument)); - MemoryContextSwitchTo(oldcontext); + if (!planstate->worker_instrument) + { + oldcontext = MemoryContextSwitchTo(planstate->state->es_query_cxt); + ibytes = mul_size(instrumentation->num_workers, sizeof(Instrumentation)); + planstate->worker_instrument = + palloc(ibytes + offsetof(WorkerInstrumentation, instrument)); + MemoryContextSwitchTo(oldcontext); + + for (n = 0; n < instrumentation->num_workers; ++n) + InstrInit(&planstate->worker_instrument->instrument[n], + planstate->state->es_instrument); + } planstate->worker_instrument->num_workers = instrumentation->num_workers; - memcpy(&planstate->worker_instrument->instrument, instrument, ibytes); + + /* Accumulate the per-worker detail. */ + for (n = 0; n < instrumentation->num_workers; ++n) + InstrAggNode(&planstate->worker_instrument->instrument[n], + &instrument[n]); /* * Perform any node-type-specific work that needs to be done. Currently, diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index d1d5b22..3bb4381 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -378,7 +378,27 @@ select count(*) from bmscantest where a>1; 99999 (1 row) +-- test accumulation of stats for parallel node reset enable_seqscan; +alter table tenk2 set (parallel_workers = 0); +explain (analyze, timing off, summary off, costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Nested Loop (actual rows=98000 loops=1) + -> Seq Scan on tenk2 (actual rows=10 loops=1) + Filter: (thousand = 0) + Rows Removed by Filter: 9990 + -> Gather (actual rows=9800 loops=10) + Workers Planned: 4 + Workers Launched: 4 + -> Parallel Seq Scan on tenk1 (actual rows=1960 loops=50) + Filter: (hundred > 1) + Rows Removed by Filter: 40 +(11 rows) + +alter table tenk2 reset (parallel_workers); reset enable_indexscan; reset enable_hashjoin; reset enable_mergejoin; diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index bb4e34a..0f006f9 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -149,7 +149,13 @@ insert into bmscantest select r, 'fooooooooooooooooooooooooooooooooooooooooooooo create index i_bmtest ON bmscantest(a); select count(*) from bmscantest where a>1; +-- test accumulation of stats for parallel node reset enable_seqscan; +alter table tenk2 set (parallel_workers = 0); +explain (analyze, timing off, summary off, costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; +alter table tenk2 reset (parallel_workers); + reset enable_indexscan; reset enable_hashjoin; reset enable_mergejoin;