Subject: Re: LOCALE C.UTF-8 on EDB Windows v17 server

From: Dominique Devienne <[email-masked]>
Date: Thu, 5 Jun 2025 11:07:14 +0200

On Thu, Jun 5, 2025 at 4:52 AM Jeff Davis <[email-masked]> wrote:
> > On Windows, I'm getting
> I tried on windows and linux and got the same result.

Thanks Jeff, for your informative email. The command work,
just like it does on Linux. YET... The results are NOT the same!

C:\Users\ddevienne>psql service=my17
psql (17.4, server 17.5)

ddevienne=> select version();
                                 version
-------------------------------------------------------------------------
 PostgreSQL 17.5 on x86_64-windows, compiled by msvc-19.43.34808, 64-bit
(1 row)

ddevienne=> create database "dd_v168" encoding 'UTF8' locale 'C.UTF-8'
ddevienne-> locale_provider 'builtin' template template0;
ERROR:  invalid LC_COLLATE locale name: "C.UTF-8"
HINT:  If the locale name is specific to ICU, use ICU_LOCALE.

ddevienne=> create database "dd_v168" encoding 'UTF8' builtin_locale 'C.UTF-8'
ddevienne-> locale_provider 'builtin' template template0;
CREATE DATABASE
ddevienne=> select datlocprovider, datlocale, datcollate, datctype
from pg_database where datname = 'dd_v168';
 datlocprovider | datlocale | datcollate | datctype
----------------+-----------+------------+----------
 b              | C.UTF-8   | C          | C
(1 row)

Contrast that with the results on Linux, I just sent in response to
Laurenz's message, and that I'll repeat below:

ddevienne=> select version();
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 17.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0
20210514 (Red Hat 8.5.0-26), 64-bit
(1 row)
ddevienne=> create database "dd_v168b" encoding 'UTF8' builtin_locale 'C.UTF-8'
ddevienne-> locale_provider 'builtin' template template0;
CREATE DATABASE
ddevienne=> select datlocprovider, datlocale, datcollate, datctype
from pg_database where datname = 'dd_v168b';
 datlocprovider | datlocale | datcollate  |  datctype
----------------+-----------+-------------+-------------
 b              | C.UTF-8   | en_US.UTF-8 | en_US.UTF-8
(1 row)

Which means the same commands sometimes work, sometimes not, across platforms.
But when they work, they don't even yield the SAME results. Which
means it's not portable IMHO...

So... It is possible to have the SAME command on Windows and Linux,
which yields the SAME datcollate and datctype values???
So far, such a command eludes me, I'm afraid. --DD

---

From: Dominique Devienne <[email-masked]>
Date: Thu, 5 Jun 2025 11:34:48 +0200

> So far, such a command eludes me, I'm afraid. --DD

So I tried to be explicit about lc_collate and lc_ctype too.
OK on Linux, KO on Windows...

Windows:
ddevienne=> create database "dd_v168b" encoding 'UTF8' builtin_locale
'C.UTF-8' lc_collate 'C.UTF-8' lc_ctype 'C.UTF-8'
ddevienne-> locale_provider 'builtin' template template0;
ERROR:  invalid LC_COLLATE locale name: "C.UTF-8"
HINT:  If the locale name is specific to ICU, use ICU_LOCALE.

Linux:
ddevienne=> create database "dd_v168c" encoding 'UTF8' builtin_locale
'C.UTF-8' lc_collate 'C.UTF-8' lc_ctype 'C.UTF-8'
ddevienne-> locale_provider 'builtin' template template0;
CREATE DATABASE
ddevienne=> select datlocprovider, datlocale, datcollate, datctype
from pg_database where datname = 'dd_v168c';
 datlocprovider | datlocale | datcollate | datctype
----------------+-----------+------------+----------
 b              | C.UTF-8   | C.UTF-8    | C.UTF-8
(1 row)

AFAIK, C and C.UTF-8 are NOT the same thing, for collations.
It is indeed super confusing Jeff. I'm lost.

How can I get a

datlocprovider | datlocale | datcollate | datctype
----------------+-----------+------------+----------
 b              | C.UTF-8   | C.UTF-8    | C.UTF-8

database on Windows *AND* Linux?
If not possible using the same SQL (but why...), using what SQL?

---

From: Jeff Davis <[email-masked]>
Date: Thu, 05 Jun 2025 14:11:43 -0700

> OK on Linux, KO on Windows...

LC_COLLATE and LC_CTYPE (datcollate and datctype) are platform-
dependent (handled by libc) so it won't be possible for those to have
the same meaning across different systems. The only locale that's
guaranteed to be available, AFAIK, is "C". Even some other unix-like
operating systems don't support "C.UTF-8".

The good news is that LC_COLLATE and LC_CTYPE don't have much effect if
you are using a different provider like "builtin" or ICU. They affect
the server's LC_COLLATE and LC_CTYPE environment, which does have a few
effects, but in general we are trying to avoid cases where those matter
a lot.

To maintain consistency across platforms, use LC_COLLATE=C and
LC_CTYPE=C when creating a database; along with the builtin provider
and UTF-8 as you are already doing.

Regards,
	Jeff Davis