pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Cc: Fabien COELHO <coelho@cri.ensmp.fr>
Subject: libpq async duplicate error results
Date: Tue, 25 Jan 2022 09:32:41 +0100
Message-ID: <ab4288f8-be5c-57fb-2400-e3e857f53e46@enterprisedb.com> (raw)


This issue was discovered by Fabien in the SHOW_ALL_RESULTS thread.  I'm 
posting it here separately, because I think it ought to be addressed in 
libpq rather than with a workaround in psql, as proposed over there.

When using PQsendQuery() + PQgetResult() and the server crashes during 
the execution of the command, PQgetResult() then returns two result sets 
with partially duplicated error messages, like this from the attached 
test program:

command = SELECT 'before';
result 1 status = PGRES_TUPLES_OK
error message = ""

command = SELECT pg_terminate_backend(pg_backend_pid());
result 1 status = PGRES_FATAL_ERROR
error message = "FATAL:  terminating connection due to administrator command
"
result 2 status = PGRES_FATAL_ERROR
error message = "FATAL:  terminating connection due to administrator command
server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
"

command = SELECT 'after';
PQsendQuery() error: no connection to the server


This is hidden in normal use because PQexec() throws away all but the 
last result set, but the extra one is still generated internally.

Apparently, this has changed between PG13 and PG14.  In PG13 and 
earlier, the output is

command = SELECT 'before';
result 1 status = PGRES_TUPLES_OK
error message = ""

command = SELECT pg_terminate_backend(pg_backend_pid());
result 1 status = PGRES_FATAL_ERROR
error message = "FATAL:  terminating connection due to administrator command
"
result 2 status = PGRES_FATAL_ERROR
error message = "server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
"

command = SELECT 'after';
PQsendQuery() error: no connection to the server

In PG13, PQexec() concatenates all the error messages from multiple 
results, so a user of PQexec() sees the same output before and after. 
But for users of the lower-level APIs, things have become a bit more 
confusing.

Also, why are there multiple results being generated in the first place?


[0]: 
https://www.postgresql.org/message-id/alpine.DEB.2.22.394.2112230703530.2668598@pseudo

Attachments:

test.c (text/plain, 1015B) download #include <stdio.h> #include <libpq-fe.h> static void run_query(PGconn *conn, const char *command) { int rc; PGresult *res; int count = 0; fprintf(stderr, "command = %s\n", command); rc = PQsendQuery(conn, command); if (rc != 1) { char *error = PQerrorMessage(conn); fprintf(stderr, "PQsendQuery() error: %s", error); return; } while ((res = PQgetResult(conn))) { ExecStatusType status; status = PQresultStatus(res); fprintf(stderr, "result %d status = %s\n", ++count, PQresStatus(status)); fprintf(stderr, "error message = \"%s\"\n", PQresultErrorMessage(res)); PQclear(res); } fprintf(stderr, "\n"); return; } int main() { PGconn *conn; conn = PQconnectdb(""); if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn)); return 1; } run_query(conn, "SELECT 'before';"); run_query(conn, "SELECT pg_terminate_backend(pg_backend_pid());"); run_query(conn, "SELECT 'after';"); PQfinish(conn); return 0; }

view thread (19+ messages)  latest in thread

Message-ID: <ab4288f8-be5c-57fb-2400-e3e857f53e46@enterprisedb.com>
Permalink:  ../ab4288f8-be5c-57fb-2400-e3e857f53e46@enterprisedb.com/
Also on:    postgresql.org/message-id/ab4288f8-be5c-57fb-2400-e3e857f53e46@enterprisedb.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: peter.eisentraut@enterprisedb.com, coelho@cri.ensmp.fr
  Subject: Re: libpq async duplicate error results
  In-Reply-To: <ab4288f8-be5c-57fb-2400-e3e857f53e46@enterprisedb.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox