From: Tom Lane Date: Mon, 15 Dec 2025 20:16:26 +0000 (-0500) Subject: Avoid requiring Spanish locale to test NLS infrastructure. X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=7db6809ced4406257a80766e4109c8be8e1ea744;p=postgresql.git Avoid requiring Spanish locale to test NLS infrastructure. I had supposed that the majority of machines with gettext installed would have most language locales installed, but at least in the buildfarm it turns out less than half have es_ES installed. So depending on that to run the test now seems like a bad idea. But it turns out that gettext can be persuaded to "translate" even in the C locale, as long as you fake out its short-circuit logic by spelling the locale name like "C.UTF-8" or similar. (Many thanks to Bryan Green for correcting my misconceptions about that.) Quick testing suggests that that spelling is accepted by most platforms, though again the buildfarm may show that "most" isn't "all". Hence, remove the es_ES dependency and instead create a "C" message catalog. I've made the test unconditionally set lc_messages to 'C.UTF-8'. That approach might need adjustment depending on what the buildfarm shows, but let's keep it simple until proven wrong. While at it, tweak the test so that we run the various ereport's even when !ENABLE_NLS. This is useful to verify that the macros provided by are compatible with snprintf.c, as we now know is worth questioning. Discussion: https://postgr.es/m/1991599.1765818338@sss.pgh.pa.us --- diff --git a/src/test/regress/expected/nls.out b/src/test/regress/expected/nls.out index 2bc795fc822..924fbc72a26 100644 --- a/src/test/regress/expected/nls.out +++ b/src/test/regress/expected/nls.out @@ -6,50 +6,29 @@ 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 -\quit -\endif +-- 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'; SELECT test_translation(); -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 +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 test_translation ------------------ diff --git a/src/test/regress/expected/nls_1.out b/src/test/regress/expected/nls_1.out index 3117fa21ae0..031670a549d 100644 --- a/src/test/regress/expected/nls_1.out +++ b/src/test/regress/expected/nls_1.out @@ -6,35 +6,30 @@ 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 -\quit -\endif +-- 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'; 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 deleted file mode 100644 index cb8e4b59d16..00000000000 --- a/src/test/regress/expected/nls_2.out +++ /dev/null @@ -1,35 +0,0 @@ --- 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 new file mode 100644 index 00000000000..7df56ba2f3b --- /dev/null +++ b/src/test/regress/po/C.po @@ -0,0 +1,161 @@ +# 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 , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: regress (PostgreSQL) 19\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\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 \n" +"Language-Team: PG Hackers \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 = %" +msgstr "translated PRId64 = %" + +#: regress.c:1199 +#, c-format +msgid "untranslated PRId32 = %" +msgstr "translated PRId32 = %" + +#: regress.c:1201 +#, c-format +msgid "untranslated PRIdMAX = %" +msgstr "translated PRIdMAX = %" + +#: regress.c:1203 +#, c-format +msgid "untranslated PRIdPTR = %" +msgstr "translated PRIdPTR = %" + +#: regress.c:1206 +#, c-format +msgid "untranslated PRIu64 = %" +msgstr "translated PRIu64 = %" + +#: regress.c:1208 +#, c-format +msgid "untranslated PRIu32 = %" +msgstr "translated PRIu32 = %" + +#: regress.c:1210 +#, c-format +msgid "untranslated PRIuMAX = %" +msgstr "translated PRIuMAX = %" + +#: regress.c:1212 +#, c-format +msgid "untranslated PRIuPTR = %" +msgstr "translated PRIuPTR = %" + +#: regress.c:1215 +#, c-format +msgid "untranslated PRIx64 = %" +msgstr "translated PRIx64 = %" + +#: regress.c:1217 +#, c-format +msgid "untranslated PRIx32 = %" +msgstr "translated PRIx32 = %" + +#: regress.c:1219 +#, c-format +msgid "untranslated PRIxMAX = %" +msgstr "translated PRIxMAX = %" + +#: regress.c:1221 +#, c-format +msgid "untranslated PRIxPTR = %" +msgstr "translated PRIxPTR = %" + +#: regress.c:1224 +#, c-format +msgid "untranslated PRIX64 = %" +msgstr "translated PRIX64 = %" + +#: regress.c:1226 +#, c-format +msgid "untranslated PRIX32 = %" +msgstr "translated PRIX32 = %" + +#: regress.c:1228 +#, c-format +msgid "untranslated PRIXMAX = %" +msgstr "translated PRIXMAX = %" + +#: regress.c:1230 +#, c-format +msgid "untranslated PRIXPTR = %" +msgstr "translated PRIXPTR = %" diff --git a/src/test/regress/po/LINGUAS b/src/test/regress/po/LINGUAS index 8357fcaaed4..3cc58df8375 100644 --- a/src/test/regress/po/LINGUAS +++ b/src/test/regress/po/LINGUAS @@ -1 +1 @@ -es +C diff --git a/src/test/regress/po/es.po b/src/test/regress/po/es.po deleted file mode 100644 index b3021d57e22..00000000000 --- a/src/test/regress/po/es.po +++ /dev/null @@ -1,159 +0,0 @@ -# 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 , 2025. -# -msgid "" -msgstr "" -"Project-Id-Version: regress (PostgreSQL) 19\n" -"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\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 \n" -"Language-Team: PgSQL-es-Ayuda \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 = %" -msgstr "traducido PRId64 = %" - -#: regress.c:1177 -#, c-format -msgid "translated PRId32 = %" -msgstr "traducido PRId32 = %" - -#: regress.c:1179 -#, c-format -msgid "translated PRIdMAX = %" -msgstr "traducido PRIdMAX = %" - -#: regress.c:1181 -#, c-format -msgid "translated PRIdPTR = %" -msgstr "traducido PRIdPTR = %" - -#: regress.c:1184 -#, c-format -msgid "translated PRIu64 = %" -msgstr "traducido PRIu64 = %" - -#: regress.c:1186 -#, c-format -msgid "translated PRIu32 = %" -msgstr "traducido PRIu32 = %" - -#: regress.c:1188 -#, c-format -msgid "translated PRIuMAX = %" -msgstr "traducido PRIuMAX = %" - -#: regress.c:1190 -#, c-format -msgid "translated PRIuPTR = %" -msgstr "traducido PRIuPTR = %" - -#: regress.c:1193 -#, c-format -msgid "translated PRIx64 = %" -msgstr "traducido PRIx64 = %" - -#: regress.c:1195 -#, c-format -msgid "translated PRIx32 = %" -msgstr "traducido PRIx32 = %" - -#: regress.c:1197 -#, c-format -msgid "translated PRIxMAX = %" -msgstr "traducido PRIxMAX = %" - -#: regress.c:1199 -#, c-format -msgid "translated PRIxPTR = %" -msgstr "traducido PRIxPTR = %" - -#: regress.c:1202 -#, c-format -msgid "translated PRIX64 = %" -msgstr "traducido PRIX64 = %" - -#: regress.c:1204 -#, c-format -msgid "translated PRIX32 = %" -msgstr "traducido PRIX32 = %" - -#: regress.c:1206 -#, c-format -msgid "translated PRIXMAX = %" -msgstr "traducido PRIXMAX = %" - -#: regress.c:1208 -#, c-format -msgid "translated PRIXPTR = %" -msgstr "traducido PRIXPTR = %" diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 26ae0a6c787..9a84fccef39 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -1179,50 +1179,55 @@ test_translation(PG_FUNCTION_ARGS) * ensure that the nls.sql regression test will work. */ #if defined(__sun__) - setenv("LANGUAGE", "es_ES.UTF-8:es", 1); + setenv("LANGUAGE", "C.UTF-8:C", 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("translated PRId64 = %" PRId64, (int64) 424242424242)); + errmsg("untranslated PRId64 = %" PRId64, (int64) 424242424242)); ereport(NOTICE, - errmsg("translated PRId32 = %" PRId32, (int32) -1234)); + errmsg("untranslated PRId32 = %" PRId32, (int32) -1234)); ereport(NOTICE, - errmsg("translated PRIdMAX = %" PRIdMAX, (intmax_t) -5678)); + errmsg("untranslated PRIdMAX = %" PRIdMAX, (intmax_t) -123456789012)); ereport(NOTICE, - errmsg("translated PRIdPTR = %" PRIdPTR, (intptr_t) 9999)); + errmsg("untranslated PRIdPTR = %" PRIdPTR, (intptr_t) -9999)); ereport(NOTICE, - errmsg("translated PRIu64 = %" PRIu64, (uint64) 424242424242)); + errmsg("untranslated PRIu64 = %" PRIu64, (uint64) 424242424242)); ereport(NOTICE, - errmsg("translated PRIu32 = %" PRIu32, (uint32) 1234)); + errmsg("untranslated PRIu32 = %" PRIu32, (uint32) -1234)); ereport(NOTICE, - errmsg("translated PRIuMAX = %" PRIuMAX, (uintmax_t) 5678)); + errmsg("untranslated PRIuMAX = %" PRIuMAX, (uintmax_t) 123456789012)); ereport(NOTICE, - errmsg("translated PRIuPTR = %" PRIuPTR, (uintptr_t) 9999)); + errmsg("untranslated PRIuPTR = %" PRIuPTR, (uintptr_t) 9999)); ereport(NOTICE, - errmsg("translated PRIx64 = %" PRIx64, (uint64) 424242424242)); + errmsg("untranslated PRIx64 = %" PRIx64, (uint64) 424242424242)); ereport(NOTICE, - errmsg("translated PRIx32 = %" PRIx32, (uint32) 1234)); + errmsg("untranslated PRIx32 = %" PRIx32, (uint32) -1234)); ereport(NOTICE, - errmsg("translated PRIxMAX = %" PRIxMAX, (uintmax_t) 5678)); + errmsg("untranslated PRIxMAX = %" PRIxMAX, (uintmax_t) 123456789012)); ereport(NOTICE, - errmsg("translated PRIxPTR = %" PRIxPTR, (uintptr_t) 9999)); + errmsg("untranslated PRIxPTR = %" PRIxPTR, (uintptr_t) 9999)); ereport(NOTICE, - errmsg("translated PRIX64 = %" PRIX64, (uint64) 424242424242)); + errmsg("untranslated PRIX64 = %" PRIX64, (uint64) 424242424242)); ereport(NOTICE, - errmsg("translated PRIX32 = %" PRIX32, (uint32) 1234)); + errmsg("untranslated PRIX32 = %" PRIX32, (uint32) -1234)); ereport(NOTICE, - errmsg("translated PRIXMAX = %" PRIXMAX, (uintmax_t) 5678)); + errmsg("untranslated PRIXMAX = %" PRIXMAX, (uintmax_t) 123456789012)); ereport(NOTICE, - errmsg("translated PRIXPTR = %" PRIXPTR, (uintptr_t) 9999)); -#else - elog(NOTICE, "NLS is not enabled"); -#endif + errmsg("untranslated PRIXPTR = %" PRIXPTR, (uintptr_t) 9999)); PG_RETURN_VOID(); } diff --git a/src/test/regress/sql/nls.sql b/src/test/regress/sql/nls.sql index 9c605af2f0b..e9f2cc88e7f 100644 --- a/src/test/regress/sql/nls.sql +++ b/src/test/regress/sql/nls.sql @@ -9,35 +9,12 @@ CREATE FUNCTION test_translation() 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 -\quit -\endif +-- 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'; SELECT test_translation();