Abort pgbench if script end is reached with an open pipeline
authorAlvaro Herrera <[email protected]>
Mon, 22 Jan 2024 16:48:30 +0000 (17:48 +0100)
committerAlvaro Herrera <[email protected]>
Mon, 22 Jan 2024 16:48:30 +0000 (17:48 +0100)
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 <[email protected]>
Reported-by: Michael Paquier <[email protected]>
Discussion: https://postgr.es/m/[email protected]

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

index f6e4d04ea1ab04756c6abfc1aaa2ad38b00c36b1..c1d577a959f7ecc1e2c337e50596b7f70668d8ab 100644 (file)
@@ -3337,10 +3337,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;
                }
 
index c124741fa5d41bb8aba27ff48779e6f5f56140d6..dfe72f525b76d05ec7cf2f9b18aea59a0c3e2b9b 100644 (file)
@@ -828,6 +828,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',