aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2024-01-22 17:48:30 +0100
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2024-01-22 17:48:30 +0100
commit49f7c6c44a5f6a7f7b39d140e490c9c627511893 (patch)
treeb79a71bf9918266472b51ee7b5c62422cf858977 /src
parent752533d40fd50de0b09d4b956cc32c38f5df2f05 (diff)
downloadpostgresql-49f7c6c44a5f6a7f7b39d140e490c9c627511893.tar.gz
postgresql-49f7c6c44a5f6a7f7b39d140e490c9c627511893.zip
Abort pgbench if script end is reached with an open pipeline
When a pipeline is opened with \startpipeline and not closed, pgbench will either error on the next transaction with a "already in pipeline mode" error or successfully end if this was the last transaction -- despite not sending anything that was piped in the pipeline. Make it an error to reach end of script is reached while there's an open pipeline. Backpatch to 14, where pgbench got support for pipelines. Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> Reported-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/Za4IObZkDjrO4TcS@paquier.xyz
Diffstat (limited to 'src')
-rw-r--r--src/bin/pgbench/pgbench.c15
-rw-r--r--src/bin/pgbench/t/001_pgbench_with_server.pl28
2 files changed, 41 insertions, 2 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 25744548392..7b53f9c24da 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3763,10 +3763,21 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
case CSTATE_START_COMMAND:
command = sql_script[st->use_file].commands[st->command];
- /* Transition to script end processing if done */
+ /*
+ * Transition to script end processing if done, but close up
+ * shop if a pipeline is open at this point.
+ */
if (command == NULL)
{
- st->state = CSTATE_END_TX;
+ if (PQpipelineStatus(st->con) == PQ_PIPELINE_OFF)
+ st->state = CSTATE_END_TX;
+ else
+ {
+ pg_log_error("client %d aborted: end of script reached with pipeline open",
+ st->id);
+ st->state = CSTATE_ABORTED;
+ }
+
break;
}
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index fc57facf9e2..f60f7e89c1f 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -876,6 +876,34 @@ select 1 \gset f
}
});
+# Try \startpipeline without \endpipeline in a single transaction
+$node->pgbench(
+ '-t 1 -n -M extended',
+ 2,
+ [],
+ [qr{end of script reached with pipeline open}],
+ 'error: call \startpipeline without \endpipeline in a single transaction',
+ {
+ '001_pgbench_pipeline_5' => q{
+-- startpipeline only with single transaction
+\startpipeline
+}
+ });
+
+# Try \startpipeline without \endpipeline
+$node->pgbench(
+ '-t 2 -n -M extended',
+ 2,
+ [],
+ [qr{end of script reached with pipeline open}],
+ 'error: call \startpipeline without \endpipeline',
+ {
+ '001_pgbench_pipeline_6' => q{
+-- startpipeline only
+\startpipeline
+}
+ });
+
# Working \startpipeline in prepared query mode with serializable
$node->pgbench(
'-c4 -t 10 -n -M prepared',