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,

Reply via email to