From 11745364d074f3a7ee54c98fad55cfb5c5149326 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sun, 10 Apr 2011 00:14:20 +0300 Subject: [PATCH] Add collation support on Windows (MSVC build) There is not yet support in initdb to populate the pg_collation catalog, but if that is done manually, the rest should work. --- src/backend/utils/adt/pg_locale.c | 15 +++++++++++++++ src/backend/utils/adt/varlena.c | 5 +++++ src/bin/initdb/initdb.c | 2 +- src/include/pg_config.h.win32 | 8 +++++++- src/include/port/win32.h | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index cbf74a07f2..09ff926cba 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -971,8 +971,12 @@ pg_newlocale_from_collation(Oid collid) if (strcmp(collcollate, collctype) == 0) { /* Normal case where they're the same */ +#ifndef WIN32 result = newlocale(LC_COLLATE_MASK | LC_CTYPE_MASK, collcollate, NULL); +#else + result = _create_locale(LC_ALL, collcollate); +#endif if (!result) ereport(ERROR, (errcode_for_file_access(), @@ -981,6 +985,7 @@ pg_newlocale_from_collation(Oid collid) } else { +#ifndef WIN32 /* We need two newlocale() steps */ locale_t loc1; @@ -996,6 +1001,16 @@ pg_newlocale_from_collation(Oid collid) (errcode_for_file_access(), errmsg("could not create locale \"%s\": %m", collctype))); +#else + /* + * XXX The _create_locale() API doesn't appear to support + * this. Could perhaps be worked around by changing + * pg_locale_t to contain two separate fields. + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("collations with different collate and ctype values are not supported on this platform"))); +#endif } cache_entry->locale = result; diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 3587fe4595..7a54521475 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -1374,6 +1374,11 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid) ((LPWSTR) a2p)[r] = 0; errno = 0; +#ifdef HAVE_LOCALE_T + if (mylocale) + result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, mylocale); + else +#endif result = wcscoll((LPWSTR) a1p, (LPWSTR) a2p); if (result == 2147483647) /* _NLSCMPERROR; missing from mingw * headers */ diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 9ea2ea39ce..e87edb88a9 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1571,7 +1571,7 @@ setup_collation(void) fputs(_("creating collations ... "), stdout); fflush(stdout); -#ifdef HAVE_LOCALE_T +#if defined(HAVE_LOCALE_T) && !defined(WIN32) snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 79b803616d..177bca1bd5 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -5,7 +5,7 @@ * changes to be valid for Visual C++ (and compatible): * * HAVE_CBRT, HAVE_FUNCNAME_FUNC, HAVE_GETOPT, HAVE_GETOPT_H, - * HAVE_GETOPT_LONG, HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL, + * HAVE_GETOPT_LONG, HAVE_LOCALE_T, HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL, * HAVE_STRTOULL, HAVE_STRUCT_OPTION, ENABLE_THREAD_SAFETY, * USE_INLINE, inline */ @@ -244,6 +244,9 @@ #define HAVE_LL_CONSTANTS 1 #endif +/* Define to 1 if the system has the type `locale_t'. */ +#define HAVE_LOCALE_T 1 + /* Define to 1 if `long int' works and is 64 bits. */ /* #undef HAVE_LONG_INT_64 */ @@ -547,6 +550,9 @@ /* Define to build with Kerberos 5 support. (--with-krb5) */ /* #undef KRB5 */ +/* Define to 1 if `locale_t' requires . */ +/* #undef LOCALE_T_IN_XLOCALE */ + /* Define to the location of locale files. */ /* #undef LOCALEDIR */ diff --git a/src/include/port/win32.h b/src/include/port/win32.h index 5e193223d6..f442cca523 100644 --- a/src/include/port/win32.h +++ b/src/include/port/win32.h @@ -275,6 +275,20 @@ typedef int pid_t; #define EBADFD WSAENOTSOCK #define EOPNOTSUPP WSAEOPNOTSUPP +/* + * Extended locale functions with gratuitous underscore prefixes. + * (These APIs are nevertheless fully documented by Microsoft.) + */ +#define locale_t _locale_t +#define tolower_l _tolower_l +#define toupper_l _toupper_l +#define towlower_l _towlower_l +#define towupper_l _towupper_l +#define isalnum_l _isalnum_l +#define iswalnum_l _iswalnum_l +#define strcoll_l _strcoll_l +#define wcscoll_l _wcscoll_l + /* In backend/port/win32/signal.c */ extern PGDLLIMPORT volatile int pg_signal_queue;