mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +03:00
Handle the "und" locale in ICU versions 54 and older.
The "und" locale is an alternative spelling of the root locale, but it
was not recognized until ICU 55. To maintain common behavior across
all supported ICU versions, check for "und" and replace with "root"
before opening.
Previously, the lack of support for "und" was dangerous, because
versions 54 and older fall back to the environment when a locale is
not found. If the user specified "und" for the language (which is
expected and documented), it could not only resolve to the wrong
collator, but it could unexpectedly change (which could lead to
corrupt indexes).
This effectively reverts commit d72900bded
, which worked around the
problem for the built-in "unicode" collation, and is no longer
necessary.
Discussion: https://postgr.es/m/60da0cecfb512a78b8666b31631a636215d8ce73.camel@j-davis.com
Discussion: https://postgr.es/m/0c6fa66f2753217d2a40480a96bd2ccf023536a1.camel@j-davis.com
Reviewed-by: Peter Eisentraut
This commit is contained in:
@ -2503,6 +2503,7 @@ pg_ucol_open(const char *loc_str)
|
||||
{
|
||||
UCollator *collator;
|
||||
UErrorCode status;
|
||||
char *fixed_str = NULL;
|
||||
|
||||
/*
|
||||
* Must never open default collator, because it depends on the environment
|
||||
@ -2517,6 +2518,36 @@ pg_ucol_open(const char *loc_str)
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("opening default collator is not supported")));
|
||||
|
||||
/*
|
||||
* In ICU versions 54 and earlier, "und" is not a recognized spelling of
|
||||
* the root locale. If the first component of the locale is "und", replace
|
||||
* with "root" before opening.
|
||||
*/
|
||||
if (U_ICU_VERSION_MAJOR_NUM < 55)
|
||||
{
|
||||
char lang[ULOC_LANG_CAPACITY];
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
|
||||
if (U_FAILURE(status))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errmsg("could not get language from locale \"%s\": %s",
|
||||
loc_str, u_errorName(status))));
|
||||
}
|
||||
|
||||
if (strcmp(lang, "und") == 0)
|
||||
{
|
||||
const char *remainder = loc_str + strlen("und");
|
||||
|
||||
fixed_str = palloc(strlen("root") + strlen(remainder) + 1);
|
||||
strcpy(fixed_str, "root");
|
||||
strcat(fixed_str, remainder);
|
||||
|
||||
loc_str = fixed_str;
|
||||
}
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
collator = ucol_open(loc_str, &status);
|
||||
if (U_FAILURE(status))
|
||||
@ -2527,6 +2558,9 @@ pg_ucol_open(const char *loc_str)
|
||||
if (U_ICU_VERSION_MAJOR_NUM < 54)
|
||||
icu_set_collation_attributes(collator, loc_str);
|
||||
|
||||
if (fixed_str != NULL)
|
||||
pfree(fixed_str);
|
||||
|
||||
return collator;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user