diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-25 19:45:10 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-25 19:45:10 +0000 |
commit | 9cbaf7217747d6b5c88ba9b500a37b8372f185c9 (patch) | |
tree | 18569f5cba46f81d9097c9ea21c29f4a0e055936 /src/interfaces/libpq/fe-exec.c | |
parent | a2190c9eb6afc65fddb80667d48024428368a9b6 (diff) |
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.)
Diffstat (limited to 'src/interfaces/libpq/fe-exec.c')
-rw-r--r-- | src/interfaces/libpq/fe-exec.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 84520987812..53c4e288622 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -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 */ /* @@ -1672,6 +1690,35 @@ fail: } /* + * 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. * Entry: 'A' message type and length have already been consumed. @@ -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, |