]> granicus.if.org Git - postgresql/commitdiff
Fix interaction of parallel query with prepared statements.
authorRobert Haas <rhaas@postgresql.org>
Tue, 6 Dec 2016 16:11:54 +0000 (11:11 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 6 Dec 2016 16:43:12 +0000 (11:43 -0500)
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.

doc/src/sgml/parallel.sgml
src/backend/commands/prepare.c
src/backend/executor/execMain.c

index 38a040ef75ec7f9ede10f6a3823dad0ea829191b..195fd308a6167429eaac1d29eb800705d14aa152 100644 (file)
@@ -218,6 +218,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
       </para>
     </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>
       <para> 
         The transaction isolation level is serializable.  This situation
index cec37ce0405739d42732848ae08eef58dfa3daaa..b01051df9d2f942d14a7d102fec97274f6342c05 100644 (file)
@@ -159,7 +159,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
                                           nargs,
                                           NULL,
                                           NULL,
-                                          0,           /* default cursor options */
+                                          CURSOR_OPT_PARALLEL_OK,      /* allow parallel mode */
                                           true);       /* fixed result */
 
        /*
index 32bb3f9205491e5467cc2cc297fcb9387ac48a9c..71c07288a19082d790411a5d2369035ad461cdac 100644 (file)
@@ -1540,10 +1540,11 @@ 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.
+        * If a tuple count was supplied or data is being written to relation, we
+        * must force the plan to run without parallelism, because we might exit
+        * early.
         */
-       if (numberTuples)
+       if (numberTuples || dest->mydest == DestIntoRel)
                use_parallel_mode = false;
 
        /*