mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
In the continuing saga of FE/BE protocol revisions, add reporting of
initial values and runtime changes in selected parameters. This gets rid of the need for an initial 'select pg_client_encoding()' query in libpq, bringing us back to one message transmitted in each direction for a standard connection startup. To allow server version to be sent using the same GUC mechanism that handles other parameters, invent the concept of a never-settable GUC parameter: you can 'show server_version' but it's not settable by any GUC input source. Create 'lc_collate' and 'lc_ctype' never-settable parameters so that people can find out these settings without need for pg_controldata. (These side ideas were all discussed some time ago in pgsql-hackers, but not yet implemented.)
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.132 2003/04/25 01:24:00 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.133 2003/04/25 19:45:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -21,6 +21,8 @@
|
||||
#include "libpq-fe.h"
|
||||
#include "libpq-int.h"
|
||||
|
||||
#include "mb/pg_wchar.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "win32.h"
|
||||
#else
|
||||
@ -54,6 +56,7 @@ static void handleSendFailure(PGconn *conn);
|
||||
static void handleSyncLoss(PGconn *conn, char id, int msgLength);
|
||||
static int getRowDescriptions(PGconn *conn);
|
||||
static int getAnotherTuple(PGconn *conn, int binary);
|
||||
static int getParameterStatus(PGconn *conn);
|
||||
static int getNotify(PGconn *conn);
|
||||
|
||||
/* ---------------
|
||||
@ -950,6 +953,11 @@ parseInput(PGconn *conn)
|
||||
*
|
||||
* However, if the state is IDLE then we got trouble; we need to deal
|
||||
* with the unexpected message somehow.
|
||||
*
|
||||
* ParameterStatus ('S') messages are a special case: in IDLE state
|
||||
* we must process 'em (this case could happen if a new value was
|
||||
* adopted from config file due to SIGHUP), but otherwise we hold
|
||||
* off until BUSY state.
|
||||
*/
|
||||
if (id == 'A')
|
||||
{
|
||||
@ -970,6 +978,7 @@ parseInput(PGconn *conn)
|
||||
/*
|
||||
* Unexpected message in IDLE state; need to recover somehow.
|
||||
* ERROR messages are displayed using the notice processor;
|
||||
* ParameterStatus is handled normally;
|
||||
* anything else is just dropped on the floor after displaying
|
||||
* a suitable warning notice. (An ERROR is very possibly the
|
||||
* backend telling us why it is about to close the connection,
|
||||
@ -980,6 +989,11 @@ parseInput(PGconn *conn)
|
||||
if (pqGetErrorNotice(conn, false /* treat as notice */))
|
||||
return;
|
||||
}
|
||||
else if (id == 'S')
|
||||
{
|
||||
if (getParameterStatus(conn))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(noticeWorkspace, sizeof(noticeWorkspace),
|
||||
@ -1021,6 +1035,10 @@ parseInput(PGconn *conn)
|
||||
PGRES_EMPTY_QUERY);
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
break;
|
||||
case 'S': /* parameter status */
|
||||
if (getParameterStatus(conn))
|
||||
return;
|
||||
break;
|
||||
case 'K': /* secret key data from the backend */
|
||||
|
||||
/*
|
||||
@ -1671,6 +1689,35 @@ fail:
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to read a ParameterStatus message.
|
||||
* This is possible in several places, so we break it out as a subroutine.
|
||||
* Entry: 'S' message type and length have already been consumed.
|
||||
* Exit: returns 0 if successfully consumed message.
|
||||
* returns EOF if not enough data.
|
||||
*/
|
||||
static int
|
||||
getParameterStatus(PGconn *conn)
|
||||
{
|
||||
/* Get the parameter name */
|
||||
if (pqGets(&conn->workBuffer, conn))
|
||||
return EOF;
|
||||
/* Is it one we care about? */
|
||||
if (strcmp(conn->workBuffer.data, "client_encoding") == 0)
|
||||
{
|
||||
if (pqGets(&conn->workBuffer, conn))
|
||||
return EOF;
|
||||
conn->client_encoding = pg_char_to_encoding(conn->workBuffer.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Uninteresting parameter, ignore it */
|
||||
if (pqGets(&conn->workBuffer, conn))
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to read a Notify response message.
|
||||
* This is possible in several places, so we break it out as a subroutine.
|
||||
@ -2249,6 +2296,10 @@ PQfn(PGconn *conn,
|
||||
if (conn->result)
|
||||
return prepareAsyncResult(conn);
|
||||
return PQmakeEmptyPGresult(conn, status);
|
||||
case 'S': /* parameter status */
|
||||
if (getParameterStatus(conn))
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
|
Reference in New Issue
Block a user