diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 30ecbd3779ef923bd76c548a63c8715586472aac..2fcb23628ddb68993365d3844e248f242dc95e2a 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -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
 }
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 7f2cfdaea0c056ec4cd4cc9d72600fcf6fccfd83..44d7dc25247d3d39a6ba2c28226ebdd6b67c8624 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -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.
 	 */
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 60c4576115650f40535dd7059c533af65eeacbe7..e1d1095cf5e9f4c44d89abb0ccc2110b6160e0d0 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -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)
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 5b780db2a2deb1f2d42ac5d6db4fcf15daf02f7b..b7e1fe9c8182c866bf54a4f7191753ae633a86b1 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -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);