Skip to content

Commit 853c175

Browse files
committed
Be more wary in initdb's creation of platform-dependent collations.
Discard any collation aliases that match the built-in pg_collation entries (ie, "default", "C", "POSIX"). Such aliases would be refused by a CREATE COLLATION command, but since initdb is injecting them via a simple INSERT, it has to make the corresponding check for itself. Per Martin Pitt's report of funny behavior in a machine that had a bogus "C.UTF-8" locale. Also, use E'' syntax for the output of escape_quotes, as per its header comment.
1 parent 5059cf6 commit 853c175

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/bin/initdb/initdb.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,7 @@ setup_collation(void)
15951595
size_t len;
15961596
int enc;
15971597
bool skip;
1598+
char *quoted_locale;
15981599
char alias[NAMEDATALEN];
15991600

16001601
len = strlen(localebuf);
@@ -1645,38 +1646,44 @@ setup_collation(void)
16451646

16461647
count++;
16471648

1648-
PG_CMD_PRINTF2("INSERT INTO tmp_pg_collation (locale, encoding) VALUES ('%s', %d);\n",
1649-
escape_quotes(localebuf), enc);
1649+
quoted_locale = escape_quotes(localebuf);
1650+
1651+
PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
1652+
quoted_locale, quoted_locale, enc);
16501653

16511654
/*
16521655
* Generate aliases such as "en_US" in addition to "en_US.utf8" for
16531656
* ease of use. Note that collation names are unique per encoding
16541657
* only, so this doesn't clash with "en_US" for LATIN1, say.
16551658
*/
16561659
if (normalize_locale_name(alias, localebuf))
1657-
PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation (collname, locale, encoding) VALUES ('%s', '%s', %d);\n",
1658-
escape_quotes(alias), escape_quotes(localebuf), enc);
1660+
PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
1661+
escape_quotes(alias), quoted_locale, enc);
16591662
}
16601663

16611664
/* Add an SQL-standard name */
1662-
PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation (collname, locale, encoding) VALUES ('ucs_basic', 'C', %d);\n", PG_UTF8);
1665+
PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n", PG_UTF8);
16631666

16641667
/*
16651668
* When copying collations to the final location, eliminate aliases that
16661669
* conflict with an existing locale name for the same encoding. For
16671670
* example, "br_FR.iso88591" is normalized to "br_FR", both for encoding
16681671
* LATIN1. But the unnormalized locale "br_FR" already exists for LATIN1.
1669-
* Prefer the collation that matches the OS locale name, else the first
1672+
* Prefer the alias that matches the OS locale name, else the first locale
16701673
* name by sort order (arbitrary choice to be deterministic).
1674+
*
1675+
* Also, eliminate any aliases that conflict with pg_collation's
1676+
* hard-wired entries for "C" etc.
16711677
*/
16721678
PG_CMD_PUTS("INSERT INTO pg_collation (collname, collnamespace, collowner, collencoding, collcollate, collctype) "
1673-
" SELECT DISTINCT ON (final_collname, collnamespace, encoding)"
1674-
" COALESCE(collname, locale) AS final_collname, "
1679+
" SELECT DISTINCT ON (collname, encoding)"
1680+
" collname, "
16751681
" (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') AS collnamespace, "
16761682
" (SELECT relowner FROM pg_class WHERE relname = 'pg_collation') AS collowner, "
16771683
" encoding, locale, locale "
16781684
" FROM tmp_pg_collation"
1679-
" ORDER BY final_collname, collnamespace, encoding, (collname = locale) DESC, locale;\n");
1685+
" WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)"
1686+
" ORDER BY collname, encoding, (collname = locale) DESC, locale;\n");
16801687

16811688
pclose(locale_a_handle);
16821689
PG_CMD_CLOSE;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy