mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
In pg_upgrade, try to convert the locale names to canonical form before
comparison; also report the old/new values if they don't match. Backpatch to 9.2.
This commit is contained in:
parent
2a4bbed7b8
commit
b61837a49f
@ -21,6 +21,7 @@ static void check_for_prepared_transactions(ClusterInfo *cluster);
|
||||
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
|
||||
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
|
||||
static void get_bin_version(ClusterInfo *cluster);
|
||||
static char *get_canonical_locale_name(int category, const char *locale);
|
||||
|
||||
|
||||
/*
|
||||
@ -359,8 +360,23 @@ set_locale_and_encoding(ClusterInfo *cluster)
|
||||
i_datcollate = PQfnumber(res, "datcollate");
|
||||
i_datctype = PQfnumber(res, "datctype");
|
||||
|
||||
if (GET_MAJOR_VERSION(cluster->major_version) < 902)
|
||||
{
|
||||
/*
|
||||
* Pre-9.2 did not canonicalize the supplied locale names
|
||||
* to match what the system returns, while 9.2+ does, so
|
||||
* convert pre-9.2 to match.
|
||||
*/
|
||||
ctrl->lc_collate = get_canonical_locale_name(LC_COLLATE,
|
||||
pg_strdup(PQgetvalue(res, 0, i_datcollate)));
|
||||
ctrl->lc_ctype = get_canonical_locale_name(LC_CTYPE,
|
||||
pg_strdup(PQgetvalue(res, 0, i_datctype)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
|
||||
ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
@ -390,16 +406,23 @@ static void
|
||||
check_locale_and_encoding(ControlData *oldctrl,
|
||||
ControlData *newctrl)
|
||||
{
|
||||
/* These are often defined with inconsistent case, so use pg_strcasecmp(). */
|
||||
/*
|
||||
* These are often defined with inconsistent case, so use pg_strcasecmp().
|
||||
* They also often use inconsistent hyphenation, which we cannot fix, e.g.
|
||||
* UTF-8 vs. UTF8, so at least we display the mismatching values.
|
||||
*/
|
||||
if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
|
||||
pg_log(PG_FATAL,
|
||||
"old and new cluster lc_collate values do not match\n");
|
||||
"lc_collate cluster values do not match: old \"%s\", new \"%s\"\n",
|
||||
oldctrl->lc_collate, newctrl->lc_collate);
|
||||
if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
|
||||
pg_log(PG_FATAL,
|
||||
"old and new cluster lc_ctype values do not match\n");
|
||||
"lc_ctype cluster values do not match: old \"%s\", new \"%s\"\n",
|
||||
oldctrl->lc_ctype, newctrl->lc_ctype);
|
||||
if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
|
||||
pg_log(PG_FATAL,
|
||||
"old and new cluster encoding values do not match\n");
|
||||
"encoding cluster values do not match: old \"%s\", new \"%s\"\n",
|
||||
oldctrl->encoding, newctrl->encoding);
|
||||
}
|
||||
|
||||
|
||||
@ -931,3 +954,40 @@ get_bin_version(ClusterInfo *cluster)
|
||||
|
||||
cluster->bin_version = (pre_dot * 100 + post_dot) * 100;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_canonical_locale_name
|
||||
*
|
||||
* Send the locale name to the system, and hope we get back a canonical
|
||||
* version. This should match the backend's check_locale() function.
|
||||
*/
|
||||
static char *
|
||||
get_canonical_locale_name(int category, const char *locale)
|
||||
{
|
||||
char *save;
|
||||
char *res;
|
||||
|
||||
save = setlocale(category, NULL);
|
||||
if (!save)
|
||||
pg_log(PG_FATAL, "failed to get the current locale\n");
|
||||
|
||||
/* 'save' may be pointing at a modifiable scratch variable, so copy it. */
|
||||
save = pg_strdup(save);
|
||||
|
||||
/* set the locale with setlocale, to see if it accepts it. */
|
||||
res = setlocale(category, locale);
|
||||
|
||||
if (!res)
|
||||
pg_log(PG_FATAL, "failed to get system local name for \"%s\"\n", res);
|
||||
|
||||
res = pg_strdup(res);
|
||||
|
||||
/* restore old value. */
|
||||
if (!setlocale(category, save))
|
||||
pg_log(PG_FATAL, "failed to restore old locale \"%s\"\n", save);
|
||||
|
||||
free(save);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user