From 1e9bccb2d43c0d2264133ef239655947c8e0864e Mon Sep 17 00:00:00 2001 From: Yugo Nagata 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