From 8e4b9d2489f12d342b3a613466dfa043130e8e5f Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Fri, 26 Sep 2025 10:41:34 +0900 Subject: [PATCH v15 1/3] 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 cc03af05447..a84c68705de 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -3272,6 +3272,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 @@ -3287,6 +3288,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); @@ -3356,7 +3360,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: @@ -3366,7 +3370,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 */ @@ -3374,14 +3378,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) @@ -3395,6 +3399,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