diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 38 | ||||
-rw-r--r-- | src/backend/executor/execParallel.c | 2 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 2 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 2 |
4 files changed, 29 insertions, 15 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 023ea0081a0..c28cf9c8eab 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -85,7 +85,8 @@ static void ExecutePlan(EState *estate, PlanState *planstate, bool sendTuples, uint64 numberTuples, ScanDirection direction, - DestReceiver *dest); + DestReceiver *dest, + bool execute_once); static bool ExecCheckRTEPerms(RangeTblEntry *rte); static bool ExecCheckRTEPermsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols, @@ -288,17 +289,18 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) */ void ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, uint64 count) + ScanDirection direction, uint64 count, + bool execute_once) { if (ExecutorRun_hook) - (*ExecutorRun_hook) (queryDesc, direction, count); + (*ExecutorRun_hook) (queryDesc, direction, count, execute_once); else - standard_ExecutorRun(queryDesc, direction, count); + standard_ExecutorRun(queryDesc, direction, count, execute_once); } void standard_ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, uint64 count) + ScanDirection direction, uint64 count, bool execute_once) { EState *estate; CmdType operation; @@ -345,6 +347,11 @@ standard_ExecutorRun(QueryDesc *queryDesc, * run plan */ if (!ScanDirectionIsNoMovement(direction)) + { + if (execute_once && queryDesc->already_executed) + elog(ERROR, "can't re-execute query flagged for single execution"); + queryDesc->already_executed = true; + ExecutePlan(estate, queryDesc->planstate, queryDesc->plannedstmt->parallelModeNeeded, @@ -352,7 +359,9 @@ standard_ExecutorRun(QueryDesc *queryDesc, sendTuples, count, direction, - dest); + dest, + execute_once); + } /* * shutdown tuple receiver, if we started it @@ -1595,7 +1604,8 @@ ExecutePlan(EState *estate, bool sendTuples, uint64 numberTuples, ScanDirection direction, - DestReceiver *dest) + DestReceiver *dest, + bool execute_once) { TupleTableSlot *slot; uint64 current_tuple_count; @@ -1611,12 +1621,12 @@ ExecutePlan(EState *estate, estate->es_direction = direction; /* - * If a tuple count was supplied, we must force the plan to run without - * parallelism, because we might exit early. Also disable parallelism - * when writing into a relation, because no database changes are allowed - * in parallel mode. + * If the plan might potentially be executed multiple times, we must force + * it to run without parallelism, because we might exit early. Also + * disable parallelism when writing into a relation, because no database + * changes are allowed in parallel mode. */ - if (numberTuples || dest->mydest == DestIntoRel) + if (!execute_once || dest->mydest == DestIntoRel) use_parallel_mode = false; if (use_parallel_mode) @@ -1687,7 +1697,11 @@ ExecutePlan(EState *estate, */ current_tuple_count++; if (numberTuples && numberTuples == current_tuple_count) + { + /* Allow nodes to release or shut down resources. */ + (void) ExecShutdownNode(planstate); break; + } } if (use_parallel_mode) diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index 86db73be431..b91b663c46f 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -853,7 +853,7 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) ExecParallelInitializeWorker(queryDesc->planstate, toc); /* Run the plan */ - ExecutorRun(queryDesc, ForwardScanDirection, 0L); + ExecutorRun(queryDesc, ForwardScanDirection, 0L, true); /* Shut down the executor */ ExecutorFinish(queryDesc); diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 2d49a656502..12214f8a150 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -855,7 +855,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache) /* Run regular commands to completion unless lazyEval */ uint64 count = (es->lazyEval) ? 1 : 0; - ExecutorRun(es->qd, ForwardScanDirection, count); + ExecutorRun(es->qd, ForwardScanDirection, count, !fcache->returnsSet || !es->lazyEval); /* * If we requested run to completion OR there was no tuple returned, diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 55f97b14e6e..72c7b4d0689 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -2305,7 +2305,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount) ExecutorStart(queryDesc, eflags); - ExecutorRun(queryDesc, ForwardScanDirection, tcount); + ExecutorRun(queryDesc, ForwardScanDirection, tcount, true); _SPI_current->processed = queryDesc->estate->es_processed; _SPI_current->lastoid = queryDesc->estate->es_lastoid; |