From b438e7e7a1c58e0c20b5f46e73cbd713e8033c69 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 10 Sep 2019 12:13:29 -0300 Subject: [PATCH] Restructure libpq code to remove some duplicity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 89 ++++++++++++------------------- src/interfaces/libpq/libpq-fe.h | 3 +- 2 files changed, 35 insertions(+), 57 deletions(-) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index f03d43376c5..8ba0159313c 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -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,67 +3483,37 @@ 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; - - case PGRES_POLLING_WRITING: /* Still going */ - conn->status = CONNECTION_SETENV; - return PGRES_POLLING_WRITING; - - default: - goto error_return; - } - - /* - * 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; - + /* + * 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; - if (!PQsendQuery(conn, - "SHOW transaction_read_only")) + + switch (pqSetenvPoll(conn)) { - restoreErrorMessage(conn, &savedMessage); - goto error_return; + case PGRES_POLLING_OK: /* Success */ + break; + + case PGRES_POLLING_READING: /* Still going */ + conn->status = CONNECTION_SETENV; + return PGRES_POLLING_READING; + + case PGRES_POLLING_WRITING: /* Still going */ + conn->status = CONNECTION_SETENV; + return PGRES_POLLING_WRITING; + + default: + goto error_return; } - conn->status = CONNECTION_CHECK_WRITABLE; - restoreErrorMessage(conn, &savedMessage); - return PGRES_POLLING_READING; + + /* Almost there now ... */ + conn->status = CONNECTION_CHECK_TARGET; + goto keep_going; } - /* We can release the address list now. */ - release_conn_addrinfo(conn); - - /* We are open for business! */ - conn->status = CONNECTION_OK; - return PGRES_POLLING_OK; - case CONNECTION_CONSUME: { conn->status = CONNECTION_OK; diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index 22c4954f2b7..5f65db30e4f 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -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