Skip to content

Commit 5e6e42e

Browse files
committed
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>
1 parent 0858f0f commit 5e6e42e

File tree

6 files changed

+42
-37
lines changed

6 files changed

+42
-37
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3158,7 +3158,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
31583158
<structfield>datcollate</structfield> <type>text</type>
31593159
</para>
31603160
<para>
3161-
LC_COLLATE for this database
3161+
LC_COLLATE for this database (ignored unless <structfield>datlocprovider</structfield> is <literal>c</literal>)
31623162
</para></entry>
31633163
</row>
31643164

doc/src/sgml/charset.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ initdb --locale=sv_SE
100100
<tbody>
101101
<row>
102102
<entry><envar>LC_COLLATE</envar></entry>
103-
<entry>String sort order</entry>
103+
<entry>String sort order (ignored unless the provider is <literal>libc</literal>)</entry>
104104
</row>
105105
<row>
106106
<entry><envar>LC_CTYPE</envar></entry>

doc/src/sgml/ref/create_database.sgml

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,12 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
150150
<para>
151151
Sets the default collation order and character classification in the
152152
new database. Collation affects the sort order applied to strings,
153-
e.g., in queries with <literal>ORDER BY</literal>, as well as the order used in indexes
154-
on text columns. Character classification affects the categorization
155-
of characters, e.g., lower, upper, and digit. Also sets the
156-
associated aspects of the operating system environment,
157-
<literal>LC_COLLATE</literal> and <literal>LC_CTYPE</literal>. The
158-
default is the same setting as the template database. See <xref
153+
e.g., in queries with <literal>ORDER BY</literal>, as well as the
154+
order used in indexes on text columns. Character classification
155+
affects the categorization of characters, e.g., lower, upper, and
156+
digit. Also sets the <literal>LC_CTYPE</literal> aspect of the
157+
operating system environment. The default is the same setting as the
158+
template database. See <xref
159159
linkend="collation-managing-create-libc"/> and <xref
160160
linkend="collation-managing-create-icu"/> for details.
161161
</para>
@@ -189,17 +189,16 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
189189
<term><replaceable class="parameter">lc_collate</replaceable></term>
190190
<listitem>
191191
<para>
192-
Sets <literal>LC_COLLATE</literal> in the database server's operating
193-
system environment. The default is the setting of <xref
194-
linkend="create-database-locale"/> if specified, otherwise the same
195-
setting as the template database. See below for additional
196-
restrictions.
192+
If <xref linkend="create-database-locale-provider"/> is
193+
<literal>libc</literal>, sets the default collation order to use in
194+
the new database, overriding the setting <xref
195+
linkend="create-database-locale"/>. Otherwise, this setting is
196+
ignored.
197197
</para>
198198
<para>
199-
If <xref linkend="create-database-locale-provider"/> is
200-
<literal>libc</literal>, also sets the default collation order to use
201-
in the new database, overriding the setting <xref
202-
linkend="create-database-locale"/>.
199+
The default is the setting of <xref linkend="create-database-locale"/>
200+
if specified, otherwise the same setting as the template database.
201+
See below for additional restrictions.
203202
</para>
204203
</listitem>
205204
</varlistentry>
@@ -208,16 +207,18 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
208207
<listitem>
209208
<para>
210209
Sets <literal>LC_CTYPE</literal> in the database server's operating
211-
system environment. The default is the setting of <xref
212-
linkend="create-database-locale"/> if specified, otherwise the same
213-
setting as the template database. See below for additional
214-
restrictions.
210+
system environment.
215211
</para>
216212
<para>
217213
If <xref linkend="create-database-locale-provider"/> is
218-
<literal>libc</literal>, also sets the default character
219-
classification to use in the new database, overriding the setting
220-
<xref linkend="create-database-locale"/>.
214+
<literal>libc</literal>, sets the default character classification to
215+
use in the new database, overriding the setting <xref
216+
linkend="create-database-locale"/>.
217+
</para>
218+
<para>
219+
The default is the setting of <xref linkend="create-database-locale"/>
220+
if specified, otherwise the same setting as the template database.
221+
See below for additional restrictions.
221222
</para>
222223
</listitem>
223224
</varlistentry>

doc/src/sgml/ref/createdb.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ PostgreSQL documentation
136136
<term><option>--lc-collate=<replaceable class="parameter">locale</replaceable></option></term>
137137
<listitem>
138138
<para>
139-
Specifies the LC_COLLATE setting to be used in this database.
139+
Specifies the LC_COLLATE setting to be used in this database (ignored
140+
unless the locale provider is <literal>libc</literal>).
140141
</para>
141142
</listitem>
142143
</varlistentry>

src/backend/main/main.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,17 @@ main(int argc, char *argv[])
125125
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
126126

127127
/*
128-
* In the postmaster, absorb the environment values for LC_COLLATE and
129-
* LC_CTYPE. Individual backends will change these later to settings
130-
* taken from pg_database, but the postmaster cannot do that. If we leave
131-
* these set to "C" then message localization might not work well in the
132-
* postmaster.
128+
* Collation is handled by pg_locale.c, and the behavior is dependent on
129+
* the provider. strcoll(), etc., should not be called directly.
130+
*/
131+
init_locale("LC_COLLATE", LC_COLLATE, "C");
132+
133+
/*
134+
* In the postmaster, absorb the environment value for LC_CTYPE.
135+
* Individual backends will change it later to pg_database.datctype, but
136+
* the postmaster cannot do that. If we leave it set to "C" then message
137+
* localization might not work well in the postmaster.
133138
*/
134-
init_locale("LC_COLLATE", LC_COLLATE, "");
135139
init_locale("LC_CTYPE", LC_CTYPE, "");
136140

137141
/*

src/backend/utils/init/postinit.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,11 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
417417
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype);
418418
ctype = TextDatumGetCString(datum);
419419

420-
if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
421-
ereport(FATAL,
422-
(errmsg("database locale is incompatible with operating system"),
423-
errdetail("The database was initialized with LC_COLLATE \"%s\", "
424-
" which is not recognized by setlocale().", collate),
425-
errhint("Recreate the database with another locale or install the missing locale.")));
420+
/*
421+
* Historcally, we set LC_COLLATE from datcollate, as well. That's no
422+
* longer necessary because all collation behavior is handled through
423+
* pg_locale_t.
424+
*/
426425

427426
if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
428427
ereport(FATAL,

0 commit comments

Comments
 (0)