1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +03:00

Force LC_COLLATE to C in postmaster.

Avoid dependence on setlocale().

strcoll(), etc., are not called directly; all collation-sensitive
calls should go through pg_locale.c and use the appropriate
provider. By setting LC_COLLATE to C, we avoid accidentally depending
on libc behavior when using a different provider.

No behavior change in the backend, but it's possible that some
extensions will be affected. Such extensions should be updated to use
the pg_locale_t APIs.

Discussion: https://postgr.es/m/9875f7f9-50f1-4b5d-86fc-ee8b03e8c162@eisentraut.org
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
This commit is contained in:
Jeff Davis
2025-07-16 14:13:18 -07:00
parent 0858f0f96e
commit 5e6e42e44f
6 changed files with 42 additions and 37 deletions

View File

@ -3158,7 +3158,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<structfield>datcollate</structfield> <type>text</type>
</para>
<para>
LC_COLLATE for this database
LC_COLLATE for this database (ignored unless <structfield>datlocprovider</structfield> is <literal>c</literal>)
</para></entry>
</row>

View File

@ -100,7 +100,7 @@ initdb --locale=sv_SE
<tbody>
<row>
<entry><envar>LC_COLLATE</envar></entry>
<entry>String sort order</entry>
<entry>String sort order (ignored unless the provider is <literal>libc</literal>)</entry>
</row>
<row>
<entry><envar>LC_CTYPE</envar></entry>

View File

@ -150,12 +150,12 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<para>
Sets the default collation order and character classification in the
new database. Collation affects the sort order applied to strings,
e.g., in queries with <literal>ORDER BY</literal>, as well as the order used in indexes
on text columns. Character classification affects the categorization
of characters, e.g., lower, upper, and digit. Also sets the
associated aspects of the operating system environment,
<literal>LC_COLLATE</literal> and <literal>LC_CTYPE</literal>. The
default is the same setting as the template database. See <xref
e.g., in queries with <literal>ORDER BY</literal>, as well as the
order used in indexes on text columns. Character classification
affects the categorization of characters, e.g., lower, upper, and
digit. Also sets the <literal>LC_CTYPE</literal> aspect of the
operating system environment. The default is the same setting as the
template database. See <xref
linkend="collation-managing-create-libc"/> and <xref
linkend="collation-managing-create-icu"/> for details.
</para>
@ -189,17 +189,16 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<term><replaceable class="parameter">lc_collate</replaceable></term>
<listitem>
<para>
Sets <literal>LC_COLLATE</literal> in the database server's operating
system environment. The default is the setting of <xref
linkend="create-database-locale"/> if specified, otherwise the same
setting as the template database. See below for additional
restrictions.
If <xref linkend="create-database-locale-provider"/> is
<literal>libc</literal>, sets the default collation order to use in
the new database, overriding the setting <xref
linkend="create-database-locale"/>. Otherwise, this setting is
ignored.
</para>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>libc</literal>, also sets the default collation order to use
in the new database, overriding the setting <xref
linkend="create-database-locale"/>.
The default is the setting of <xref linkend="create-database-locale"/>
if specified, otherwise the same setting as the template database.
See below for additional restrictions.
</para>
</listitem>
</varlistentry>
@ -208,16 +207,18 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Sets <literal>LC_CTYPE</literal> in the database server's operating
system environment. The default is the setting of <xref
linkend="create-database-locale"/> if specified, otherwise the same
setting as the template database. See below for additional
restrictions.
system environment.
</para>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>libc</literal>, also sets the default character
classification to use in the new database, overriding the setting
<xref linkend="create-database-locale"/>.
<literal>libc</literal>, sets the default character classification to
use in the new database, overriding the setting <xref
linkend="create-database-locale"/>.
</para>
<para>
The default is the setting of <xref linkend="create-database-locale"/>
if specified, otherwise the same setting as the template database.
See below for additional restrictions.
</para>
</listitem>
</varlistentry>

View File

@ -136,7 +136,8 @@ PostgreSQL documentation
<term><option>--lc-collate=<replaceable class="parameter">locale</replaceable></option></term>
<listitem>
<para>
Specifies the LC_COLLATE setting to be used in this database.
Specifies the LC_COLLATE setting to be used in this database (ignored
unless the locale provider is <literal>libc</literal>).
</para>
</listitem>
</varlistentry>

View File

@ -125,13 +125,17 @@ main(int argc, char *argv[])
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
/*
* In the postmaster, absorb the environment values for LC_COLLATE and
* LC_CTYPE. Individual backends will change these later to settings
* taken from pg_database, but the postmaster cannot do that. If we leave
* these set to "C" then message localization might not work well in the
* postmaster.
* Collation is handled by pg_locale.c, and the behavior is dependent on
* the provider. strcoll(), etc., should not be called directly.
*/
init_locale("LC_COLLATE", LC_COLLATE, "C");
/*
* In the postmaster, absorb the environment value for LC_CTYPE.
* Individual backends will change it later to pg_database.datctype, but
* the postmaster cannot do that. If we leave it set to "C" then message
* localization might not work well in the postmaster.
*/
init_locale("LC_COLLATE", LC_COLLATE, "");
init_locale("LC_CTYPE", LC_CTYPE, "");
/*

View File

@ -417,12 +417,11 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
ctype = TextDatumGetCString(datum);
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
ereport(FATAL,
(errmsg("database locale is incompatible with operating system"),
errdetail("The database was initialized with LC_COLLATE \"%s\", "
" which is not recognized by setlocale().", collate),
errhint("Recreate the database with another locale or install the missing locale.")));
/*
* Historcally, we set LC_COLLATE from datcollate, as well. That's no
* longer necessary because all collation behavior is handled through
* pg_locale_t.
*/
if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
ereport(FATAL,