From 122923c97febe794796ede5c9a35d6c317bcde30 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
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   | 33 +++++++++++++++++++++++++++++++--
 src/backend/tcop/dest.c        |  6 +++---
 src/backend/utils/error/elog.c |  6 +++---
 src/include/libpq/pqformat.h   |  4 +++-
 4 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c
index ad6f045a944..45b4259d8b9 100644
--- a/src/backend/libpq/pqformat.c
+++ b/src/backend/libpq/pqformat.c
@@ -15,13 +15,13 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *  $Id: pqformat.c,v 1.2 1999/04/25 19:27:44 tgl Exp $
+ *  $Id: pqformat.c,v 1.3 1999/04/25 21:50:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 /*
  * 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 26e04f5f855..ded755a3547 100644
--- a/src/backend/tcop/dest.c
+++ b/src/backend/tcop/dest.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.27 1999/04/25 19:27:45 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.28 1999/04/25 21:50:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 096cd093443..eea197d3469 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.42 1999/04/25 03:19:11 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.43 1999/04/25 21:50:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 6404583a103..b546c36c5e7 100644
--- a/src/include/libpq/pqformat.h
+++ b/src/include/libpq/pqformat.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqformat.h,v 1.2 1999/04/25 19:27:47 tgl Exp $
+ * $Id: pqformat.h,v 1.3 1999/04/25 21:50:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);
 
-- 
GitLab