Re: Windows locales and tests portability

From: Andrew Bille <andrewbille(at)gmail(dot)com>
To: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Windows locales and tests portability
Date: 2026-09-22 07:21:25
Message-ID: CAJnzarxD=FPRA14BVyStYWgr9HekapRU+_uDOmdNg+QF5McmKg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Andrey,

I recently ran into the same problem independently while running the TAP
tests on Windows with the system locale set to Russian.

At first I saw the same pg_test_timing failures with a comma as the
decimal separator, but while investigating it I also found that this is
not only a test-output portability issue. For example, psql fails to
parse:

\watch 0.01

under a Windows user locale using a comma decimal separator, even though
the TAP environment sets LC_NUMERIC=C.

So I ended up trying the approach Thomas mentioned in this thread:
explicitly honor LC_NUMERIC from the environment on Windows after
setlocale(LC_ALL, "").

I posted a patch here:

https://www.postgresql.org/message-id/CAJnzarxw2pJjVGQpwosjzBW%2BMO67vqSJt4jjVD5T3GpKpX%2BdkQ%40mail.gmail.com

The patch only applies a non-empty LC_NUMERIC; if it is unset or empty,
the existing Windows behavior is unchanged. With it, both
pg_test_timing formatting and psql decimal \watch parsing behave as
expected under a Russian Windows locale.

Looks like I mostly rediscovered the issue from this thread, but the
\watch case convinced me that fixing it in frontend locale
initialization is preferable to teaching individual tests about Windows
decimal separators.

Regards,
Andrew

On Tue, Sep 22, 2026 at 2:15 PM Andrey Borodin <x4mmm(at)yandex-team(dot)ru> wrote:
>
> Hi hackers!
>
> I'm toying with Windows machine. It's nice, fast, run cool games, so I decided to keep it and make a BF animal on top. The problem is I have RU locale.
>
> PostgreSQL::Test::Utils.pm (lines 113-115) explicitly sets:
> $ENV{LC_NUMERIC} = 'C';
> setlocale(LC_ALL, "");
> This makes Perl format numbers with . as the decimal separator.
>
> Windows MSVC strtod(): seems to ignore environment variables entirely and use the system's regional settings (Russian locale ,)
> On Unix, environment variables like LC_NUMERIC control both Perl and C library functions like strtod(). Looks like on Windows with MSVC, the C runtime gets its locale from the Windows regional settings, not from environment variables.
>
> FWIW I used strawberry perl 5, version 42, subversion 0 (v5.42.0) built for MSWin32-x64-multi-thread. Windows 11 Pro 23H2 build 22631.4890.
>
> I propose attached ugly fix, it makes my box happy and works on CI machines.
>
> In pg_test_timing fix is easy. It just accept [,.] as a decimal separator. AFAIK that would solve the problem for Russian, Brazilian, Indonesia, German, Italian, Polish etc locales. There are some other separators, but with really small fraction, I could add them into regex, but with a wiki-page-like comment... so here's [,.]
>
> For \watch tests we need to format number that would be acceptable to strtod(), so I resorted to printing this number by psql. Luckily in standard SQL syntax so far, the period (.) is the universal decimal separator for numeric literals in a query.
>
>
> Perhaps, I should just switch my machine to locale with dot too. But just in case if we really want tests on Windows with locales, PFA.
> I did not consider seriously bashing with Utils.pm setlocale(). But maybe I should try.
>
> WDYT?
>
>
> Best regards, Andrey Borodin.
>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andrey Borodin 2026-09-22 07:40:24 Re: Windows locales and tests portability
Previous Message Tatsuya Kawata 2026-09-22 07:15:35 Re: [PATCH] Add memory/disk usage for Function Scan nodes in EXPLAIN