From 1e9bccb2d43c0d2264133ef239655947c8e0864e Mon Sep 17 00:00:00 2001
From: Yugo Nagata <nagata@sraoss.co.jp>
Date: Fri, 26 Sep 2025 10:41:34 +0900
Subject: [PATCH v14 1/4] pgbench: Do not reference error message after another
 PQgetResult() call

Previously, readCommandResponse() accessed the error message
after calling another PQgetResult() to peek at the next result
in order to determine whether the current one was the last.

This caused the error message to be lost in pipeline mode.
Although this issue has never been observed in non-pipeline mode,
referencing an error message after another PQgetResult() call
does not seem like a good idea in general.

Fix this by saving the previous error message and using it for reporting.
---
 src/bin/pgbench/pgbench.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 3cafd88ac53..f0a405ca129 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3265,6 +3265,7 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 	PGresult   *res;
 	PGresult   *next_res;
 	int			qrynum = 0;
+	char	   *errmsg;
 
 	/*
 	 * varprefix should be set only with \gset or \aset, and \endpipeline and
@@ -3280,6 +3281,9 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 	{
 		bool		is_last;
 
+		/* save the previous error message before peek at the next result */
+		errmsg = pg_strdup(PQerrorMessage(st->con));
+
 		/* peek at the next result to know whether the current is last */
 		next_res = PQgetResult(st->con);
 		is_last = (next_res == NULL);
@@ -3349,7 +3353,7 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 				st->num_syncs--;
 				if (st->num_syncs == 0 && PQexitPipelineMode(st->con) != 1)
 					pg_log_error("client %d failed to exit pipeline mode: %s", st->id,
-								 PQerrorMessage(st->con));
+								 errmsg);
 				break;
 
 			case PGRES_NONFATAL_ERROR:
@@ -3359,7 +3363,7 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 				if (canRetryError(st->estatus))
 				{
 					if (verbose_errors)
-						commandError(st, PQerrorMessage(st->con));
+						commandError(st, errmsg);
 					goto error;
 				}
 				/* fall through */
@@ -3367,14 +3371,14 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 			default:
 				/* anything else is unexpected */
 				pg_log_error("client %d script %d aborted in command %d query %d: %s",
-							 st->id, st->use_file, st->command, qrynum,
-							 PQerrorMessage(st->con));
+							 st->id, st->use_file, st->command, qrynum, errmsg);
 				goto error;
 		}
 
 		PQclear(res);
 		qrynum++;
 		res = next_res;
+		pg_free(errmsg);
 	}
 
 	if (qrynum == 0)
@@ -3388,6 +3392,7 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 error:
 	PQclear(res);
 	PQclear(next_res);
+	pg_free(errmsg);
 	do
 	{
 		res = PQgetResult(st->con);
-- 
2.43.0

