mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
Fix libpq startup code to work correctly in autocommit off mode.
In passing, fix breakage for case where PGCLIENTENCODING is set in environment.
This commit is contained in:
parent
9ff695c944
commit
e258a2b436
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
|
|
||||||
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
|
|||||||
/* 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
|
|||||||
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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user