diff options
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 79bbe6bc762..d5385438e3b 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -205,7 +205,8 @@ init_execution_state(List *queryTree_list, if (ps->commandType == CMD_SELECT && ps->utilityStmt == NULL && - ps->intoClause == NULL) + ps->intoClause == NULL && + !ps->hasModifyingCTE) fcache->lazyEval = lasttages->lazyEval = true; } } @@ -431,14 +432,19 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) if (es->qd->utilitystmt == NULL) { /* - * Only set up to collect queued triggers if it's not a SELECT. This - * isn't just an optimization, but is necessary in case a SELECT - * returns multiple rows to caller --- we mustn't exit from the - * function execution with a stacked AfterTrigger level still active. + * In lazyEval mode, do not let the executor set up an AfterTrigger + * context. This is necessary not just an optimization, because we + * mustn't exit from the function execution with a stacked + * AfterTrigger level still active. We are careful not to select + * lazyEval mode for any statement that could possibly queue triggers. */ - if (es->qd->operation != CMD_SELECT) - AfterTriggerBeginQuery(); - ExecutorStart(es->qd, 0); + int eflags; + + if (es->lazyEval) + eflags = EXEC_FLAG_SKIP_TRIGGERS; + else + eflags = 0; /* default run-to-completion flags */ + ExecutorStart(es->qd, eflags); } es->status = F_EXEC_RUN; @@ -499,8 +505,7 @@ postquel_end(execution_state *es) /* Make our snapshot the active one for any called functions */ PushActiveSnapshot(es->qd->snapshot); - if (es->qd->operation != CMD_SELECT) - AfterTriggerEndQuery(es->qd->estate); + ExecutorFinish(es->qd); ExecutorEnd(es->qd); PopActiveSnapshot(); |