diff -rpcd a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c *** a/src/backend/postmaster/postmaster.c 2014-01-05 05:17:12.000000000 +0900 --- b/src/backend/postmaster/postmaster.c 2014-01-20 14:22:05.000000000 +0900 *************** *** 100,105 **** --- 100,106 ---- #include "libpq/ip.h" #include "libpq/libpq.h" #include "libpq/pqsignal.h" + #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" *************** ProcessStartupPacket(Port *port, bool SS *** 1742,1747 **** --- 1743,1750 ---- void *buf; ProtocolVersion proto; MemoryContext oldcontext; + const char *client_encoding = NULL; + int enc; if (pq_getbytes((char *) &len, 4) == EOF) { *************** retry1: *** 1912,1917 **** --- 1915,1922 ---- port->guc_options = lappend(port->guc_options, pstrdup(valptr)); } + if (strcmp(nameptr, "client_encoding") == 0) + client_encoding = valptr; offset = valoffset + strlen(valptr) + 1; } *************** retry1: *** 1946,1951 **** --- 1951,1966 ---- port->guc_options = NIL; } + /* + * If the client encoding is the same as the server, localize and send + * messages to the client in that encoding. + */ + if (client_encoding == NULL || client_encoding[0] == '\0') + client_encoding = GetConfigOption("client_encoding", true, false); + enc = pg_valid_client_encoding(client_encoding); + if (enc == pg_get_encoding_from_locale("", true)) + enable_message_localization(); + /* Check a user name was given. */ if (port->user_name == NULL || port->user_name[0] == '\0') ereport(FATAL, *************** BackendInitialize(Port *port) *** 3970,3975 **** --- 3985,3995 ---- enable_timeout_after(STARTUP_PACKET_TIMEOUT, AuthenticationTimeout * 1000); /* + * Output messages in English because client encoding is not known yet. + */ + disable_message_localization(); + + /* * Receive the startup packet (which might turn out to be a cancel request * packet). */ diff -rpcd a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c *** a/src/backend/utils/error/elog.c 2014-01-05 05:17:10.000000000 +0900 --- b/src/backend/utils/error/elog.c 2014-01-20 11:53:18.000000000 +0900 *************** static int errordata_stack_depth = -1; / *** 147,152 **** --- 147,154 ---- static int recursion_depth = 0; /* to detect actual recursion */ + static bool localize_message = true; + /* buffers for formatted timestamps that might be used by both * log_line_prefix and csv logs. */ *************** in_error_recursion_trouble(void) *** 197,202 **** --- 199,216 ---- return (recursion_depth > 2); } + void + enable_message_localization(void) + { + localize_message = true; + } + + void + disable_message_localization(void) + { + localize_message = false; + } + /* * One of those fallback steps is to stop trying to localize the error * message, since there's a significant probability that that's exactly *************** static inline const char * *** 206,212 **** err_gettext(const char *str) { #ifdef ENABLE_NLS ! if (in_error_recursion_trouble()) return str; else return gettext(str); --- 220,226 ---- err_gettext(const char *str) { #ifdef ENABLE_NLS ! if (!localize_message || in_error_recursion_trouble()) return str; else return gettext(str); *************** errcode_for_socket_access(void) *** 704,710 **** char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ ! if (translateit && !in_error_recursion_trouble()) \ fmt = dgettext((domain), fmt); \ /* Expand %m in format string */ \ fmtbuf = expand_fmt_string(fmt, edata); \ --- 718,724 ---- char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ ! if (translateit && localize_message && !in_error_recursion_trouble()) \ fmt = dgettext((domain), fmt); \ /* Expand %m in format string */ \ fmtbuf = expand_fmt_string(fmt, edata); \ *************** errcode_for_socket_access(void) *** 745,751 **** char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ ! if (!in_error_recursion_trouble()) \ fmt = dngettext((domain), fmt_singular, fmt_plural, n); \ else \ fmt = (n == 1 ? fmt_singular : fmt_plural); \ --- 759,765 ---- char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ ! if (localize_message && !in_error_recursion_trouble()) \ fmt = dngettext((domain), fmt_singular, fmt_plural, n); \ else \ fmt = (n == 1 ? fmt_singular : fmt_plural); \ diff -rpcd a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c *** a/src/backend/utils/init/postinit.c 2014-01-05 05:17:10.000000000 +0900 --- b/src/backend/utils/init/postinit.c 2014-01-20 11:53:18.000000000 +0900 *************** InitPostgres(const char *in_dbname, Oid *** 736,741 **** --- 736,744 ---- /* initialize client encoding */ InitializeClientEncoding(); + /* now that client encoding is known, localize later messages */ + enable_message_localization(); + /* report this backend in the PgBackendStatus array */ pgstat_bestart(); *************** InitPostgres(const char *in_dbname, Oid *** 913,918 **** --- 916,924 ---- /* initialize client encoding */ InitializeClientEncoding(); + /* now that client encoding is known, localize later messages */ + enable_message_localization(); + /* report this backend in the PgBackendStatus array */ if (!bootstrap) pgstat_bestart(); diff -rpcd a/src/include/utils/elog.h b/src/include/utils/elog.h *** a/src/include/utils/elog.h 2014-01-05 05:17:05.000000000 +0900 --- b/src/include/utils/elog.h 2014-01-20 11:53:18.000000000 +0900 *************** extern char *Log_destination_string; *** 440,445 **** --- 440,447 ---- extern void DebugFileOpen(void); extern char *unpack_sql_state(int sql_state); extern bool in_error_recursion_trouble(void); + extern void enable_message_localization(void); + extern void disable_message_localization(void); #ifdef HAVE_SYSLOG extern void set_syslog_parameters(const char *ident, int facility);