Revert "Handle better implicit transaction state of pipeline mode"

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
This commit is contained in:
Michael Paquier 2024-11-28 09:43:28 +09:00
parent f1cb5e51f3
commit 24da0e7618
3 changed files with 23 additions and 29 deletions

View 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>

View 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;

View 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;