From 5174d658dc7ab05964518bcfc82b82e408fb6a17 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Fri, 8 Nov 2019 12:01:05 +1300 Subject: [PATCH 1/2] Add collation versions for Windows. Work in progress. --- src/backend/utils/adt/pg_locale.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index fcdbaae37b..36f70279e5 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1532,6 +1532,29 @@ get_collation_actual_version(char collprovider, const char *collcollate) #if defined(__GLIBC__) /* Use the glibc version because we don't have anything better. */ collversion = pstrdup(gnu_get_libc_version()); +#elif defined(WIN32) && _WIN32_WINNT >= 0x0600 + /* + * If we are targeting Windows Vista and above, we can ask for a + * name given a collation name (earlier versions required a + * location code that we don't have). + */ + NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)}; + WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH]; + + /* These would be invalid arguments, but have no version. */ + if (pg_strcasecmp("c", collcollate) == 0 || + pg_strcasecmp("posix", collcollate) == 0) + return pstrdup(""); + + /* For all other names, ask the OS. */ + MultiByteToWideChar(CP_ACP, 0, collcollate, -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, + GetLastError()))); + collversion = psprintf("%x,%x", version.dwNLSVersion, version.dwDefinedVersion); #endif } -- 2.23.0