Windows locales and tests portability

Started by Andrey Borodin7 months ago2 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t53261
psql -h localhost -U postgres

Built from patchset v1 (message #1), August 23, 2026 at 01:32 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t53261_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t53261_1 && git checkout t53261_1

Patchset v1 (message #1) is on t53261_1

Jump to latest
#1Andrey Borodin
amborodin@acm.org

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.

Attachments:

t53261_1
0001-Fix-TAP-tests-for-Windows-with-non-C-numeric-locales.patchapplication/octet-stream; name=0001-Fix-TAP-tests-for-Windows-with-non-C-numeric-locales.patch; x-unix-mode=0644Download+59-12
#2Thomas Munro
thomas.munro@gmail.com
In reply to: Andrey Borodin (#1)
Re: Windows locales and tests portability

On Fri, Feb 6, 2026 at 8:03 PM Andrey Borodin <x4mmm@yandex-team.ru> wrote:

Windows MSVC strtod(): seems to ignore environment variables entirely and use the system's regional settings (Russian locale ,)

Hmm, right, we probably do setlocale(..., ""), which gets you an
"implementation-defined native environment", and Windows implements
that as you say. I suppose if we wanted it to work like Unix, we
could call getenv("LC_XXX") and feed the results to setlocale()
ourselves... maybe a terrible idea, IDK.