From 1de0a4e00eee2a72c0b5b34892092efcec681f81 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 15 Feb 2017 11:03:30 -0500
Subject: [PATCH] libpq: Make target_session_attrs=read-write consume empty
 result.

Otherwise, the leftover empty result can cause problems in some
situations.

Michael Paquier and Ashutosh Bapat, per a report from Higuchi Daisuke
---
 src/interfaces/libpq/fe-connect.c | 38 ++++++++++++++++++++++++++++---
 src/interfaces/libpq/libpq-fe.h   |  4 +++-
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index c505b661c6b..65b7c31dc03 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1896,6 +1896,7 @@ PQconnectPoll(PGconn *conn)
 		case CONNECTION_SSL_STARTUP:
 		case CONNECTION_NEEDED:
 		case CONNECTION_CHECK_WRITABLE:
+		case CONNECTION_CONSUME:
 			break;
 
 		default:
@@ -2935,6 +2936,34 @@ keep_going:						/* We will come back to here until there is
 			conn->status = CONNECTION_OK;
 			return PGRES_POLLING_OK;
 
+		case CONNECTION_CONSUME:
+			{
+				conn->status = CONNECTION_OK;
+				if (!PQconsumeInput(conn))
+					goto error_return;
+
+				if (PQisBusy(conn))
+				{
+					conn->status = CONNECTION_CONSUME;
+					restoreErrorMessage(conn, &savedMessage);
+					return PGRES_POLLING_READING;
+				}
+
+				/*
+				 * Call PQgetResult() again to consume NULL result.
+				 */
+				res = PQgetResult(conn);
+				if (res != NULL)
+				{
+					PQclear(res);
+					conn->status = CONNECTION_CONSUME;
+					goto keep_going;
+				}
+
+				/* We are open for business! */
+				conn->status = CONNECTION_OK;
+				return PGRES_POLLING_OK;
+			}
 		case CONNECTION_CHECK_WRITABLE:
 			{
 				if (!saveErrorMessage(conn, &savedMessage))
@@ -2994,9 +3023,12 @@ keep_going:						/* We will come back to here until there is
 					/* We can release the address lists now. */
 					release_all_addrinfo(conn);
 
-					/* We are open for business! */
-					conn->status = CONNECTION_OK;
-					return PGRES_POLLING_OK;
+					/*
+					 * Finish reading any remaining messages before
+					 * being considered as ready.
+					 */
+					conn->status = CONNECTION_CONSUME;
+					goto keep_going;
 				}
 
 				/*
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 1b53d0ed16a..635af5b50e3 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -63,8 +63,10 @@ typedef enum
 	CONNECTION_SETENV,			/* Negotiating environment. */
 	CONNECTION_SSL_STARTUP,		/* Negotiating SSL. */
 	CONNECTION_NEEDED,			/* Internal state: connect() needed */
-	CONNECTION_CHECK_WRITABLE	/* Check if we could make a writable
+	CONNECTION_CHECK_WRITABLE,	/* Check if we could make a writable
 								 * connection. */
+	CONNECTION_CONSUME			/* Wait for any pending message and
+								 * consume them. */
 } ConnStatusType;
 
 typedef enum
-- 
GitLab