From 7939f913ee610ece749fa4c5acacb0301308f503 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi Date: Tue, 25 Oct 2016 19:04:04 +0900 Subject: [PATCH 7/7] Add instrumentation to async execution Make explain analyze give sane result when async execution has taken place. --- src/backend/executor/execAsync.c | 19 +++++++++++++++++++ src/backend/executor/instrument.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/execAsync.c b/src/backend/executor/execAsync.c index 40e3f67..588ba18 100644 --- a/src/backend/executor/execAsync.c +++ b/src/backend/executor/execAsync.c @@ -46,6 +46,9 @@ ExecAsyncRequest(EState *estate, PlanState *requestor, int request_index, PendingAsyncRequest *areq = NULL; int nasync = estate->es_num_pending_async; + if (requestee->instrument) + InstrStartNode(requestee->instrument); + /* * If the number of pending asynchronous nodes exceeds the number of * available slots in the es_pending_async array, expand the array. @@ -121,11 +124,17 @@ ExecAsyncRequest(EState *estate, PlanState *requestor, int request_index, if (areq->state == ASYNC_COMPLETE) { Assert(areq->result == NULL || IsA(areq->result, TupleTableSlot)); + ExecAsyncResponse(estate, areq); + if (areq->requestee->instrument) + InstrStopNode(requestee->instrument, + TupIsNull((TupleTableSlot*)areq->result) ? 0.0 : 1.0); return; } + if (areq->requestee->instrument) + InstrStopNode(requestee->instrument, 0); /* No result available now, make this node pending */ estate->es_num_pending_async++; } @@ -193,6 +202,9 @@ ExecAsyncEventLoop(EState *estate, PlanState *requestor, long timeout) { PendingAsyncRequest *areq = estate->es_pending_async[i]; + if (areq->requestee->instrument) + InstrStartNode(areq->requestee->instrument); + /* Skip it if not pending. */ if (areq->state == ASYNC_CALLBACK_PENDING) { @@ -211,7 +223,14 @@ ExecAsyncEventLoop(EState *estate, PlanState *requestor, long timeout) if (requestor == areq->requestor) requestor_done = true; ExecAsyncResponse(estate, areq); + + if (areq->requestee->instrument) + InstrStopNode(areq->requestee->instrument, + TupIsNull((TupleTableSlot*)areq->result) ? + 0.0 : 1.0); } + else if (areq->requestee->instrument) + InstrStopNode(areq->requestee->instrument, 0); } /* If any node completed, compact the array. */ diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c index 6ec96ec..959ee90 100644 --- a/src/backend/executor/instrument.c +++ b/src/backend/executor/instrument.c @@ -102,7 +102,7 @@ InstrStopNode(Instrumentation *instr, double nTuples) &pgBufferUsage, &instr->bufusage_start); /* Is this the first tuple of this cycle? */ - if (!instr->running) + if (!instr->running && nTuples > 0) { instr->running = true; instr->firsttuple = INSTR_TIME_GET_DOUBLE(instr->counter); -- 2.9.2