Thread
-
Re: PRI?64 vs Visual Studio (2022)
Bryan Green <dbryan.green@gmail.com> — 2025-12-15T23:10:36Z
On 12/15/2025 2:39 PM, Tom Lane wrote: > I wrote: >> Experimenting here, it looks like 'C.UTF-8' might be accepted >> everywhere. I even got it to pass on Solaris's not-GNU gettext, >> which I thought for sure would be the weak spot in the idea. >> I'll press forward with that. > > Hmmm ... the first batch of BF reports show that on some Linux > machines, it works to set lc_messages to 'C.UTF-8', but nonetheless > no translation happens. Did you notice any other gating factors? > > regards, tom lane Yes - the LANGUAGE environment variable. gettext has a priority order for locale selection that's different from what most people expect. Here's what guess_category_value() does: Environment Variable Priority (from dcigettext.c): 1. LANGUAGE - GNU extension, colon-separated list (e.g., "en_US:en:C") 2. setlocale(category, NULL) result - the actual locale set 3. LC_ALL - POSIX override for all categories 4. LC_MESSAGES (or other LC_* for that category) 5. LANG - fallback default LANGUAGE has the highest priority and will override LC_MESSAGES completely. I am not sure this is the problem, but you probably should unset LANGUAGE before doing almost anything else in the test script. I wouldn't be surprised if the CI/BF environments have it set. Do we know what version of libintl is being used on those BF machines? There are some marked differences between some versions, which makes this a little more guesswork than it should be. --------------------------------------------------------------------- What follows is a walkthrough that just shows that language overrides lc_messages and how that can impact things. No need to read this unless you just want more detail. Assume, export LANGUAGE=en_US:en export LC_MESSAGES=C.UTF-8 System has catalogs for C.UTF-8 and es. #postgres.conf lc_messages = 'C.UTF-8' InitPostgres calls pg_perm_setlocale with C.UTF-8. pg_perm_setlocale calls setlocale(LC_MESSAGES, "C.UTF-8") and succeeds. setlocale uses setenv to set LC_MESSAGES=C.UTF_8 Now assume an error occurs and gettext is called. A couple of wrappers down we get to DCIGETTEXT() with a category of LC_MESSAGES. We call guess_category_value with LC_MESSAGES. guess_category_value implements the priorty as discussed above. The very first thing it checks is getenv("LANGUAGE"). If that is not NULL or an empty string it returns whatever is in LANGUAUGE, which in this case is en_US:en. Then back in DCIGETTEXT() we will loop through en_US:en. We try to find the message catalog with 'en_US' first...and fail because we don't have that catalog. Then we loop back and try 'en'...and fail again because we don't have that catalog. One more time through the loop where we don't have anything left in our list of languages, so we set the locale to 'C'. Then we check that we don't translate if the locale is a single C. and we break. Nothing translated. -- Bryan Green EDB: https://www.enterprisedb.com