Restructure libpq code to remove some duplicity
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 10 Sep 2019 15:13:29 +0000 (12:13 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 10 Sep 2019 15:14:24 +0000 (12:14 -0300)
There was some duplicate code to run SHOW transaction_read_only to
determine whether the server is read-write or read-only.  Reduce it by
adding another state to the state machine.

Author: Hari Babu Kommi
Reviewed-by: Takayuki Tsunakawa, Álvaro Herrera
Discussion: https://postgr.es/m/CAJrrPGe_qgdbbN+yBgEVpd+YLHXXjTruzk6RmTMhqrFig+32ag@mail.gmail.com

src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-fe.h

index f03d43376c5961fcd2224606aed7eb042c30ef47..8ba0159313cb826507e42552b6c3dcb42b454e7d 100644 (file)
@@ -170,7 +170,7 @@ typedef struct _internalPQconninfoOption
    char       *keyword;        /* The keyword of the option            */
    char       *envvar;         /* Fallback environment variable name   */
    char       *compiled;       /* Fallback compiled in default value   */
-   char       *val;            /* Option's current value, or NULL       */
+   char       *val;            /* Option's current value, or NULL      */
    char       *label;          /* Label for field in connect dialog    */
    char       *dispchar;       /* Indicates how to display this field in a
                                 * connect dialog. Values are: "" Display
@@ -3434,6 +3434,13 @@ keep_going:                      /* We will come back to here until there is
                    return PGRES_POLLING_WRITING;
                }
 
+               /* Almost there now ... */
+               conn->status = CONNECTION_CHECK_TARGET;
+               goto keep_going;
+           }
+
+       case CONNECTION_CHECK_TARGET:
+           {
                /*
                 * If a read-write connection is required, see if we have one.
                 *
@@ -3476,66 +3483,36 @@ keep_going:                     /* We will come back to here until there is
            }
 
        case CONNECTION_SETENV:
-
-           /*
-            * Do post-connection housekeeping (only needed in protocol 2.0).
-            *
-            * We pretend that the connection is OK for the duration of these
-            * queries.
-            */
-           conn->status = CONNECTION_OK;
-
-           switch (pqSetenvPoll(conn))
            {
-               case PGRES_POLLING_OK:  /* Success */
-                   break;
-
-               case PGRES_POLLING_READING: /* Still going */
-                   conn->status = CONNECTION_SETENV;
-                   return PGRES_POLLING_READING;
+               /*
+                * Do post-connection housekeeping (only needed in protocol 2.0).
+                *
+                * We pretend that the connection is OK for the duration of these
+                * queries.
+                */
+               conn->status = CONNECTION_OK;
 
-               case PGRES_POLLING_WRITING: /* Still going */
-                   conn->status = CONNECTION_SETENV;
-                   return PGRES_POLLING_WRITING;
+               switch (pqSetenvPoll(conn))
+               {
+                   case PGRES_POLLING_OK:  /* Success */
+                       break;
 
-               default:
-                   goto error_return;
-           }
+                   case PGRES_POLLING_READING: /* Still going */
+                       conn->status = CONNECTION_SETENV;
+                       return PGRES_POLLING_READING;
 
-           /*
-            * If a read-write connection is required, see if we have one.
-            * (This should match the stanza in the CONNECTION_AUTH_OK case
-            * above.)
-            *
-            * Servers before 7.4 lack the transaction_read_only GUC, but by
-            * the same token they don't have any read-only mode, so we may
-            * just skip the test in that case.
-            */
-           if (conn->sversion >= 70400 &&
-               conn->target_session_attrs != NULL &&
-               strcmp(conn->target_session_attrs, "read-write") == 0)
-           {
-               if (!saveErrorMessage(conn, &savedMessage))
-                   goto error_return;
+                   case PGRES_POLLING_WRITING: /* Still going */
+                       conn->status = CONNECTION_SETENV;
+                       return PGRES_POLLING_WRITING;
 
-               conn->status = CONNECTION_OK;
-               if (!PQsendQuery(conn,
-                                "SHOW transaction_read_only"))
-               {
-                   restoreErrorMessage(conn, &savedMessage);
-                   goto error_return;
+                   default:
+                       goto error_return;
                }
-               conn->status = CONNECTION_CHECK_WRITABLE;
-               restoreErrorMessage(conn, &savedMessage);
-               return PGRES_POLLING_READING;
-           }
-
-           /* We can release the address list now. */
-           release_conn_addrinfo(conn);
 
-           /* We are open for business! */
-           conn->status = CONNECTION_OK;
-           return PGRES_POLLING_OK;
+               /* Almost there now ... */
+               conn->status = CONNECTION_CHECK_TARGET;
+               goto keep_going;
+           }
 
        case CONNECTION_CONSUME:
            {
index 22c4954f2b71535c29721422348d6c3028723c92..5f65db30e4f3de723c86d37053ce308c43ab20b8 100644 (file)
@@ -67,7 +67,8 @@ typedef enum
                                 * connection. */
    CONNECTION_CONSUME,         /* Wait for any pending message and consume
                                 * them. */
-   CONNECTION_GSS_STARTUP      /* Negotiating GSSAPI. */
+   CONNECTION_GSS_STARTUP,     /* Negotiating GSSAPI. */
+   CONNECTION_CHECK_TARGET     /* Check if we have a proper target connection */
 } ConnStatusType;
 
 typedef enum