Re: PRI?64 vs Visual Studio (2022)

Поиск
Список
Период
Сортировка
От Bryan Green
Тема Re: PRI?64 vs Visual Studio (2022)
Дата
Msg-id a337896e-5bff-490b-afc9-c545f06c014c@gmail.com
обсуждение исходный текст
Ответ на Re: PRI?64 vs Visual Studio (2022)  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: PRI?64 vs Visual Studio (2022)
Список pgsql-hackers
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



В списке pgsql-hackers по дате отправления: