Commit 4212cb73 authored by Robert Haas's avatar Robert Haas

Fix interaction of parallel query with prepared statements.

Previously, a prepared statement created via a Parse message could get
a parallel plan, but one created with a PREPARE statement could not.
This state of affairs was due to confusion on my (rhaas) part: I
erroneously believed that a CREATE TABLE .. AS EXECUTE statement could
only be performed with a prepared statement by PREPARE, but in fact
one created by a Prepare message works just as well.  Therefore, it
makes no sense to allow parallel query in one case but not the other.

To fix, allow parallel query with all prepared statements, but run
the parallel plan serially (i.e. without workers) in the case of
CREATE TABLE .. AS EXECUTE.  Also, document this.

Amit Kapila and Tobias Bussman, plus an extra sentence of
documentation by me.
parent cb9dcbc1
...@@ -227,6 +227,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; ...@@ -227,6 +227,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
</para> </para>
</listitem> </listitem>
<listitem>
<para>
A prepared statement is executed using a <literal>CREATE TABLE .. AS
EXECUTE ..</literal> statement. This construct converts what otherwise
would have been a read-only operation into a read-write operation,
making it ineligible for parallel query.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The transaction isolation level is serializable. This situation The transaction isolation level is serializable. This situation
......
...@@ -159,7 +159,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString) ...@@ -159,7 +159,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
nargs, nargs,
NULL, NULL,
NULL, NULL,
0, /* default cursor options */ CURSOR_OPT_PARALLEL_OK, /* allow parallel mode */
true); /* fixed result */ true); /* fixed result */
/* /*
......
...@@ -1540,10 +1540,11 @@ ExecutePlan(EState *estate, ...@@ -1540,10 +1540,11 @@ ExecutePlan(EState *estate,
estate->es_direction = direction; estate->es_direction = direction;
/* /*
* If a tuple count was supplied, we must force the plan to run without * If a tuple count was supplied or data is being written to relation, we
* parallelism, because we might exit early. * must force the plan to run without parallelism, because we might exit
* early.
*/ */
if (numberTuples) if (numberTuples || dest->mydest == DestIntoRel)
use_parallel_mode = false; use_parallel_mode = false;
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment