Tell gettext which codeset to use by calling bind_textdomain_codeset(). We
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 8 Apr 2009 09:50:48 +0000 (09:50 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 8 Apr 2009 09:50:48 +0000 (09:50 +0000)
already did that on Windows, but it's needed on other platforms too when
LC_CTYPE=C. With other locales, we enforce (or trust) that the codeset of
the locale matches the server encoding so we don't need to bind it
explicitly. It should do no harm in that case either, but I don't have
full faith in the PG encoding -> OS codeset mapping table yet. Per recent
discussion on pgsql-hackers.

src/backend/utils/init/miscinit.c
src/backend/utils/init/postinit.c
src/backend/utils/mb/mbutils.c
src/include/mb/pg_wchar.h

index 30ecbd3779ef923bd76c548a63c8715586472aac..2fcb23628ddb68993365d3844e248f242dc95e2a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.173 2009/03/08 16:07:12 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.174 2009/04/08 09:50:48 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1242,7 +1242,7 @@ pg_bindtextdomain(const char *domain)
 
                get_locale_path(my_exec_path, locale_path);
                bindtextdomain(domain, locale_path);
-               pg_bind_textdomain_codeset(domain, GetDatabaseEncoding());
+               pg_bind_textdomain_codeset(domain);
        }
 #endif
 }
index 7f2cfdaea0c056ec4cd4cc9d72600fcf6fccfd83..44d7dc25247d3d39a6ba2c28226ebdd6b67c8624 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.188 2009/02/18 15:58:41 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.189 2009/04/08 09:50:48 heikki Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -265,6 +265,9 @@ CheckMyDatabase(const char *name, bool am_superuser)
        SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
        SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
 
+       /* Use the right encoding in translated messages */
+       pg_bind_textdomain_codeset(textdomain(NULL));
+
        /*
         * Lastly, set up any database-specific configuration variables.
         */
index 60c4576115650f40535dd7059c533af65eeacbe7..e1d1095cf5e9f4c44d89abb0ccc2110b6160e0d0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Tatsuo Ishii
  *
- * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.84 2009/04/06 19:34:52 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.85 2009/04/08 09:50:48 heikki Exp $
  */
 #include "postgres.h"
 
@@ -890,7 +890,7 @@ cliplen(const char *str, int len, int limit)
        return l;
 }
 
-#if defined(ENABLE_NLS) && defined(WIN32)
+#if defined(ENABLE_NLS)
 static const struct codeset_map {
        int     encoding;
        const char *codeset;
@@ -929,7 +929,7 @@ static const struct codeset_map {
        {PG_EUC_TW, "EUC-TW"},
        {PG_EUC_JIS_2004, "EUC-JP"}
 };
-#endif /* WIN32 */
+#endif /* ENABLE_NLS */
 
 void
 SetDatabaseEncoding(int encoding)
@@ -939,22 +939,36 @@ SetDatabaseEncoding(int encoding)
 
        DatabaseEncoding = &pg_enc2name_tbl[encoding];
        Assert(DatabaseEncoding->encoding == encoding);
-
-#ifdef ENABLE_NLS
-       pg_bind_textdomain_codeset(textdomain(NULL), encoding);
-#endif
 }
 
 /*
- * On Windows, we need to explicitly bind gettext to the correct
- * encoding, because gettext() tends to get confused.
+ * Bind gettext to the codeset equivalent with the database encoding.
  */
 void
-pg_bind_textdomain_codeset(const char *domainname, int encoding)
+pg_bind_textdomain_codeset(const char *domainname)
 {
-#if defined(ENABLE_NLS) && defined(WIN32)
+#if defined(ENABLE_NLS)
+       int             encoding = GetDatabaseEncoding();
        int     i;
 
+       /*
+        * gettext() uses the codeset specified by LC_CTYPE by default,
+        * so if that matches the database encoding we don't need to do
+        * anything. In CREATE DATABASE, we enforce or trust that the
+        * locale's codeset matches database encoding, except for the C
+        * locale. In C locale, we bind gettext() explicitly to the right
+        * codeset.
+        *
+        * On Windows, though, gettext() tends to get confused so we always
+        * bind it.
+        */
+#ifndef WIN32
+       const char *ctype = setlocale(LC_CTYPE, NULL);
+
+       if (pg_strcasecmp(ctype, "C") != 0 && pg_strcasecmp(ctype, "POSIX") != 0)
+               return;
+#endif
+
        for (i = 0; i < lengthof(codeset_map_array); i++)
        {
                if (codeset_map_array[i].encoding == encoding)
index 5b780db2a2deb1f2d42ac5d6db4fcf15daf02f7b..b7e1fe9c8182c866bf54a4f7191753ae633a86b1 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/mb/pg_wchar.h,v 1.88 2009/04/02 17:30:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/mb/pg_wchar.h,v 1.89 2009/04/08 09:50:48 heikki Exp $
  *
  *     NOTES
  *             This is used both by the backend and by libpq, but should not be
@@ -391,7 +391,7 @@ extern const char *pg_get_client_encoding_name(void);
 extern void SetDatabaseEncoding(int encoding);
 extern int     GetDatabaseEncoding(void);
 extern const char *GetDatabaseEncodingName(void);
-extern void pg_bind_textdomain_codeset(const char *domainname, int encoding);
+extern void pg_bind_textdomain_codeset(const char *domainname);
 
 extern int     pg_valid_client_encoding(const char *name);
 extern int     pg_valid_server_encoding(const char *name);