]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Revert "Handle better implicit transaction state of pipeline mode"
authorMichael Paquier <michael@paquier.xyz>
Thu, 28 Nov 2024 00:43:28 +0000 (09:43 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 28 Nov 2024 00:43:28 +0000 (09:43 +0900)
This reverts commit d77f91214fb7 on all stable branches, due to concerns
regarding the compatility side effects this could create in a minor
release.  The change still exists on HEAD.

Discussion: https://postgr.es/m/CA+TgmoZqRgeFTg4+Yf_CMRRXiHuNz1u6ZC4FvVk+rxw0RmOPnw@mail.gmail.com
Backpatch-through: 13

doc/src/sgml/protocol.sgml
src/backend/access/transam/xact.c
src/backend/tcop/postgres.c

index 9a5b7eeb4a8213d439a2b7339b5fa9d2271c8141..812c07e500f2566edcf796407d133e37b3ec5cd7 100644 (file)
@@ -1088,17 +1088,16 @@ SELCT 1/0;<!-- this typo is intentional -->
 
    <para>
     If the client has not issued an explicit <command>BEGIN</command>,
-    then an implicit transaction block is started and each Sync ordinarily
-    causes an implicit <command>COMMIT</command> if the preceding step(s)
-    succeeded, or an implicit <command>ROLLBACK</command> if they failed.
-    This implicit transaction block will only be detected by the server
-    when the first command ends without a sync.  There are a few DDL
-    commands (such as <command>CREATE DATABASE</command>) that cannot be
-    executed inside a transaction block. If one of these is executed in a
-    pipeline, it will fail unless it is the first command after a Sync.
-    Furthermore, upon success it will force an immediate commit to preserve
-    database consistency. Thus a Sync immediately following one of these
-    commands has no effect except to respond with ReadyForQuery.
+    then each Sync ordinarily causes an implicit <command>COMMIT</command>
+    if the preceding step(s) succeeded, or an
+    implicit <command>ROLLBACK</command> if they failed.  However, there
+    are a few DDL commands (such as <command>CREATE DATABASE</command>)
+    that cannot be executed inside a transaction block.  If one of
+    these is executed in a pipeline, it will fail unless it is the first
+    command in the pipeline.  Furthermore, upon success it will force an
+    immediate commit to preserve database consistency.  Thus a Sync
+    immediately following one of these commands has no effect except to
+    respond with ReadyForQuery.
    </para>
 
    <para>
index 423545e6038cee9a6c1ba089b4daffef185224a8..ffe26e26f660e7c302dddf586c027a49c3d9c750 100644 (file)
@@ -3405,6 +3405,16 @@ PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
                                 errmsg("%s cannot run inside a subtransaction",
                                                stmtType)));
 
+       /*
+        * inside a pipeline that has started an implicit transaction?
+        */
+       if (MyXactFlags & XACT_FLAGS_PIPELINING)
+               ereport(ERROR,
+                               (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+               /* translator: %s represents an SQL statement name */
+                                errmsg("%s cannot be executed within a pipeline",
+                                               stmtType)));
+
        /*
         * inside a function call?
         */
@@ -3516,6 +3526,9 @@ IsInTransactionBlock(bool isTopLevel)
        if (IsSubTransaction())
                return true;
 
+       if (MyXactFlags & XACT_FLAGS_PIPELINING)
+               return true;
+
        if (!isTopLevel)
                return true;
 
index d375d845b97e97d6b8a979987dea1943dfb8f0ea..ec630b449166fad5ac15a7354dcb017109c3523d 100644 (file)
@@ -2656,17 +2656,6 @@ start_xact_command(void)
 
                xact_started = true;
        }
-       else if (MyXactFlags & XACT_FLAGS_PIPELINING)
-       {
-               /*
-                * When the first Execute message is completed, following commands
-                * will be done in an implicit transaction block created via
-                * pipelining. The transaction state needs to be updated to an
-                * implicit block if we're not already in a transaction block (like
-                * one started by an explicit BEGIN).
-                */
-               BeginImplicitTransactionBlock();
-       }
 
        /*
         * Start statement timeout if necessary.  Note that this'll intentionally
@@ -4616,13 +4605,6 @@ PostgresMain(int argc, char *argv[],
 
                        case 'S':                       /* sync */
                                pq_getmsgend(&input_message);
-
-                               /*
-                                * If pipelining was used, we may be in an implicit
-                                * transaction block. Close it before calling
-                                * finish_xact_command.
-                                */
-                               EndImplicitTransactionBlock();
                                finish_xact_command();
                                send_ready_for_query = true;
                                break;