]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
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