diff options
| author | Robert Haas | 2017-03-23 17:05:48 +0000 |
|---|---|---|
| committer | Robert Haas | 2017-03-23 17:14:36 +0000 |
| commit | 691b8d59281b5177f16fe80858df921f77a8e955 (patch) | |
| tree | 8708ae434bf120e73f93e3ef43779d761438ba79 /src/backend/commands | |
| parent | 218f51584d5a9fcdf702bcc7f54b5b65e255c187 (diff) | |
Allow for parallel execution whenever ExecutorRun() is done only once.
Previously, it was unsafe to execute a plan in parallel if
ExecutorRun() might be called with a non-zero row count. However,
it's quite easy to fix things up so that we can support that case,
provided that it is known that we will never call ExecutorRun() a
second time for the same QueryDesc. Add infrastructure to signal
this, and cross-checks to make sure that a caller who claims this is
true doesn't later reneg.
While that pattern never happens with queries received directly from a
client -- there's no way to know whether multiple Execute messages
will be sent unless the first one requests all the rows -- it's pretty
common for queries originating from procedural languages, which often
limit the result to a single tuple or to a user-specified number of
tuples.
This commit doesn't actually enable parallelism in any additional
cases, because currently none of the places that would be able to
benefit from this infrastructure pass CURSOR_OPT_PARALLEL_OK in the
first place, but it makes it much more palatable to pass
CURSOR_OPT_PARALLEL_OK in places where we currently don't, because it
eliminates some cases where we'd end up having to run the parallel
plan serially.
Patch by me, based on some ideas from Rafia Sabih and corrected by
Rafia Sabih based on feedback from Dilip Kumar and myself.
Discussion: http://postgr.es/m/CA+TgmobXEhvHbJtWDuPZM9bVSLiTj-kShxQJ2uM5GPDze9fRYA@mail.gmail.com
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/copy.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/createas.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/explain.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/extension.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/matview.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/portalcmds.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/prepare.c | 2 |
7 files changed, 7 insertions, 7 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index b0fd09f458a..ab59be84552 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -2074,7 +2074,7 @@ CopyTo(CopyState cstate) else { /* run the plan --- the dest receiver will send tuples */ - ExecutorRun(cstate->queryDesc, ForwardScanDirection, 0L); + ExecutorRun(cstate->queryDesc, ForwardScanDirection, 0L, true); processed = ((DR_copy *) cstate->queryDesc->dest)->processed; } diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 646a88409f2..3daffc894a1 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -347,7 +347,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, ExecutorStart(queryDesc, GetIntoRelEFlags(into)); /* run the plan to completion */ - ExecutorRun(queryDesc, ForwardScanDirection, 0L); + ExecutorRun(queryDesc, ForwardScanDirection, 0L, true); /* save the rowcount if we're given a completionTag to fill */ if (completionTag) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index c9b55ead3dc..b4c7466666b 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -530,7 +530,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, dir = ForwardScanDirection; /* run the plan */ - ExecutorRun(queryDesc, dir, 0L); + ExecutorRun(queryDesc, dir, 0L, true); /* run cleanup too */ ExecutorFinish(queryDesc); diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 86a84ee2346..5a84bedf467 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -742,7 +742,7 @@ execute_sql_string(const char *sql, const char *filename) dest, NULL, 0); ExecutorStart(qdesc, 0); - ExecutorRun(qdesc, ForwardScanDirection, 0); + ExecutorRun(qdesc, ForwardScanDirection, 0, true); ExecutorFinish(qdesc); ExecutorEnd(qdesc); diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 8df3d1d81dd..9d41ad8fad2 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -424,7 +424,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query, ExecutorStart(queryDesc, EXEC_FLAG_WITHOUT_OIDS); /* run the plan */ - ExecutorRun(queryDesc, ForwardScanDirection, 0L); + ExecutorRun(queryDesc, ForwardScanDirection, 0L, true); processed = queryDesc->estate->es_processed; diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 29d0430dd87..f57cf87e8c3 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -395,7 +395,7 @@ PersistHoldablePortal(Portal portal) true); /* Fetch the result set into the tuplestore */ - ExecutorRun(queryDesc, ForwardScanDirection, 0L); + ExecutorRun(queryDesc, ForwardScanDirection, 0L, false); (*queryDesc->dest->rDestroy) (queryDesc->dest); queryDesc->dest = NULL; diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index 1cf0d2b971a..992ba1c9a2e 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -301,7 +301,7 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause, */ PortalStart(portal, paramLI, eflags, GetActiveSnapshot()); - (void) PortalRun(portal, count, false, dest, dest, completionTag); + (void) PortalRun(portal, count, false, true, dest, dest, completionTag); PortalDrop(portal, false); |
