Skip to content

Commit 7668e85

Browse files
committed
Revert "Handle better implicit transaction state of pipeline mode"
This reverts commit d77f912 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
1 parent c93dffd commit 7668e85

File tree

4 files changed

+23
-203
lines changed

4 files changed

+23
-203
lines changed

doc/src/sgml/protocol.sgml

+10-11
Original file line numberDiff line numberDiff line change
@@ -1070,17 +1070,16 @@ SELCT 1/0;<!-- this typo is intentional -->
10701070

10711071
<para>
10721072
If the client has not issued an explicit <command>BEGIN</command>,
1073-
then an implicit transaction block is started and each Sync ordinarily
1074-
causes an implicit <command>COMMIT</command> if the preceding step(s)
1075-
succeeded, or an implicit <command>ROLLBACK</command> if they failed.
1076-
This implicit transaction block will only be detected by the server
1077-
when the first command ends without a sync. There are a few DDL
1078-
commands (such as <command>CREATE DATABASE</command>) that cannot be
1079-
executed inside a transaction block. If one of these is executed in a
1080-
pipeline, it will fail unless it is the first command after a Sync.
1081-
Furthermore, upon success it will force an immediate commit to preserve
1082-
database consistency. Thus a Sync immediately following one of these
1083-
commands has no effect except to respond with ReadyForQuery.
1073+
then each Sync ordinarily causes an implicit <command>COMMIT</command>
1074+
if the preceding step(s) succeeded, or an
1075+
implicit <command>ROLLBACK</command> if they failed. However, there
1076+
are a few DDL commands (such as <command>CREATE DATABASE</command>)
1077+
that cannot be executed inside a transaction block. If one of
1078+
these is executed in a pipeline, it will fail unless it is the first
1079+
command in the pipeline. Furthermore, upon success it will force an
1080+
immediate commit to preserve database consistency. Thus a Sync
1081+
immediately following one of these commands has no effect except to
1082+
respond with ReadyForQuery.
10841083
</para>
10851084

10861085
<para>

src/backend/access/transam/xact.c

+13
Original file line numberDiff line numberDiff line change
@@ -3603,6 +3603,16 @@ PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
36033603
errmsg("%s cannot run inside a subtransaction",
36043604
stmtType)));
36053605

3606+
/*
3607+
* inside a pipeline that has started an implicit transaction?
3608+
*/
3609+
if (MyXactFlags & XACT_FLAGS_PIPELINING)
3610+
ereport(ERROR,
3611+
(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3612+
/* translator: %s represents an SQL statement name */
3613+
errmsg("%s cannot be executed within a pipeline",
3614+
stmtType)));
3615+
36063616
/*
36073617
* inside a function call?
36083618
*/
@@ -3714,6 +3724,9 @@ IsInTransactionBlock(bool isTopLevel)
37143724
if (IsSubTransaction())
37153725
return true;
37163726

3727+
if (MyXactFlags & XACT_FLAGS_PIPELINING)
3728+
return true;
3729+
37173730
if (!isTopLevel)
37183731
return true;
37193732

src/backend/tcop/postgres.c

-18
Original file line numberDiff line numberDiff line change
@@ -2775,17 +2775,6 @@ start_xact_command(void)
27752775

27762776
xact_started = true;
27772777
}
2778-
else if (MyXactFlags & XACT_FLAGS_PIPELINING)
2779-
{
2780-
/*
2781-
* When the first Execute message is completed, following commands
2782-
* will be done in an implicit transaction block created via
2783-
* pipelining. The transaction state needs to be updated to an
2784-
* implicit block if we're not already in a transaction block (like
2785-
* one started by an explicit BEGIN).
2786-
*/
2787-
BeginImplicitTransactionBlock();
2788-
}
27892778

27902779
/*
27912780
* Start statement timeout if necessary. Note that this'll intentionally
@@ -4971,13 +4960,6 @@ PostgresMain(const char *dbname, const char *username)
49714960

49724961
case PqMsg_Sync:
49734962
pq_getmsgend(&input_message);
4974-
4975-
/*
4976-
* If pipelining was used, we may be in an implicit
4977-
* transaction block. Close it before calling
4978-
* finish_xact_command.
4979-
*/
4980-
EndImplicitTransactionBlock();
49814963
finish_xact_command();
49824964
valgrind_report_error_query("SYNC message");
49834965
send_ready_for_query = true;

src/bin/pgbench/t/001_pgbench_with_server.pl

-174
Original file line numberDiff line numberDiff line change
@@ -968,180 +968,6 @@ sub check_data_state
968968
}
969969
});
970970

971-
# Try SET LOCAL as first pipeline command. This succeeds and the first
972-
# command is not executed inside an implicit transaction block, causing
973-
# a WARNING.
974-
$node->pgbench(
975-
'-t 1 -n -M extended',
976-
0,
977-
[],
978-
[qr{WARNING: SET LOCAL can only be used in transaction blocks}],
979-
'SET LOCAL outside implicit transaction block of pipeline',
980-
{
981-
'001_pgbench_pipeline_set_local_1' => q{
982-
\startpipeline
983-
SET LOCAL statement_timeout='1h';
984-
\endpipeline
985-
}
986-
});
987-
988-
# Try SET LOCAL as second pipeline command. This succeeds and the second
989-
# command does not cause a WARNING to be generated.
990-
$node->pgbench(
991-
'-t 1 -n -M extended',
992-
0,
993-
[],
994-
[qr{^$}],
995-
'SET LOCAL inside implicit transaction block of pipeline',
996-
{
997-
'001_pgbench_pipeline_set_local_2' => q{
998-
\startpipeline
999-
SELECT 1;
1000-
SET LOCAL statement_timeout='1h';
1001-
\endpipeline
1002-
}
1003-
});
1004-
1005-
# Try SET LOCAL with \syncpipeline. This succeeds and the command
1006-
# launched after the sync is outside the implicit transaction block
1007-
# of the pipeline, causing a WARNING.
1008-
$node->pgbench(
1009-
'-t 1 -n -M extended',
1010-
0,
1011-
[],
1012-
[qr{WARNING: SET LOCAL can only be used in transaction blocks}],
1013-
'SET LOCAL and \syncpipeline',
1014-
{
1015-
'001_pgbench_pipeline_set_local_3' => q{
1016-
\startpipeline
1017-
SELECT 1;
1018-
\syncpipeline
1019-
SET LOCAL statement_timeout='1h';
1020-
\endpipeline
1021-
}
1022-
});
1023-
1024-
# Try REINDEX CONCURRENTLY as first pipeline command. This succeeds
1025-
# as the first command is outside the implicit transaction block of
1026-
# a pipeline.
1027-
$node->pgbench(
1028-
'-t 1 -n -M extended',
1029-
0,
1030-
[],
1031-
[],
1032-
'REINDEX CONCURRENTLY outside implicit transaction block of pipeline',
1033-
{
1034-
'001_pgbench_pipeline_reindex_1' => q{
1035-
\startpipeline
1036-
REINDEX TABLE CONCURRENTLY pgbench_accounts;
1037-
SELECT 1;
1038-
\endpipeline
1039-
}
1040-
});
1041-
1042-
# Try REINDEX CONCURRENTLY as second pipeline command. This fails
1043-
# as the second command is inside an implicit transaction block.
1044-
$node->pgbench(
1045-
'-t 1 -n -M extended',
1046-
2,
1047-
[],
1048-
[],
1049-
'error: REINDEX CONCURRENTLY inside implicit transaction block of pipeline',
1050-
{
1051-
'001_pgbench_pipeline_reindex_2' => q{
1052-
\startpipeline
1053-
SELECT 1;
1054-
REINDEX TABLE CONCURRENTLY pgbench_accounts;
1055-
\endpipeline
1056-
}
1057-
});
1058-
1059-
# Try VACUUM as first pipeline command. Like REINDEX CONCURRENTLY, this
1060-
# succeeds as this is outside the implicit transaction block of a pipeline.
1061-
$node->pgbench(
1062-
'-t 1 -n -M extended',
1063-
0,
1064-
[],
1065-
[],
1066-
'VACUUM outside implicit transaction block of pipeline',
1067-
{
1068-
'001_pgbench_pipeline_vacuum_1' => q{
1069-
\startpipeline
1070-
VACUUM pgbench_accounts;
1071-
\endpipeline
1072-
}
1073-
});
1074-
1075-
# Try VACUUM as second pipeline command. This fails, as the second command
1076-
# of a pipeline is inside an implicit transaction block.
1077-
$node->pgbench(
1078-
'-t 1 -n -M extended',
1079-
2,
1080-
[],
1081-
[],
1082-
'error: VACUUM inside implicit transaction block of pipeline',
1083-
{
1084-
'001_pgbench_pipeline_vacuum_2' => q{
1085-
\startpipeline
1086-
SELECT 1;
1087-
VACUUM pgbench_accounts;
1088-
\endpipeline
1089-
}
1090-
});
1091-
1092-
# Try subtransactions in a pipeline. These are forbidden in implicit
1093-
# transaction blocks.
1094-
$node->pgbench(
1095-
'-t 1 -n -M extended',
1096-
2,
1097-
[],
1098-
[],
1099-
'error: subtransactions not allowed in pipeline',
1100-
{
1101-
'001_pgbench_pipeline_subtrans' => q{
1102-
\startpipeline
1103-
SAVEPOINT a;
1104-
SELECT 1;
1105-
ROLLBACK TO SAVEPOINT a;
1106-
SELECT 2;
1107-
\endpipeline
1108-
}
1109-
});
1110-
1111-
# Try LOCK TABLE as first pipeline command. This fails as LOCK is outside
1112-
# an implicit transaction block.
1113-
$node->pgbench(
1114-
'-t 1 -n -M extended',
1115-
2,
1116-
[],
1117-
[],
1118-
'error: LOCK TABLE outside implicit transaction block of pipeline',
1119-
{
1120-
'001_pgbench_pipeline_lock_1' => q{
1121-
\startpipeline
1122-
LOCK pgbench_accounts;
1123-
SELECT 1;
1124-
\endpipeline
1125-
}
1126-
});
1127-
1128-
# Try LOCK TABLE as second pipeline command. This succeeds as LOCK is inside
1129-
# an implicit transaction block.
1130-
$node->pgbench(
1131-
'-t 1 -n -M extended',
1132-
0,
1133-
[],
1134-
[],
1135-
'LOCK TABLE inside implicit transaction block of pipeline',
1136-
{
1137-
'001_pgbench_pipeline_lock_2' => q{
1138-
\startpipeline
1139-
SELECT 1;
1140-
LOCK pgbench_accounts;
1141-
\endpipeline
1142-
}
1143-
});
1144-
1145971
# Working \startpipeline in prepared query mode with serializable
1146972
$node->pgbench(
1147973
'-c4 -t 10 -n -M prepared',

0 commit comments

Comments
 (0)