libpq: Make target_session_attrs=read-write consume empty result.
authorRobert Haas <rhaas@postgresql.org>
Wed, 15 Feb 2017 16:03:30 +0000 (11:03 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 15 Feb 2017 16:05:44 +0000 (11:05 -0500)
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
src/interfaces/libpq/libpq-fe.h

index c505b661c6b34b9e2f4a28f16cc4a821109014bd..65b7c31dc0303f447221b9eccb37ccd906103b51 100644 (file)
@@ -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;
                }
 
                /*
index 1b53d0ed16a85d11af39724a07dc974a8036848d..635af5b50e3bf3a8321672f8a910409950c09896 100644 (file)
@@ -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