]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pgbench: Fail cleanly when finding a COPY result state
authorMichael Paquier <michael@paquier.xyz>
Fri, 3 Oct 2025 05:04:06 +0000 (14:04 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 3 Oct 2025 05:04:06 +0000 (14:04 +0900)
Currently, pgbench aborts when a COPY response is received in
readCommandResponse().  However, as PQgetResult() returns an empty
result when there is no asynchronous result, through getCopyResult(),
the logic done at the end of readCommandResponse() for the error path
leads to an infinite loop.

This commit forcefully exits the COPY state with PQendcopy() before
moving to the error handler when fiding a COPY state, avoiding the
infinite loop.  The COPY protocol is not supported by pgbench anyway, as
an error is assumed in this case, so giving up is better than having the
tool be stuck forever.  pgbench was interruptible in this state.

A TAP test is added to check that an error happens if trying to use
COPY.

Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Discussion: https://postgr.es/m/CAO6_XqpHyF2m73ifV5a=5jhXxH2chk=XrgefY+eWWPe2Eft3=A@mail.gmail.com
Backpatch-through: 13

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

index 445d4ae72c2698972a7e997c533f072428ec24ab..fd70196a160a51746d9aa673d91ef04a05ae6038 100644 (file)
@@ -3086,6 +3086,20 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
                                                                 PQresultErrorMessage(res));
                                break;
 
+                       case PGRES_COPY_IN:
+                       case PGRES_COPY_OUT:
+                       case PGRES_COPY_BOTH:
+                               pg_log_error("COPY is not supported in pgbench, aborting");
+
+                               /*
+                                * We need to exit the copy state.  Otherwise, PQgetResult()
+                                * will always return an empty PGresult as an effect of
+                                * getCopyResult(), leading to an infinite loop in the error
+                                * cleanup done below.
+                                */
+                               PQendcopy(st->con);
+                               goto error;
+
                        default:
                                /* anything else is unexpected */
                                pg_log_error("client %d script %d aborted in command %d query %d: %s",
index fbd45c766cc67143ce033c0c067591db056e44ae..52bcf8fec143054f91a5d7a753f6e7f55a9d3a21 100644 (file)
@@ -1315,6 +1315,17 @@ $node->pgbench(
 check_pgbench_logs($bdir, '001_pgbench_log_3', 1, 10, 10,
        qr{^0 \d{1,2} \d+ \d \d+ \d+$});
 
+# Test copy in pgbench
+$node->pgbench(
+       '-t 10',
+       2,
+       [],
+       [ qr{COPY is not supported in pgbench, aborting} ],
+       'Test copy in script',
+       {
+               '001_copy' => q{ COPY pgbench_accounts FROM stdin }
+       });
+
 # done
 $node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts');
 $node->stop;