aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-exec.c')
-rw-r--r--src/interfaces/libpq/fe-exec.c53
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,