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> <structfield>datcollate</structfield> <type>text</type>
</para> </para>
<para> <para>
LC_COLLATE for this database LC_COLLATE for this database (ignored unless <structfield>datlocprovider</structfield> is <literal>c</literal>)
</para></entry> </para></entry>
</row> </row>

View File

@ -100,7 +100,7 @@ initdb --locale=sv_SE
<tbody> <tbody>
<row> <row>
<entry><envar>LC_COLLATE</envar></entry> <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>
<row> <row>
<entry><envar>LC_CTYPE</envar></entry> <entry><envar>LC_CTYPE</envar></entry>

View File

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

View File

@ -136,7 +136,8 @@ PostgreSQL documentation
<term><option>--lc-collate=<replaceable class="parameter">locale</replaceable></option></term> <term><option>--lc-collate=<replaceable class="parameter">locale</replaceable></option></term>
<listitem> <listitem>
<para> <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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -125,13 +125,17 @@ main(int argc, char *argv[])
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres")); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
/* /*
* In the postmaster, absorb the environment values for LC_COLLATE and * Collation is handled by pg_locale.c, and the behavior is dependent on
* LC_CTYPE. Individual backends will change these later to settings * the provider. strcoll(), etc., should not be called directly.
* 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 init_locale("LC_COLLATE", LC_COLLATE, "C");
* postmaster.
/*
* 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, ""); 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); datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
ctype = TextDatumGetCString(datum); ctype = TextDatumGetCString(datum);
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL) /*
ereport(FATAL, * Historcally, we set LC_COLLATE from datcollate, as well. That's no
(errmsg("database locale is incompatible with operating system"), * longer necessary because all collation behavior is handled through
errdetail("The database was initialized with LC_COLLATE \"%s\", " * pg_locale_t.
" which is not recognized by setlocale().", collate), */
errhint("Recreate the database with another locale or install the missing locale.")));
if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL) if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
ereport(FATAL, ereport(FATAL,