Commit b438e7e7 authored by Alvaro Herrera's avatar Alvaro Herrera

Restructure libpq code to remove some duplicity

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
parent 55d015bd
...@@ -170,7 +170,7 @@ typedef struct _internalPQconninfoOption ...@@ -170,7 +170,7 @@ typedef struct _internalPQconninfoOption
char *keyword; /* The keyword of the option */ char *keyword; /* The keyword of the option */
char *envvar; /* Fallback environment variable name */ char *envvar; /* Fallback environment variable name */
char *compiled; /* Fallback compiled in default value */ 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 *label; /* Label for field in connect dialog */
char *dispchar; /* Indicates how to display this field in a char *dispchar; /* Indicates how to display this field in a
* connect dialog. Values are: "" Display * connect dialog. Values are: "" Display
...@@ -3434,6 +3434,13 @@ keep_going: /* We will come back to here until there is ...@@ -3434,6 +3434,13 @@ keep_going: /* We will come back to here until there is
return PGRES_POLLING_WRITING; 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. * 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 ...@@ -3476,66 +3483,36 @@ keep_going: /* We will come back to here until there is
} }
case CONNECTION_SETENV: 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; * Do post-connection housekeeping (only needed in protocol 2.0).
*
case PGRES_POLLING_READING: /* Still going */ * We pretend that the connection is OK for the duration of these
conn->status = CONNECTION_SETENV; * queries.
return PGRES_POLLING_READING; */
conn->status = CONNECTION_OK;
case PGRES_POLLING_WRITING: /* Still going */ switch (pqSetenvPoll(conn))
conn->status = CONNECTION_SETENV; {
return PGRES_POLLING_WRITING; case PGRES_POLLING_OK: /* Success */
break;
default: case PGRES_POLLING_READING: /* Still going */
goto error_return; conn->status = CONNECTION_SETENV;
} return PGRES_POLLING_READING;
/* case PGRES_POLLING_WRITING: /* Still going */
* If a read-write connection is required, see if we have one. conn->status = CONNECTION_SETENV;
* (This should match the stanza in the CONNECTION_AUTH_OK case return PGRES_POLLING_WRITING;
* 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;
conn->status = CONNECTION_OK; default:
if (!PQsendQuery(conn, goto error_return;
"SHOW transaction_read_only"))
{
restoreErrorMessage(conn, &savedMessage);
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! */ /* Almost there now ... */
conn->status = CONNECTION_OK; conn->status = CONNECTION_CHECK_TARGET;
return PGRES_POLLING_OK; goto keep_going;
}
case CONNECTION_CONSUME: case CONNECTION_CONSUME:
{ {
......
...@@ -67,7 +67,8 @@ typedef enum ...@@ -67,7 +67,8 @@ typedef enum
* connection. */ * connection. */
CONNECTION_CONSUME, /* Wait for any pending message and consume CONNECTION_CONSUME, /* Wait for any pending message and consume
* them. */ * them. */
CONNECTION_GSS_STARTUP /* Negotiating GSSAPI. */ CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */
CONNECTION_CHECK_TARGET /* Check if we have a proper target connection */
} ConnStatusType; } ConnStatusType;
typedef enum typedef enum
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment