Commit e258a2b4 authored by Tom Lane's avatar Tom Lane

Fix libpq startup code to work correctly in autocommit off mode.

In passing, fix breakage for case where PGCLIENTENCODING is set in
environment.
parent 9ff695c9
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.209 2002/10/14 17:15:11 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.210 2002/10/15 01:48:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1583,8 +1583,6 @@ PQsetenvPoll(PGconn *conn) ...@@ -1583,8 +1583,6 @@ PQsetenvPoll(PGconn *conn)
{ {
PGresult *res; PGresult *res;
static const char envname[] = "PGCLIENTENCODING";
if (conn == NULL || conn->status == CONNECTION_BAD) if (conn == NULL || conn->status == CONNECTION_BAD)
return PGRES_POLLING_FAILED; return PGRES_POLLING_FAILED;
...@@ -1625,25 +1623,23 @@ PQsetenvPoll(PGconn *conn) ...@@ -1625,25 +1623,23 @@ PQsetenvPoll(PGconn *conn)
goto error_return; goto error_return;
} }
/* We will loop here until there is nothing left to do in this call. */
keep_going: /* We will come back to here until there for (;;)
* is nothing left to parse. */
switch (conn->setenv_state)
{ {
switch (conn->setenv_state)
case SETENV_STATE_ENCODINGS_SEND: {
case SETENV_STATE_ENCODINGS_SEND:
{ {
const char *env; const char *env = getenv("PGCLIENTENCODING");
env = getenv(envname);
if (!env || *env == '\0') if (!env || *env == '\0')
{ {
/* /*
* query server encoding if PGCLIENTENCODING is not * PGCLIENTENCODING is not specified, so query server
* specified * for it. We must use begin/commit in case autocommit
* is off by default.
*/ */
if (!PQsendQuery(conn, if (!PQsendQuery(conn, "begin; select getdatabaseencoding(); commit"))
"select getdatabaseencoding()"))
goto error_return; goto error_return;
conn->setenv_state = SETENV_STATE_ENCODINGS_WAIT; conn->setenv_state = SETENV_STATE_ENCODINGS_WAIT;
...@@ -1662,11 +1658,14 @@ keep_going: /* We will come back to here until there ...@@ -1662,11 +1658,14 @@ keep_going: /* We will come back to here until there
goto error_return; goto error_return;
} }
conn->client_encoding = encoding; conn->client_encoding = encoding;
}
/* Move on to setting the environment options */
conn->setenv_state = SETENV_STATE_OPTION_SEND;
}
break;
} }
case SETENV_STATE_ENCODINGS_WAIT: case SETENV_STATE_ENCODINGS_WAIT:
{ {
if (PQisBusy(conn)) if (PQisBusy(conn))
return PGRES_POLLING_READING; return PGRES_POLLING_READING;
...@@ -1675,37 +1674,35 @@ keep_going: /* We will come back to here until there ...@@ -1675,37 +1674,35 @@ keep_going: /* We will come back to here until there
if (res) if (res)
{ {
char *encoding; if (PQresultStatus(res) == PGRES_TUPLES_OK)
{
/* set client encoding in pg_conn struct */
char *encoding;
if (PQresultStatus(res) != PGRES_TUPLES_OK) encoding = PQgetvalue(res, 0, 0);
if (!encoding) /* this should not happen */
conn->client_encoding = PG_SQL_ASCII;
else
conn->client_encoding = pg_char_to_encoding(encoding);
}
else if (PQresultStatus(res) != PGRES_COMMAND_OK)
{ {
PQclear(res); PQclear(res);
goto error_return; goto error_return;
} }
/* set client encoding in pg_conn struct */
encoding = PQgetvalue(res, 0, 0);
if (!encoding) /* this should not happen */
conn->client_encoding = PG_SQL_ASCII;
else
conn->client_encoding = pg_char_to_encoding(encoding);
PQclear(res); PQclear(res);
/* Keep reading until PQgetResult returns NULL */
/*
* We have to keep going in order to clear up the
* query
*/
goto keep_going;
} }
else
/* NULL result indicates that the query is finished */ {
/* NULL result indicates that the query is finished */
/* Move on to setting the environment options */ /* Move on to setting the environment options */
conn->setenv_state = SETENV_STATE_OPTION_SEND; conn->setenv_state = SETENV_STATE_OPTION_SEND;
goto keep_going; }
break;
} }
case SETENV_STATE_OPTION_SEND: case SETENV_STATE_OPTION_SEND:
{ {
/* Send an Environment Option */ /* Send an Environment Option */
char setQuery[100]; /* note length limits in char setQuery[100]; /* note length limits in
...@@ -1740,11 +1737,10 @@ keep_going: /* We will come back to here until there ...@@ -1740,11 +1737,10 @@ keep_going: /* We will come back to here until there
/* No more options to send, so we are done. */ /* No more options to send, so we are done. */
conn->setenv_state = SETENV_STATE_IDLE; conn->setenv_state = SETENV_STATE_IDLE;
} }
break;
goto keep_going;
} }
case SETENV_STATE_OPTION_WAIT: case SETENV_STATE_OPTION_WAIT:
{ {
if (PQisBusy(conn)) if (PQisBusy(conn))
return PGRES_POLLING_READING; return PGRES_POLLING_READING;
...@@ -1758,33 +1754,29 @@ keep_going: /* We will come back to here until there ...@@ -1758,33 +1754,29 @@ keep_going: /* We will come back to here until there
PQclear(res); PQclear(res);
goto error_return; goto error_return;
} }
/* Don't need the result */
PQclear(res); PQclear(res);
/* Keep reading until PQgetResult returns NULL */
/*
* We have to keep going in order to clear up the
* query
*/
goto keep_going;
} }
else
/* NULL result indicates that the query is finished */ {
/* NULL result indicates that the query is finished */
/* Send the next option */ /* Send the next option */
conn->next_eo++; conn->next_eo++;
conn->setenv_state = SETENV_STATE_OPTION_SEND; conn->setenv_state = SETENV_STATE_OPTION_SEND;
goto keep_going; }
break;
} }
case SETENV_STATE_IDLE: case SETENV_STATE_IDLE:
return PGRES_POLLING_OK; return PGRES_POLLING_OK;
default: default:
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("invalid state %c, " libpq_gettext("invalid state %c, "
"probably indicative of memory corruption\n"), "probably indicative of memory corruption\n"),
conn->setenv_state); conn->setenv_state);
goto error_return; goto error_return;
}
} }
/* Unreachable */ /* Unreachable */
......
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