Revert "Avoid requiring Spanish locale to test NLS infrastructure."
authorTom Lane <[email protected]>
Mon, 15 Dec 2025 23:36:29 +0000 (18:36 -0500)
committerTom Lane <[email protected]>
Mon, 15 Dec 2025 23:36:29 +0000 (18:36 -0500)
This reverts commit 7db6809ced4406257a80766e4109c8be8e1ea744.
That doesn't seem to work with recent (last couple of years)
glibc, and the reasons are obscure.  I can't let the farm stay
this broken for long.

src/test/regress/expected/nls.out
src/test/regress/expected/nls_1.out
src/test/regress/expected/nls_2.out [new file with mode: 0644]
src/test/regress/po/C.po [deleted file]
src/test/regress/po/LINGUAS
src/test/regress/po/es.po [new file with mode: 0644]
src/test/regress/regress.c
src/test/regress/sql/nls.sql

index 924fbc72a26987e28f022a254d6d53daf4b0df49..2bc795fc822049b9ec1ace15f53cf805479bbffb 100644 (file)
@@ -6,29 +6,50 @@ CREATE FUNCTION test_translation()
     RETURNS void
     AS :'regresslib'
     LANGUAGE C;
--- We don't want to assume that the platform has any particular language
--- installed, so we use a "translation" for the C locale.  However, gettext
--- will short-circuit translation if lc_messages is just 'C'.  Fake it out
--- by appending a codeset name.  Fortunately it seems that that need not
--- match the actual database encoding.
-SET lc_messages = 'C.UTF-8';
+-- There's less standardization in locale name spellings than one could wish.
+-- While some platforms insist on having a codeset name in lc_messages,
+-- fortunately it seems that it need not match the actual database encoding.
+-- However, if no es_ES locale is installed at all, this'll fail.
+SET lc_messages = 'C';
+do $$
+declare locale text; ok bool;
+begin
+  for locale in values('es_ES'), ('es_ES.UTF-8'), ('es_ES.utf8')
+  loop
+    ok = true;
+    begin
+      execute format('set lc_messages = %L', locale);
+    exception when invalid_parameter_value then
+      ok = false;
+    end;
+    exit when ok;
+  end loop;
+  -- Don't clutter the expected results with this info, just log it
+  raise log 'NLS regression test: lc_messages = %',
+    current_setting('lc_messages');
+end $$;
+SELECT current_setting('lc_messages') = 'C' AS failed \gset
+\if :failed
+\echo Could not find an acceptable spelling of es_ES locale
+\quit
+\endif
 SELECT test_translation();
-NOTICE:  translated PRId64 = 424242424242
-NOTICE:  translated PRId32 = -1234
-NOTICE:  translated PRIdMAX = -123456789012
-NOTICE:  translated PRIdPTR = -9999
-NOTICE:  translated PRIu64 = 424242424242
-NOTICE:  translated PRIu32 = 4294966062
-NOTICE:  translated PRIuMAX = 123456789012
-NOTICE:  translated PRIuPTR = 9999
-NOTICE:  translated PRIx64 = 62c6d1a9b2
-NOTICE:  translated PRIx32 = fffffb2e
-NOTICE:  translated PRIxMAX = 1cbe991a14
-NOTICE:  translated PRIxPTR = 270f
-NOTICE:  translated PRIX64 = 62C6D1A9B2
-NOTICE:  translated PRIX32 = FFFFFB2E
-NOTICE:  translated PRIXMAX = 1CBE991A14
-NOTICE:  translated PRIXPTR = 270F
+NOTICE:  traducido PRId64 = 424242424242
+NOTICE:  traducido PRId32 = -1234
+NOTICE:  traducido PRIdMAX = -5678
+NOTICE:  traducido PRIdPTR = 9999
+NOTICE:  traducido PRIu64 = 424242424242
+NOTICE:  traducido PRIu32 = 1234
+NOTICE:  traducido PRIuMAX = 5678
+NOTICE:  traducido PRIuPTR = 9999
+NOTICE:  traducido PRIx64 = 62c6d1a9b2
+NOTICE:  traducido PRIx32 = 4d2
+NOTICE:  traducido PRIxMAX = 162e
+NOTICE:  traducido PRIxPTR = 270f
+NOTICE:  traducido PRIX64 = 62C6D1A9B2
+NOTICE:  traducido PRIX32 = 4D2
+NOTICE:  traducido PRIXMAX = 162E
+NOTICE:  traducido PRIXPTR = 270F
  test_translation 
 ------------------
  
index 031670a549d814bb57813dbd7a3898b52e09a5fd..3117fa21ae02d77632242e2d8af1262ce11b8037 100644 (file)
@@ -6,30 +6,35 @@ CREATE FUNCTION test_translation()
     RETURNS void
     AS :'regresslib'
     LANGUAGE C;
--- We don't want to assume that the platform has any particular language
--- installed, so we use a "translation" for the C locale.  However, gettext
--- will short-circuit translation if lc_messages is just 'C'.  Fake it out
--- by appending a codeset name.  Fortunately it seems that that need not
--- match the actual database encoding.
-SET lc_messages = 'C.UTF-8';
+-- There's less standardization in locale name spellings than one could wish.
+-- While some platforms insist on having a codeset name in lc_messages,
+-- fortunately it seems that it need not match the actual database encoding.
+-- However, if no es_ES locale is installed at all, this'll fail.
+SET lc_messages = 'C';
+do $$
+declare locale text; ok bool;
+begin
+  for locale in values('es_ES'), ('es_ES.UTF-8'), ('es_ES.utf8')
+  loop
+    ok = true;
+    begin
+      execute format('set lc_messages = %L', locale);
+    exception when invalid_parameter_value then
+      ok = false;
+    end;
+    exit when ok;
+  end loop;
+  -- Don't clutter the expected results with this info, just log it
+  raise log 'NLS regression test: lc_messages = %',
+    current_setting('lc_messages');
+end $$;
+SELECT current_setting('lc_messages') = 'C' AS failed \gset
+\if :failed
+\echo Could not find an acceptable spelling of es_ES locale
+\quit
+\endif
 SELECT test_translation();
 NOTICE:  NLS is not enabled
-NOTICE:  untranslated PRId64 = 424242424242
-NOTICE:  untranslated PRId32 = -1234
-NOTICE:  untranslated PRIdMAX = -123456789012
-NOTICE:  untranslated PRIdPTR = -9999
-NOTICE:  untranslated PRIu64 = 424242424242
-NOTICE:  untranslated PRIu32 = 4294966062
-NOTICE:  untranslated PRIuMAX = 123456789012
-NOTICE:  untranslated PRIuPTR = 9999
-NOTICE:  untranslated PRIx64 = 62c6d1a9b2
-NOTICE:  untranslated PRIx32 = fffffb2e
-NOTICE:  untranslated PRIxMAX = 1cbe991a14
-NOTICE:  untranslated PRIxPTR = 270f
-NOTICE:  untranslated PRIX64 = 62C6D1A9B2
-NOTICE:  untranslated PRIX32 = FFFFFB2E
-NOTICE:  untranslated PRIXMAX = 1CBE991A14
-NOTICE:  untranslated PRIXPTR = 270F
  test_translation 
 ------------------
  
diff --git a/src/test/regress/expected/nls_2.out b/src/test/regress/expected/nls_2.out
new file mode 100644 (file)
index 0000000..cb8e4b5
--- /dev/null
@@ -0,0 +1,35 @@
+-- directory paths and dlsuffix are passed to us in environment variables
+\getenv libdir PG_LIBDIR
+\getenv dlsuffix PG_DLSUFFIX
+\set regresslib :libdir '/regress' :dlsuffix
+CREATE FUNCTION test_translation()
+    RETURNS void
+    AS :'regresslib'
+    LANGUAGE C;
+-- There's less standardization in locale name spellings than one could wish.
+-- While some platforms insist on having a codeset name in lc_messages,
+-- fortunately it seems that it need not match the actual database encoding.
+-- However, if no es_ES locale is installed at all, this'll fail.
+SET lc_messages = 'C';
+do $$
+declare locale text; ok bool;
+begin
+  for locale in values('es_ES'), ('es_ES.UTF-8'), ('es_ES.utf8')
+  loop
+    ok = true;
+    begin
+      execute format('set lc_messages = %L', locale);
+    exception when invalid_parameter_value then
+      ok = false;
+    end;
+    exit when ok;
+  end loop;
+  -- Don't clutter the expected results with this info, just log it
+  raise log 'NLS regression test: lc_messages = %',
+    current_setting('lc_messages');
+end $$;
+SELECT current_setting('lc_messages') = 'C' AS failed \gset
+\if :failed
+\echo Could not find an acceptable spelling of es_ES locale
+Could not find an acceptable spelling of es_ES locale
+\quit
diff --git a/src/test/regress/po/C.po b/src/test/regress/po/C.po
deleted file mode 100644 (file)
index 7df56ba..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-# C message translation file for regress test library
-#
-# Note that we don't need translation of this library into non-English.
-#
-# Copyright (C) 2025 PostgreSQL Global Development Group
-# This file is distributed under the same license as the regress (PostgreSQL) package.
-#
-# Tom Lane <[email protected]>, 2025.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: regress (PostgreSQL) 19\n"
-"Report-Msgid-Bugs-To: [email protected]\n"
-"POT-Creation-Date: 2025-12-15 14:28-0500\n"
-"PO-Revision-Date: 2025-12-15 14:28-0500\n"
-"Last-Translator: Tom Lane <[email protected]>\n"
-"Language-Team: PG Hackers <[email protected]>\n"
-"Language: C\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: regress.c:202
-#, c-format
-msgid "invalid input syntax for type %s: \"%s\""
-msgstr ""
-
-#: regress.c:839
-#, c-format
-msgid "test_inline_in_from_support_func called with %d args but expected 3"
-msgstr ""
-
-#: regress.c:847 regress.c:863
-#, c-format
-msgid "test_inline_in_from_support_func called with non-Const parameters"
-msgstr ""
-
-#: regress.c:854 regress.c:870
-#, c-format
-msgid "test_inline_in_from_support_func called with non-TEXT parameters"
-msgstr ""
-
-#: regress.c:903
-#, c-format
-msgid "test_inline_in_from_support_func parsed to more than one node"
-msgstr ""
-
-#: regress.c:914
-#, c-format
-msgid "test_inline_in_from_support_func rewrote to more than one node"
-msgstr ""
-
-#: regress.c:921
-#, c-format
-msgid "test_inline_in_from_support_func didn't parse to a Query"
-msgstr ""
-
-#: regress.c:1028
-#, c-format
-msgid "invalid source encoding name \"%s\""
-msgstr ""
-
-#: regress.c:1033
-#, c-format
-msgid "invalid destination encoding name \"%s\""
-msgstr ""
-
-#: regress.c:1078
-#, c-format
-msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist"
-msgstr ""
-
-#: regress.c:1085
-#, c-format
-msgid "out of memory"
-msgstr ""
-
-#: regress.c:1086
-#, c-format
-msgid "String of %d bytes is too long for encoding conversion."
-msgstr ""
-
-#: regress.c:1197
-#, c-format
-msgid "untranslated PRId64 = %<PRId64>"
-msgstr "translated PRId64 = %<PRId64>"
-
-#: regress.c:1199
-#, c-format
-msgid "untranslated PRId32 = %<PRId32>"
-msgstr "translated PRId32 = %<PRId32>"
-
-#: regress.c:1201
-#, c-format
-msgid "untranslated PRIdMAX = %<PRIdMAX>"
-msgstr "translated PRIdMAX = %<PRIdMAX>"
-
-#: regress.c:1203
-#, c-format
-msgid "untranslated PRIdPTR = %<PRIdPTR>"
-msgstr "translated PRIdPTR = %<PRIdPTR>"
-
-#: regress.c:1206
-#, c-format
-msgid "untranslated PRIu64 = %<PRIu64>"
-msgstr "translated PRIu64 = %<PRIu64>"
-
-#: regress.c:1208
-#, c-format
-msgid "untranslated PRIu32 = %<PRIu32>"
-msgstr "translated PRIu32 = %<PRIu32>"
-
-#: regress.c:1210
-#, c-format
-msgid "untranslated PRIuMAX = %<PRIuMAX>"
-msgstr "translated PRIuMAX = %<PRIuMAX>"
-
-#: regress.c:1212
-#, c-format
-msgid "untranslated PRIuPTR = %<PRIuPTR>"
-msgstr "translated PRIuPTR = %<PRIuPTR>"
-
-#: regress.c:1215
-#, c-format
-msgid "untranslated PRIx64 = %<PRIx64>"
-msgstr "translated PRIx64 = %<PRIx64>"
-
-#: regress.c:1217
-#, c-format
-msgid "untranslated PRIx32 = %<PRIx32>"
-msgstr "translated PRIx32 = %<PRIx32>"
-
-#: regress.c:1219
-#, c-format
-msgid "untranslated PRIxMAX = %<PRIxMAX>"
-msgstr "translated PRIxMAX = %<PRIxMAX>"
-
-#: regress.c:1221
-#, c-format
-msgid "untranslated PRIxPTR = %<PRIxPTR>"
-msgstr "translated PRIxPTR = %<PRIxPTR>"
-
-#: regress.c:1224
-#, c-format
-msgid "untranslated PRIX64 = %<PRIX64>"
-msgstr "translated PRIX64 = %<PRIX64>"
-
-#: regress.c:1226
-#, c-format
-msgid "untranslated PRIX32 = %<PRIX32>"
-msgstr "translated PRIX32 = %<PRIX32>"
-
-#: regress.c:1228
-#, c-format
-msgid "untranslated PRIXMAX = %<PRIXMAX>"
-msgstr "translated PRIXMAX = %<PRIXMAX>"
-
-#: regress.c:1230
-#, c-format
-msgid "untranslated PRIXPTR = %<PRIXPTR>"
-msgstr "translated PRIXPTR = %<PRIXPTR>"
index 3cc58df83752123644fef39faab2393af643b1d2..8357fcaaed4bec66c5974a26f788cebb964b280d 100644 (file)
@@ -1 +1 @@
-C
+es
diff --git a/src/test/regress/po/es.po b/src/test/regress/po/es.po
new file mode 100644 (file)
index 0000000..b3021d5
--- /dev/null
@@ -0,0 +1,159 @@
+# Spanish message translation file for regress test library
+#
+# Copyright (C) 2025 PostgreSQL Global Development Group
+# This file is distributed under the same license as the regress (PostgreSQL) package.
+#
+# Tom Lane <[email protected]>, 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: regress (PostgreSQL) 19\n"
+"Report-Msgid-Bugs-To: [email protected]\n"
+"POT-Creation-Date: 2025-12-08 13:57-0500\n"
+"PO-Revision-Date: 2025-11-19 19:01-0500\n"
+"Last-Translator: Tom Lane <[email protected]>\n"
+"Language-Team: PgSQL-es-Ayuda <[email protected]>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: regress.c:202
+#, c-format
+msgid "invalid input syntax for type %s: \"%s\""
+msgstr "la sintaxis de entrada no es válida para tipo %s: «%s»"
+
+#: regress.c:839
+#, c-format
+msgid "test_inline_in_from_support_func called with %d args but expected 3"
+msgstr ""
+
+#: regress.c:847 regress.c:863
+#, c-format
+msgid "test_inline_in_from_support_func called with non-Const parameters"
+msgstr ""
+
+#: regress.c:854 regress.c:870
+#, c-format
+msgid "test_inline_in_from_support_func called with non-TEXT parameters"
+msgstr ""
+
+#: regress.c:903
+#, c-format
+msgid "test_inline_in_from_support_func parsed to more than one node"
+msgstr ""
+
+#: regress.c:914
+#, c-format
+msgid "test_inline_in_from_support_func rewrote to more than one node"
+msgstr ""
+
+#: regress.c:921
+#, c-format
+msgid "test_inline_in_from_support_func didn't parse to a Query"
+msgstr ""
+
+#: regress.c:1028
+#, c-format
+msgid "invalid source encoding name \"%s\""
+msgstr "la codificación de origen «%s» no es válida"
+
+#: regress.c:1033
+#, c-format
+msgid "invalid destination encoding name \"%s\""
+msgstr "la codificación de destino «%s» no es válida"
+
+#: regress.c:1078
+#, c-format
+msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist"
+msgstr "no existe el procedimiento por omisión de conversión desde la codificación «%s» a «%s»"
+
+#: regress.c:1085
+#, c-format
+msgid "out of memory"
+msgstr "memoria agotada"
+
+#: regress.c:1086
+#, c-format
+msgid "String of %d bytes is too long for encoding conversion."
+msgstr "La cadena de %d bytes es demasiado larga para la recodificación."
+
+#: regress.c:1175
+#, c-format
+msgid "translated PRId64 = %<PRId64>"
+msgstr "traducido PRId64 = %<PRId64>"
+
+#: regress.c:1177
+#, c-format
+msgid "translated PRId32 = %<PRId32>"
+msgstr "traducido PRId32 = %<PRId32>"
+
+#: regress.c:1179
+#, c-format
+msgid "translated PRIdMAX = %<PRIdMAX>"
+msgstr "traducido PRIdMAX = %<PRIdMAX>"
+
+#: regress.c:1181
+#, c-format
+msgid "translated PRIdPTR = %<PRIdPTR>"
+msgstr "traducido PRIdPTR = %<PRIdPTR>"
+
+#: regress.c:1184
+#, c-format
+msgid "translated PRIu64 = %<PRIu64>"
+msgstr "traducido PRIu64 = %<PRIu64>"
+
+#: regress.c:1186
+#, c-format
+msgid "translated PRIu32 = %<PRIu32>"
+msgstr "traducido PRIu32 = %<PRIu32>"
+
+#: regress.c:1188
+#, c-format
+msgid "translated PRIuMAX = %<PRIuMAX>"
+msgstr "traducido PRIuMAX = %<PRIuMAX>"
+
+#: regress.c:1190
+#, c-format
+msgid "translated PRIuPTR = %<PRIuPTR>"
+msgstr "traducido PRIuPTR = %<PRIuPTR>"
+
+#: regress.c:1193
+#, c-format
+msgid "translated PRIx64 = %<PRIx64>"
+msgstr "traducido PRIx64 = %<PRIx64>"
+
+#: regress.c:1195
+#, c-format
+msgid "translated PRIx32 = %<PRIx32>"
+msgstr "traducido PRIx32 = %<PRIx32>"
+
+#: regress.c:1197
+#, c-format
+msgid "translated PRIxMAX = %<PRIxMAX>"
+msgstr "traducido PRIxMAX = %<PRIxMAX>"
+
+#: regress.c:1199
+#, c-format
+msgid "translated PRIxPTR = %<PRIxPTR>"
+msgstr "traducido PRIxPTR = %<PRIxPTR>"
+
+#: regress.c:1202
+#, c-format
+msgid "translated PRIX64 = %<PRIX64>"
+msgstr "traducido PRIX64 = %<PRIX64>"
+
+#: regress.c:1204
+#, c-format
+msgid "translated PRIX32 = %<PRIX32>"
+msgstr "traducido PRIX32 = %<PRIX32>"
+
+#: regress.c:1206
+#, c-format
+msgid "translated PRIXMAX = %<PRIXMAX>"
+msgstr "traducido PRIXMAX = %<PRIXMAX>"
+
+#: regress.c:1208
+#, c-format
+msgid "translated PRIXPTR = %<PRIXPTR>"
+msgstr "traducido PRIXPTR = %<PRIXPTR>"
index 9a84fccef395b854486eb880e4a958c533dba218..26ae0a6c78785d48aa5ca7e6dbbd47e48e71ef88 100644 (file)
@@ -1179,55 +1179,50 @@ test_translation(PG_FUNCTION_ARGS)
         * ensure that the nls.sql regression test will work.
         */
 #if defined(__sun__)
-       setenv("LANGUAGE", "C.UTF-8:C", 1);
+       setenv("LANGUAGE", "es_ES.UTF-8:es", 1);
 #endif
        pg_bindtextdomain(TEXTDOMAIN);
        inited = true;
    }
-#else
-   elog(NOTICE, "NLS is not enabled");
-
-   /*
-    * In non-NLS builds, we still run the ereport calls, to verify that the
-    * platform's PRI* macros are compatible with snprintf.c.
-    */
-#endif
 
    ereport(NOTICE,
-           errmsg("untranslated PRId64 = %" PRId64, (int64) 424242424242));
+           errmsg("translated PRId64 = %" PRId64, (int64) 424242424242));
    ereport(NOTICE,
-           errmsg("untranslated PRId32 = %" PRId32, (int32) -1234));
+           errmsg("translated PRId32 = %" PRId32, (int32) -1234));
    ereport(NOTICE,
-           errmsg("untranslated PRIdMAX = %" PRIdMAX, (intmax_t) -123456789012));
+           errmsg("translated PRIdMAX = %" PRIdMAX, (intmax_t) -5678));
    ereport(NOTICE,
-           errmsg("untranslated PRIdPTR = %" PRIdPTR, (intptr_t) -9999));
+           errmsg("translated PRIdPTR = %" PRIdPTR, (intptr_t) 9999));
 
    ereport(NOTICE,
-           errmsg("untranslated PRIu64 = %" PRIu64, (uint64) 424242424242));
+           errmsg("translated PRIu64 = %" PRIu64, (uint64) 424242424242));
    ereport(NOTICE,
-           errmsg("untranslated PRIu32 = %" PRIu32, (uint32) -1234));
+           errmsg("translated PRIu32 = %" PRIu32, (uint32) 1234));
    ereport(NOTICE,
-           errmsg("untranslated PRIuMAX = %" PRIuMAX, (uintmax_t) 123456789012));
+           errmsg("translated PRIuMAX = %" PRIuMAX, (uintmax_t) 5678));
    ereport(NOTICE,
-           errmsg("untranslated PRIuPTR = %" PRIuPTR, (uintptr_t) 9999));
+           errmsg("translated PRIuPTR = %" PRIuPTR, (uintptr_t) 9999));
 
    ereport(NOTICE,
-           errmsg("untranslated PRIx64 = %" PRIx64, (uint64) 424242424242));
+           errmsg("translated PRIx64 = %" PRIx64, (uint64) 424242424242));
    ereport(NOTICE,
-           errmsg("untranslated PRIx32 = %" PRIx32, (uint32) -1234));
+           errmsg("translated PRIx32 = %" PRIx32, (uint32) 1234));
    ereport(NOTICE,
-           errmsg("untranslated PRIxMAX = %" PRIxMAX, (uintmax_t) 123456789012));
+           errmsg("translated PRIxMAX = %" PRIxMAX, (uintmax_t) 5678));
    ereport(NOTICE,
-           errmsg("untranslated PRIxPTR = %" PRIxPTR, (uintptr_t) 9999));
+           errmsg("translated PRIxPTR = %" PRIxPTR, (uintptr_t) 9999));
 
    ereport(NOTICE,
-           errmsg("untranslated PRIX64 = %" PRIX64, (uint64) 424242424242));
+           errmsg("translated PRIX64 = %" PRIX64, (uint64) 424242424242));
    ereport(NOTICE,
-           errmsg("untranslated PRIX32 = %" PRIX32, (uint32) -1234));
+           errmsg("translated PRIX32 = %" PRIX32, (uint32) 1234));
    ereport(NOTICE,
-           errmsg("untranslated PRIXMAX = %" PRIXMAX, (uintmax_t) 123456789012));
+           errmsg("translated PRIXMAX = %" PRIXMAX, (uintmax_t) 5678));
    ereport(NOTICE,
-           errmsg("untranslated PRIXPTR = %" PRIXPTR, (uintptr_t) 9999));
+           errmsg("translated PRIXPTR = %" PRIXPTR, (uintptr_t) 9999));
+#else
+   elog(NOTICE, "NLS is not enabled");
+#endif
 
    PG_RETURN_VOID();
 }
index e9f2cc88e7f358dfd5d35812fb977eeb32ba65f0..9c605af2f0ba58039765d0da2cc958bf2be0215d 100644 (file)
@@ -9,12 +9,35 @@ CREATE FUNCTION test_translation()
     AS :'regresslib'
     LANGUAGE C;
 
--- We don't want to assume that the platform has any particular language
--- installed, so we use a "translation" for the C locale.  However, gettext
--- will short-circuit translation if lc_messages is just 'C'.  Fake it out
--- by appending a codeset name.  Fortunately it seems that that need not
--- match the actual database encoding.
-SET lc_messages = 'C.UTF-8';
+-- There's less standardization in locale name spellings than one could wish.
+-- While some platforms insist on having a codeset name in lc_messages,
+-- fortunately it seems that it need not match the actual database encoding.
+-- However, if no es_ES locale is installed at all, this'll fail.
+SET lc_messages = 'C';
+
+do $$
+declare locale text; ok bool;
+begin
+  for locale in values('es_ES'), ('es_ES.UTF-8'), ('es_ES.utf8')
+  loop
+    ok = true;
+    begin
+      execute format('set lc_messages = %L', locale);
+    exception when invalid_parameter_value then
+      ok = false;
+    end;
+    exit when ok;
+  end loop;
+  -- Don't clutter the expected results with this info, just log it
+  raise log 'NLS regression test: lc_messages = %',
+    current_setting('lc_messages');
+end $$;
+
+SELECT current_setting('lc_messages') = 'C' AS failed \gset
+\if :failed
+\echo Could not find an acceptable spelling of es_ES locale
+\quit
+\endif
 
 SELECT test_translation();