From 02dfe9220f15719cc37431b325e730510f887d2c Mon Sep 17 00:00:00 2001
From: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Date: Wed, 1 Oct 2025 10:37:24 +0200
Subject: [PATCH v01] Exit copy state in pgbench to avoid infinite loop

Currently, pgbench aborts when a copy response is received in
readCommandResponse. However, PQgetResult will return an empty
result when there's no async result through getCopyResult, leading to an
infinite loop in the error handling.

This patch forcefully exits the copy state with PQendcopy before moving
to the error handler, avoiding the infinite loop.
---
 src/bin/pgbench/pgbench.c                    | 13 +++++++++++++
 src/bin/pgbench/t/001_pgbench_with_server.pl | 11 +++++++++++
 2 files changed, 24 insertions(+)

diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 36c6469149e..af948c8328c 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3359,6 +3359,19 @@ 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 copy state. Otherwise, PQgetResult will
+				 * always return an empty PGresult from getCopyResult, leading
+				 * to an infinite loop during error cleanup
+				 */
+				PQendcopy(st->con);
+				goto error;
+
 			case PGRES_NONFATAL_ERROR:
 			case PGRES_FATAL_ERROR:
 				st->estatus = getSQLErrorStatus(PQresultErrorField(res,
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 7dd78940300..f61dcf68234 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -1810,6 +1810,17 @@ update counter set i = i+1 returning i \gset
 }
 	});
 
+# 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 }
+	});
+
 # Clean up
 $node->safe_psql('postgres', 'DROP TABLE counter;');
 
-- 
2.51.0

