From c3e7c24a1d60dc6ad56e2a0723399f1570c54224 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 12 Nov 2015 09:12:18 -0500
Subject: [PATCH] libpq: Notice errors a backend may have sent just before
 dying.

At least since the introduction of Hot Standby, the backend has
sometimes sent fatal errors even when no client query was in
progress, assuming that the client would receive it.  However,
pqHandleSendFailure was not in sync with this assumption, and
only tries to catch notices and notifies.  Add a parseInput call
to the loop there to fix.

Andres Freund suggested the fix.  Comments are by me.
Reviewed by Michael Paquier.
---
 src/interfaces/libpq/fe-exec.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 828f18e1110..07c43355211 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -1553,8 +1553,8 @@ sendFailed:
 /*
  * pqHandleSendFailure: try to clean up after failure to send command.
  *
- * Primarily, what we want to accomplish here is to process an async
- * NOTICE message that the backend might have sent just before it died.
+ * Primarily, what we want to accomplish here is to process any messages that
+ * the backend might have sent just before it died.
  *
  * NOTE: this routine should only be called in PGASYNC_IDLE state.
  */
@@ -1562,16 +1562,16 @@ void
 pqHandleSendFailure(PGconn *conn)
 {
 	/*
-	 * Accept any available input data, ignoring errors.  Note that if
-	 * pqReadData decides the backend has closed the channel, it will close
-	 * our side of the socket --- that's just what we want here.
+	 * Accept and parse any available input data.  Note that if pqReadData
+	 * decides the backend has closed the channel, it will close our side of
+	 * the socket --- that's just what we want here.
 	 */
 	while (pqReadData(conn) > 0)
-		 /* loop until no more data readable */ ;
+		parseInput(conn);
 
 	/*
-	 * Parse any available input messages.  Since we are in PGASYNC_IDLE
-	 * state, only NOTICE and NOTIFY messages will be eaten.
+	 * Make one attempt to parse available input messages even if we read no
+	 * data.
 	 */
 	parseInput(conn);
 }
-- 
GitLab