NLS: use gettext() to translate system error messages
Jeff Davis <pgsql@j-davis.com>
From: Jeff Davis <pgsql@j-davis.com>
To: pgsql-hackers@postgresql.org
Date: 2025-10-23T22:53:51Z
Lists: pgsql-hackers
Attachments
- v1-0001-NLS-use-gettext-to-translate-system-error-message.patch (text/x-patch) patch v1-0001
- errno_translation.c (text/x-csrc)
This is related to my effort to remove the global LC_CTYPE dependency, and set the global LC_CTYPE to C. The replacement of "%m" (e.g. with "Permission denied" if errno==EACCES) in a message is done using strerror_r(), which sometimes does translation. If it does translate, strerror uses LC_CTYPE to determine the target encoding, and LC_MESSAGES to determine the language/region. (It appears that strerror translation only happens on Linux -- corrent me if I'm wrong.) Currently, strerror translation is orthogonal to our NLS system which translates Postgres messages (e.g. "division by zero") using gettext along with our own translations (.po files). The Postgres messages might be translated but not the "%m" replacements, or vice-versa, depending on whether NLS is enabled, the OS, etc. The attached patch changes "%m" replacements to use gettext for translation. That makes the overall translations more consistent, equally available on all platforms, and not dependent on LC_CTYPE (because gettext allows the encoding for gettext can be set separately with bind_textdomain_codeset()). It also fixes an issue with translations when LC_CTYPE=C, where strerror can't find the target encoding, so it forces the translated message into ASCII even if the database encoding supports all of the resulting characters. For instance, if LC_CTYPE=C and LC_MESSAGES=fr_FR.UTF-8 and errno=EACCES and the database encoding is UTF-8, you get: Permission non accord?e instead of: Permission non accordée I also attached a C file for testing, which generates the messages and translations for a range of errnos, and outputs in .po format. As mentioned earlier, I think the only OS that does any translation of these messages is linux, but corrections are welcome. One downside is that there are more messages to translate -- one per errno that Postgres might plausibly encounter, plus a few more for variations between platforms. Comments? Regards, Jeff Davis