I wrote:
> I agree with the idea of just using a single test message that checks
> all the PRI* macros we care about. I don't think we need to invent a
> whole new translation for this. I'd be inclined to just get the
> desired translated string pushed into one or two .po files in HEAD,
> then we can start testing with those specific languages, and we're
> good. Over time the translators would presumably get translations
> into other .po files, and then maybe we'd want to expand the set of
> tested languages, or maybe that wouldn't really buy much. (Managing
> the encoding of the expected-file might be tricky if you got too
> ambitious about that.)
Just as proof-of-concept, this is approximately what I think we
should do to begin with.
The main thing that's likely wrong here is that I just manually
shoved a new entry into src/backend/po/es.po. I suspect that
the .po-extraction machinery would fail to pick up that string
because it's in src/test/regress/regress.c. We could hack it
to do that, or we could put the test function into some backend
file. I don't have much sense of which would be cleaner.
Lesser loose ends: I didn't bother fleshing out the test message
to cover all of the likely PRI* cases, and my Spanish probably
sucks. I'm also unsure if this will work as-is on Windows;
are the LC_MESSAGES settings the same there?
regards, tom lane
From 3f89fb8f0070a35e26e35eb63fe54caea647a4ec Mon Sep 17 00:00:00 2001
From: Tom Lane <[email protected]>
Date: Wed, 19 Nov 2025 17:16:04 -0500
Subject: [PATCH v1] Simple test of NLS translation.
This is just intended to verify minimal functionality of the
NLS message-translation system, and in particular to check that
the PRI* macros work.
---
src/backend/po/es.po | 5 +++++
src/test/regress/expected/nls.out | 17 +++++++++++++++++
src/test/regress/expected/nls_1.out | 17 +++++++++++++++++
src/test/regress/parallel_schedule | 2 +-
src/test/regress/regress.c | 18 ++++++++++++++++++
src/test/regress/sql/nls.sql | 16 ++++++++++++++++
6 files changed, 74 insertions(+), 1 deletion(-)
create mode 100644 src/test/regress/expected/nls.out
create mode 100644 src/test/regress/expected/nls_1.out
create mode 100644 src/test/regress/sql/nls.sql
diff --git a/src/backend/po/es.po b/src/backend/po/es.po
index e2593b52271..861aea61b68 100644
--- a/src/backend/po/es.po
+++ b/src/backend/po/es.po
@@ -31143,3 +31143,8 @@ msgstr "uso no estandar de escape en un literal de cadena"
#, c-format
msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'."
msgstr "Use la sintaxis de escape para cadenas, por ej. E'\\r\\n'."
+
+#: regress.c:1041
+#, c-format
+msgid "translated PRId64 = %<PRId64>, PRId32 = %<PRId32>"
+msgstr "traducido PRId64 = %<PRId64>, PRId32 = %<PRId32>"
diff --git a/src/test/regress/expected/nls.out b/src/test/regress/expected/nls.out
new file mode 100644
index 00000000000..b97802aeee8
--- /dev/null
+++ b/src/test/regress/expected/nls.out
@@ -0,0 +1,17 @@
+-- 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;
+SET lc_messages = 'es_ES';
+SELECT test_translation();
+NOTICE: traducido PRId64 = 4242, PRId32 = -1234
+ test_translation
+------------------
+
+(1 row)
+
+RESET lc_messages;
diff --git a/src/test/regress/expected/nls_1.out b/src/test/regress/expected/nls_1.out
new file mode 100644
index 00000000000..4b707e9dad4
--- /dev/null
+++ b/src/test/regress/expected/nls_1.out
@@ -0,0 +1,17 @@
+-- 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;
+SET lc_messages = 'es_ES';
+SELECT test_translation();
+NOTICE: NLS is not enabled
+ test_translation
+------------------
+
+(1 row)
+
+RESET lc_messages;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index f56482fb9f1..66ce1b7d9cd 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -76,7 +76,7 @@ test: brin_bloom brin_multi
# ----------
# Another group of parallel tests
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps generated_virtual
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions nls sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps generated_virtual
# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
# psql depends on create_am
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index a2db6080876..7d939565e2e 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1028,3 +1028,21 @@ test_relpath(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
+
+/*
+ * Simple test to verify NLS support, particularly that the PRI* macros work.
+ */
+PG_FUNCTION_INFO_V1(test_translation);
+Datum
+test_translation(PG_FUNCTION_ARGS)
+{
+#ifdef ENABLE_NLS
+ ereport(NOTICE,
+ (errmsg("translated PRId64 = %" PRId64 ", PRId32 = %" PRId32,
+ (int64) 4242, (int32) -1234)));
+#else
+ elog(NOTICE, "NLS is not enabled");
+#endif
+
+ PG_RETURN_VOID();
+}
diff --git a/src/test/regress/sql/nls.sql b/src/test/regress/sql/nls.sql
new file mode 100644
index 00000000000..53b4add86eb
--- /dev/null
+++ b/src/test/regress/sql/nls.sql
@@ -0,0 +1,16 @@
+-- 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;
+
+SET lc_messages = 'es_ES';
+
+SELECT test_translation();
+
+RESET lc_messages;
--
2.43.7