]> granicus.if.org Git - postgresql/commitdiff
Add collation support on Windows (MSVC build)
authorPeter Eisentraut <peter_e@gmx.net>
Sat, 9 Apr 2011 21:14:20 +0000 (00:14 +0300)
committerPeter Eisentraut <peter_e@gmx.net>
Sat, 9 Apr 2011 21:15:41 +0000 (00:15 +0300)
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
src/backend/utils/adt/varlena.c
src/bin/initdb/initdb.c
src/include/pg_config.h.win32
src/include/port/win32.h

index cbf74a07f2dcde385578562987d6ce486501505b..09ff926cba61342b2e52aa399ad13739f6c800f0 100644 (file)
@@ -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;
index 3587fe4595189c242dec29e28a3ada55f16e53ec..7a54521475519c3fe87f7cd59f4a418753d6ab50 100644 (file)
@@ -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 */
index 9ea2ea39cee2346d5b4ee97f74a3f80e218d0e4b..e87edb88a90c54bca8b70775d18d5f565171e3f4 100644 (file)
@@ -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,
index 79b803616de3f56105067fb8e9663c3d7a0ce2ad..177bca1bd542e4cf5bdca296ab1ef4d737c05dfb 100644 (file)
@@ -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
  */
 #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 */
 
 /* Define to build with Kerberos 5 support. (--with-krb5) */
 /* #undef KRB5 */
 
+/* Define to 1 if `locale_t' requires <xlocale.h>. */
+/* #undef LOCALE_T_IN_XLOCALE */
+
 /* Define to the location of locale files. */
 /* #undef LOCALEDIR */
 
index 5e193223d66e1fa4aaadc4cce49888b1f18269d5..f442cca5236eb6dce51aad877ce4bb19c0f92136 100644 (file)
@@ -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;