aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/pg_locale.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2020-03-25 15:56:00 +1300
committerThomas Munro <tmunro@postgresql.org>2020-03-25 16:04:32 +1300
commit352f6f2df60f8725cf6e81141985977d76c169d3 (patch)
tree3ad81a091028dcea9b41b680fd7b4dc495cbd642 /src/backend/utils/adt/pg_locale.c
parent382a821907e76bf6068492a164fdfc57578391f4 (diff)
downloadpostgresql-352f6f2df60f8725cf6e81141985977d76c169d3.tar.gz
postgresql-352f6f2df60f8725cf6e81141985977d76c169d3.zip
Add collation versions for Windows.
On Vista and later, use GetNLSVersionEx() to request collation version information. Reviewed-by: Juan José Santamaría Flecha <juanjo.santamaria@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGJvqup3s%2BJowVTcacZADO6dOhfdBmvOPHLS3KXUJu41Jw%40mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r--src/backend/utils/adt/pg_locale.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index b42122f9cea..2562eb5416d 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1555,6 +1555,33 @@ get_collation_actual_version(char collprovider, const char *collcollate)
/* 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 NULL;
+
+ /* 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("%d.%d,%d.%d",
+ (version.dwNLSVersion >> 8) & 0xFFFF,
+ version.dwNLSVersion & 0xFF,
+ (version.dwDefinedVersion >> 8) & 0xFFFF,
+ version.dwDefinedVersion & 0xFF);
#endif
}