On Tue, 3 Nov 2020 at 12:29, David Rowley <dgrowle...@gmail.com> wrote: > Running low on ideas for now, so thought I'd post this in case it > someone thinks of something else.
FWIW, the attached does fix the issue for me. It basically just calls the function that converts the windows-type "English_New Zealand.1252" locale name string into, e.g. "en_NZ". Then, since GetNLSVersionEx() wants yet another variant with a - rather than an _, I've just added a couple of lines to swap the _ for a -. There's a bit of extra work there since IsoLocaleName() just did the opposite, so perhaps doing it that way was lazy of me. I'd have invented some other function if I could have thought of a meaningful name for it, then just have the ISO version of it swap - for _. It would be good if this could also be tested on Visual Studio version 12 as I see IsoLocaleName() does something else for anything before 15. I only have 10 and 17 installed and I see we don't support anything before 12 on master per: "Unable to determine Visual Studio version: Visual Studio versions before 12.0 aren't supported. at L:/Projects/Postgres/d/src/tools/msvc/Mkvcbuild.pm line 93." David
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 3b0324ce18..4982fc7eb1 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -943,7 +943,7 @@ cache_locale_time(void) } -#if defined(WIN32) && defined(LC_MESSAGES) +#if defined(WIN32) /* * Convert a Windows setlocale() argument to a Unix-style one. * @@ -1692,6 +1692,16 @@ get_collation_actual_version(char collprovider, const char *collcollate) */ NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)}; WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH]; + char *shortlocale = IsoLocaleName(collcollate); + char *underscore; + + /* + * GetNLSVersionEx wants <language>-<REGION> format, whereas the ISO + * format is <language>_<REGION>. So replace the _ with - + */ + underscore = strchr(shortlocale, '_'); + if (underscore) + *underscore = '-'; /* These would be invalid arguments, but have no version. */ if (pg_strcasecmp("c", collcollate) == 0 || @@ -1699,12 +1709,12 @@ get_collation_actual_version(char collprovider, const char *collcollate) return NULL; /* For all other names, ask the OS. */ - MultiByteToWideChar(CP_ACP, 0, collcollate, -1, wide_collcollate, + MultiByteToWideChar(CP_ACP, 0, shortlocale, -1, wide_collcollate, LOCALE_NAME_MAX_LENGTH); if (!GetNLSVersionEx(COMPARE_STRING, wide_collcollate, &version)) ereport(ERROR, (errmsg("could not get collation version for locale \"%s\": error code %lu", - collcollate, + shortlocale, GetLastError()))); collversion = psprintf("%d.%d,%d.%d", (version.dwNLSVersion >> 8) & 0xFFFF,