Hello,

15.02.2013 02:59, Noah Misch wrote:
With your proposed change, the problem will resurface in an actual SQL_ASCII
database.  At the problem's root is write_console()'s assumption that messages
are in the database encoding.  pg_bind_textdomain_codeset() tries to make that
so, but it only works for encodings with a pg_enc2gettext_tbl entry.  That
excludes SQL_ASCII, MULE_INTERNAL, and others.  write_console() needs to
behave differently in such cases.
Thank you for the notice. So it seems that "DatabaseEncoding" variable
alone can't present a database encoding (for communication with a
client) and current process messages encoding (for logging messages) at
once. There should be another variable, something like
CurrentProcessEncoding, that will be set to OS encoding at start and can
be changed to encoding of a connected database (if
bind_textdomain_codeset succeeded).
I'd call it MessageEncoding unless it corresponds with similar rigor to a
broader concept.
Please look at the next version of the patch.

Thanks,
Alexander
>From 5bce21326d48761c6f86be8797432a69b2533dcd Mon Sep 17 00:00:00 2001
From: Alexander Lakhin <exclus...@gmail.com>
Date: Wed, 20 Feb 2013 15:34:05 +0400
Subject: Fix postmaster messages encoding

---
 src/backend/main/main.c        |    2 ++
 src/backend/utils/error/elog.c |    4 ++--
 src/backend/utils/mb/mbutils.c |   24 ++++++++++++++++++++++--
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 1173bda..ed4067e 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -100,6 +100,8 @@ main(int argc, char *argv[])
 
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
 
+	SetMessageEncoding(GetPlatformEncoding());
+
 #ifdef WIN32
 
 	/*
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 3a211bf..40f20f3 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -1868,7 +1868,7 @@ write_eventlog(int level, const char *line, int len)
 	 * Also verify that we are not on our way into error recursion trouble due
 	 * to error messages thrown deep inside pgwin32_toUTF16().
 	 */
-	if (GetDatabaseEncoding() != GetPlatformEncoding() &&
+	if (GetMessageEncoding() != GetPlatformEncoding() &&
 		!in_error_recursion_trouble())
 	{
 		utf16 = pgwin32_toUTF16(line, len, NULL);
@@ -1915,7 +1915,7 @@ write_console(const char *line, int len)
 	 * through to writing unconverted if we have not yet set up
 	 * CurrentMemoryContext.
 	 */
-	if (GetDatabaseEncoding() != GetPlatformEncoding() &&
+	if (GetMessageEncoding() != GetPlatformEncoding() &&
 		!in_error_recursion_trouble() &&
 		!redirection_done &&
 		CurrentMemoryContext != NULL)
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 287ff80..8b51b78 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -57,6 +57,7 @@ static FmgrInfo *ToClientConvProc = NULL;
  */
 static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
 static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+static pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
 static pg_enc2name *PlatformEncoding = NULL;
 
 /*
@@ -881,6 +882,16 @@ SetDatabaseEncoding(int encoding)
 	Assert(DatabaseEncoding->encoding == encoding);
 }
 
+void
+SetMessageEncoding(int encoding)
+{
+	if (!PG_VALID_BE_ENCODING(encoding))
+		elog(ERROR, "invalid message encoding: %d", encoding);
+
+	MessageEncoding = &pg_enc2name_tbl[encoding];
+	Assert(MessageEncoding->encoding == encoding);
+}
+
 /*
  * Bind gettext to the codeset equivalent with the database encoding.
  */
@@ -915,6 +926,8 @@ pg_bind_textdomain_codeset(const char *domainname)
 			if (bind_textdomain_codeset(domainname,
 										pg_enc2gettext_tbl[i].name) == NULL)
 				elog(LOG, "bind_textdomain_codeset failed");
+			else
+				SetMessageEncoding(encoding);
 			break;
 		}
 	}
@@ -964,6 +977,13 @@ GetPlatformEncoding(void)
 	return PlatformEncoding->encoding;
 }
 
+int
+GetMessageEncoding(void)
+{
+	Assert(MessageEncoding);
+	return MessageEncoding->encoding;
+}
+
 #ifdef WIN32
 
 /*
@@ -977,7 +997,7 @@ pgwin32_toUTF16(const char *str, int len, int *utf16len)
 	int			dstlen;
 	UINT		codepage;
 
-	codepage = pg_enc2name_tbl[GetDatabaseEncoding()].codepage;
+	codepage = pg_enc2name_tbl[GetMessageEncoding()].codepage;
 
 	/*
 	 * Use MultiByteToWideChar directly if there is a corresponding codepage,
@@ -994,7 +1014,7 @@ pgwin32_toUTF16(const char *str, int len, int *utf16len)
 		char	   *utf8;
 
 		utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
-										len, GetDatabaseEncoding(), PG_UTF8);
+										len, GetMessageEncoding(), PG_UTF8);
 		if (utf8 != str)
 			len = strlen(utf8);
 
-- 
1.7.10.4

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to