From 11bfb13dc89117d86644437eb53e1e6ba2d5d32b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 25 Apr 1999 21:50:58 +0000 Subject: [PATCH] Still had a few MULTIBYTE problems when client encoding was different from database's ... --- src/backend/libpq/pqformat.c | 31 ++++++++++++++++++++++++++++++- src/backend/tcop/dest.c | 4 ++-- src/backend/utils/error/elog.c | 4 ++-- src/include/libpq/pqformat.h | 2 ++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 2d2a1ab410..fc780340ea 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -21,7 +21,7 @@ */ /* * INTERFACE ROUTINES - * Message output: + * Message assembly and output: * pq_beginmessage - initialize StringInfo buffer * pq_sendbyte - append a raw byte to a StringInfo buffer * pq_sendint - append a binary integer to a StringInfo buffer @@ -33,6 +33,9 @@ * the regular StringInfo routines, but this is discouraged since required * MULTIBYTE conversion may not occur. * + * Special-case message output: + * pq_puttextmessage - generate a MULTIBYTE-converted message in one step + * * Message input: * pq_getint - get an integer from connection * pq_getstr - get a null terminated string from connection @@ -209,6 +212,32 @@ pq_endmessage(StringInfo buf) buf->data = NULL; } +/* -------------------------------- + * pq_puttextmessage - generate a MULTIBYTE-converted message in one step + * + * This is the same as the pqcomm.c routine pq_putmessage, except that + * the message body is a null-terminated string to which MULTIBYTE + * conversion applies. + * + * returns 0 if OK, EOF if trouble + * -------------------------------- + */ +int +pq_puttextmessage(char msgtype, const char *str) +{ + int slen = strlen(str); +#ifdef MULTIBYTE + const char *p; + p = (const char *) pg_server_to_client((unsigned char *) str, slen); + if (p != str) /* actual conversion has been done? */ + { + str = p; + slen = strlen(str); + } +#endif + return pq_putmessage(msgtype, str, slen+1); +} + /* -------------------------------- * pq_getint - get an integer from connection * diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index 9fe8c7c9ff..134a02a4b7 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -138,7 +138,7 @@ BeginCommand(char *pname, * send fe info on tuples we're about to send * ---------------- */ - pq_putmessage('P', pname, strlen(pname)+1); + pq_puttextmessage('P', pname); /* ---------------- * if this is a retrieve, then we send back the tuple @@ -272,7 +272,7 @@ EndCommand(char *commandTag, CommandDest dest) * ---------------- */ sprintf(buf, "%s%s", commandTag, CommandInfo); - pq_putmessage('C', buf, strlen(buf)+1); + pq_puttextmessage('C', buf); CommandInfo[0] = '\0'; break; diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 2516d5d11b..27c394fae2 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -31,6 +31,7 @@ #include "postgres.h" #include "miscadmin.h" #include "libpq/libpq.h" +#include "libpq/pqformat.h" #include "storage/proc.h" #include "tcop/tcopprot.h" #include "utils/trace.h" @@ -201,8 +202,7 @@ elog(int lev, const char *fmt,...) msgtype = 'E'; } /* exclude the timestamp from msg sent to frontend */ - pq_putmessage(msgtype, line + TIMESTAMP_SIZE, - strlen(line + TIMESTAMP_SIZE) + 1); + pq_puttextmessage(msgtype, line + TIMESTAMP_SIZE); /* * This flush is normally not necessary, since postgres.c will * flush out waiting data when control returns to the main loop. diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h index a657815aff..5d1f2dc77c 100644 --- a/src/include/libpq/pqformat.h +++ b/src/include/libpq/pqformat.h @@ -24,6 +24,8 @@ extern void pq_sendstring(StringInfo buf, const char *str); extern void pq_sendint(StringInfo buf, int i, int b); extern void pq_endmessage(StringInfo buf); +extern int pq_puttextmessage(char msgtype, const char *str); + extern int pq_getint(int *result, int b); extern int pq_getstr(char *s, int maxlen); -- 2.39.5