From 20432f8731404d2cef2a155144aca5ab3ae98e95 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 13 Dec 2022 14:23:58 -0500 Subject: Rethink handling of [Prevent|Is]InTransactionBlock in pipeline mode. Commits f92944137 et al. made IsInTransactionBlock() set the XACT_FLAGS_NEEDIMMEDIATECOMMIT flag before returning "false", on the grounds that that kept its API promises equivalent to those of PreventInTransactionBlock(). This turns out to be a bad idea though, because it allows an ANALYZE in a pipelined series of commands to cause an immediate commit, which is unexpected. Furthermore, if we return "false" then we have another issue, which is that ANALYZE will decide it's allowed to do internal commit-and-start-transaction sequences, thus possibly unexpectedly committing the effects of previous commands in the pipeline. To fix the latter situation, invent another transaction state flag XACT_FLAGS_PIPELINING, which explicitly records the fact that we have executed some extended-protocol command and not yet seen a commit for it. Then, require that flag to not be set before allowing InTransactionBlock() to return "false". Having done that, we can remove its setting of NEEDIMMEDIATECOMMIT without fear of causing problems. This means that the API guarantees of IsInTransactionBlock now diverge from PreventInTransactionBlock, which is mildly annoying, but it seems OK given the very limited usage of IsInTransactionBlock. (In any case, a caller preferring the old behavior could always set NEEDIMMEDIATECOMMIT for itself.) For consistency also require XACT_FLAGS_PIPELINING to not be set in PreventInTransactionBlock. This too is meant to prevent commands such as CREATE DATABASE from silently committing previous commands in a pipeline. Per report from Peter Eisentraut. As before, back-patch to all supported branches (which sadly no longer includes v10). Discussion: https://postgr.es/m/65a899dd-aebc-f667-1d0a-abb89ff3abf8@enterprisedb.com --- src/include/access/xact.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/include/access') diff --git a/src/include/access/xact.h b/src/include/access/xact.h index c604ee11f85..898b065b4f3 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -113,6 +113,13 @@ extern PGDLLIMPORT int MyXactFlags; */ #define XACT_FLAGS_NEEDIMMEDIATECOMMIT (1U << 2) +/* + * XACT_FLAGS_PIPELINING - set when we complete an extended-query-protocol + * Execute message. This is useful for detecting that an implicit transaction + * block has been created via pipelining. + */ +#define XACT_FLAGS_PIPELINING (1U << 3) + /* * start- and end-of-transaction callbacks for dynamically loaded modules */ -- cgit v1.2.3