Commit 0333a734 authored by Tom Lane's avatar Tom Lane

Avoid conflicts with collation aliases generated by stripping.

This resulted in failures depending on the order of "locale -a" output.
The original coding in initdb sorted the results, but that should be
unnecessary as long as "locale -a" doesn't print duplicate names.  The
original entries will then all be non-dups, and while we might generate
duplicate aliases by stripping, they should be for different encodings and
thus not conflict.  Even if the latter assumption fails somehow, it won't
be fatal because we're using if_not_exists mode for the aliases.

Discussion: https://postgr.es/m/26116.1484751196%40sss.pgh.pa.us
parent 215b43cd
......@@ -229,6 +229,12 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
FILE *locale_a_handle;
char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
int count = 0;
List *aliaslist = NIL;
List *localelist = NIL;
List *enclist = NIL;
ListCell *lca,
*lcl,
*lce;
#endif
if (!superuser())
......@@ -306,22 +312,32 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
* ease of use. Note that collation names are unique per encoding
* only, so this doesn't clash with "en_US" for LATIN1, say.
*
* This always runs in "if not exists" mode, to skip aliases that
* conflict with an existing locale name for the same encoding. For
* example, "br_FR.iso88591" is normalized to "br_FR", both for
* encoding LATIN1. But the unnormalized locale "br_FR" already
* exists for LATIN1.
* However, it might conflict with a name we'll see later in the
* "locale -a" output. So save up the aliases and try to add them
* after we've read all the output.
*/
if (normalize_locale_name(alias, localebuf))
{
CollationCreate(alias, nspid, GetUserId(), enc,
localebuf, localebuf, true);
CommandCounterIncrement();
aliaslist = lappend(aliaslist, pstrdup(alias));
localelist = lappend(localelist, pstrdup(localebuf));
enclist = lappend_int(enclist, enc);
}
}
ClosePipeStream(locale_a_handle);
/* Now try to add any aliases we created */
forthree(lca, aliaslist, lcl, localelist, lce, enclist)
{
char *alias = (char *) lfirst(lca);
char *locale = (char *) lfirst(lcl);
int enc = lfirst_int(lce);
CollationCreate(alias, nspid, GetUserId(), enc,
locale, locale, true);
CommandCounterIncrement();
}
if (count == 0)
ereport(ERROR,
(errmsg("no usable system locales were found")));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment