Where are we on this issue? --------------------------------------------------------------------------- Hiroshi Inoue wrote: > Tom Lane wrote: > > Alvaro Herrera <alvherre@xxxxxxxxxxxxxxxxx> writes: > >> Does this imply that we shouldn't allow UTF8 database on Windows at all? > > > > That would be pretty unfortunate :-( > > > > I think what this suggests is that there probably needs to be some > > encoding conversion logic near the places we examine localeconv() > > output. > > Attached is a patch to the current CVS. > It uses a similar way like LC_TIME stuff does. > > regards, > Hiroshi Inoue > Index: pg_locale.c > =================================================================== > RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v > retrieving revision 1.49 > diff -c -c -r1.49 pg_locale.c > *** pg_locale.c 1 Apr 2009 09:17:32 -0000 1.49 > --- pg_locale.c 22 Apr 2009 21:08:33 -0000 > *************** > *** 386,391 **** > --- 386,449 ---- > free(s->positive_sign); > } > > + #ifdef WIN32 > + #define MAX_BYTES_PER_CHARACTER 4 > + static char *dbstr_win32(bool matchenc, const char *str) > + { > + int encoding = GetDatabaseEncoding(); > + bool is_ascii = true; > + size_t len, ilen, wclen, dstlen; > + wchar_t *wbuf; > + char *dst, *ibuf; > + > + if (matchenc) > + return strdup(str); > + /* Is the str an ascii string ? */ > + for (ibuf = str; *ibuf; ibuf++) > + { > + if (!isascii(*ibuf)) > + { > + is_ascii = false; > + break; > + } > + } > + /* Simply returns the strdup()ed ascii string */ > + if (is_ascii) > + return strdup(str); > + > + ilen = strlen(str) + 1; > + wclen = ilen * sizeof(wchar_t); > + wbuf = (wchar_t *) palloc(wclen); > + len = mbstowcs(wbuf, str, ilen); > + if (len == -1) > + elog(ERROR, > + "could not convert string to Wide characters:error %lu", GetLastError()); > + > + dstlen = len * MAX_BYTES_PER_CHARACTER + 1; > + dst = malloc(dstlen); > + > + len = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, dst, dstlen, NULL, NULL); > + pfree(wbuf); > + if (len == 0) > + elog(ERROR, > + "could not convert string to UTF-8:error %lu", GetLastError()); > + > + dst[len] = '\0'; > + if (encoding != PG_UTF8) > + { > + char *convstr = pg_do_encoding_conversion(dst, len, PG_UTF8, encoding); > + if (dst != convstr) > + { > + strlcpy(dst, convstr, dstlen); > + pfree(convstr); > + } > + } > + > + return dst; > + } > + > + #define strdup(str) dbstr_win32(is_encoding_match, str) > + #endif /* WIN32 */ > > /* > * Return the POSIX lconv struct (contains number/money formatting > *************** > *** 398,403 **** > --- 456,466 ---- > struct lconv *extlconv; > char *save_lc_monetary; > char *save_lc_numeric; > + #ifdef WIN32 > + char *save_lc_ctype = NULL; > + bool lc_ctype_change = false, is_encoding_match; > + #endif /* WIN32 */ > + > > /* Did we do it already? */ > if (CurrentLocaleConvValid) > *************** > *** 413,418 **** > --- 476,492 ---- > if (save_lc_numeric) > save_lc_numeric = pstrdup(save_lc_numeric); > > + #ifdef WIN32 > + save_lc_ctype = setlocale(LC_CTYPE, NULL); > + if (save_lc_ctype && stricmp(locale_monetary, save_lc_ctype) != 0) > + { > + lc_ctype_change = true; > + save_lc_ctype = pstrdup(save_lc_ctype); > + setlocale(LC_CTYPE, locale_monetary); > + } > + is_encoding_match = (pg_get_encoding_from_locale(locale_monetary) == GetDatabaseEncoding()); > + #endif > + > setlocale(LC_MONETARY, locale_monetary); > setlocale(LC_NUMERIC, locale_numeric); > > *************** > *** 437,442 **** > --- 511,524 ---- > CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn; > > /* Try to restore internal settings */ > + #ifdef WIN32 > + #undef strdup > + if (lc_ctype_change) > + { > + setlocale(LC_CTYPE, save_lc_ctype); > + pfree(save_lc_ctype); > + } > + #endif /* WIN32 */ > if (save_lc_monetary) > { > setlocale(LC_MONETARY, save_lc_monetary); > > > -- > Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general -- Bruce Momjian <bruce@xxxxxxxxxx> http://momjian.us EnterpriseDB http://enterprisedb.com PG East: http://www.enterprisedb.com/community/nav-pg-east-2010.do + If your life is a hard drive, Christ can be your backup. + -- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general