From 84935ea888d8ef607af6afb521cee8d98a85d1db Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Wed, 24 Sep 2025 22:23:25 +0900 Subject: [PATCH v13 1/3] Fix assertion failure and verbose messages in pipeline mode commandError() is called to report errors when they can be retried, and it previously assumed that errors are always detected during SQL command execution. However, in pipeline mode, an error may also be detected when a \endpipeline meta-command is executed. This caused an assertion failure. To fix this, it is now assumed that errors can also be detected in this case. Additionally, in pipeline mode, the error message reported in readCommandResponse() was lost, because it was reset when PQgetResult() returned NULL to indicate the end of query processing. To fix this, save the previous error message and use it for reporting. --- src/bin/pgbench/pgbench.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 3cafd88ac53..de00669f288 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -3059,7 +3059,13 @@ commandFailed(CState *st, const char *cmd, const char *message) static void commandError(CState *st, const char *message) { - Assert(sql_script[st->use_file].commands[st->command]->type == SQL_COMMAND); + /* + * Errors should only be detected during an SQL command or the \endpipeline + * meta command. Any other case triggers an assertion failure. + */ + Assert(sql_script[st->use_file].commands[st->command]->type == SQL_COMMAND || + sql_script[st->use_file].commands[st->command]->meta == META_ENDPIPELINE); + pg_log_info("client %d got an error in command %d (SQL) of script %d; %s", st->id, st->command, st->use_file, message); } @@ -3265,6 +3271,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 +3287,8 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix) { bool is_last; + 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 +3358,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 +3368,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 +3376,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 +3397,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