Hi, Currently, PQgetResult() returns NULL not only when no results remain for a sent query, but also when an out-of-memory error occurs, except when PGconn itself is NULL. As a result, users cannot distinguish between query completion and an out-of-memory error when PQgetResult() returns NULL.
The result returned by PQgetResult() is generated by either pqPipelineProcessQueue() or getCopyResult(). While pqPipelineProcessQueue() never returns NULL, even in the case of an out-of-memory error, getCopyResult() may return NULL. Therefore, I propose modifying getCopyResult() so that it never returns NULL, but instead returns OOM_result, as pqPipelineProcessQueue() does. I’ve attached a patch for this. Regards, Yugo Nagata -- Yugo Nagata <[email protected]>
>From 370e6b36e3879241b2a9fffab4fe217cace42a35 Mon Sep 17 00:00:00 2001 From: Yugo Nagata <[email protected]> Date: Tue, 11 Nov 2025 01:51:01 +0900 Subject: [PATCH] Make PQgetResult() not return NULL on out-of-memory error Previously, PQgetResult() returned NULL not only when no results remained for a sent query, but also when an out-of-memory error occurred, except when PGconn itself was NULL. As a result, users could not distinguish between query completion and an out-of-memory error when PQgetResult() returned NULL. This commit changes PQgetResult() to not return NULL in the case of an out-of-memory error by modifying getCopyResult() so that it never returns NULL, but instead returns OOM_result, as pqPipelineProcessQueue() does. --- src/interfaces/libpq/fe-exec.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 0b1e37ec30b..dfc25755b85 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -2061,8 +2061,7 @@ PQisBusy(PGconn *conn) /* * PQgetResult * Get the next PGresult produced by a query. Returns NULL if no - * query work remains or an error has occurred (e.g. out of - * memory). + * query work remains. * * In pipeline mode, once all the result of a query have been returned, * PQgetResult returns NULL to let the user know that the next @@ -2234,6 +2233,8 @@ PQgetResult(PGconn *conn) static PGresult * getCopyResult(PGconn *conn, ExecStatusType copytype) { + PGresult *res; + /* * If the server connection has been lost, don't pretend everything is * hunky-dory; instead return a PGRES_FATAL_ERROR result, and reset the @@ -2254,7 +2255,16 @@ getCopyResult(PGconn *conn, ExecStatusType copytype) return pqPrepareAsyncResult(conn); /* Otherwise, invent a suitable PGresult */ - return PQmakeEmptyPGresult(conn, copytype); + res = PQmakeEmptyPGresult(conn, copytype); + + /* + * Return the static OOM_result if out-of-memory. See the comments + * in pqPrepareAsyncResult(). + */ + if (!res) + res = unconstify(PGresult *, &OOM_result); + + return res; } -- 2.43.0
