Received: from localhost (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 9D1D164FC52 for ; Mon, 24 Nov 2008 11:00:50 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 33708-07 for ; Mon, 24 Nov 2008 11:00:47 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from svr2.hagander.net (svr2.hagander.net [88.198.128.226]) by mail.postgresql.org (Postfix) with ESMTP id DD81564FC44 for ; Mon, 24 Nov 2008 11:00:46 -0400 (AST) Received: from dynamic.hagander.net ([127.0.0.1]) (encrypted and authenticated) by svr2.hagander.net (Postfix) with ESMTP id 311E7DCCF28; Mon, 24 Nov 2008 16:00:43 +0100 (CET) Received: from [127.0.0.1] (localhost [127.0.0.1]) by mha-laptop.hagander.net (Postfix) with ESMTP id 8D035124122; Mon, 24 Nov 2008 16:00:42 +0100 (CET) Message-ID: <492AC19A.6090401@hagander.net> Date: Mon, 24 Nov 2008 16:00:42 +0100 From: Magnus Hagander User-Agent: Thunderbird 2.0.0.17 (X11/20080925) MIME-Version: 1.0 To: Tom Lane CC: Hiroshi Saito , ITAGAKI Takahiro , Jaime Casanova , Alvaro Herrera , pgsql-hackers Subject: Re: [PATCHES] Solve a problem of LC_TIME of windows. References: <20081104094301.7EE8.52131E4D@oss.ntt.co.jp> <3073cc9b0811102212n278644a8o7169f7c5ea562081@mail.gmail.com> <20081111152112.B605.52131E4D@oss.ntt.co.jp> <446F4763B989489C9B626D21AB9F6C7F@HIRO57887DE653> <492AA5CD.8050001@hagander.net> <18269.1227538234@sss.pgh.pa.us> <492AC031.7010901@hagander.net> In-Reply-To: <492AC031.7010901@hagander.net> X-Enigmail-Version: 0.95.0 Content-Type: multipart/mixed; boundary="------------010101050005070208080009" X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200811/1573 X-Sequence-Number: 128285 This is a multi-part message in MIME format. --------------010101050005070208080009 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Magnus Hagander wrote: > Tom Lane wrote: >> Magnus Hagander writes: >>> *** a/src/backend/utils/adt/pg_locale.c >>> --- b/src/backend/utils/adt/pg_locale.c >>> *************** >>> *** 54,59 **** >>> --- 54,60 ---- >>> #include "utils/memutils.h" >>> #include "utils/pg_locale.h" >> >>> + #include "mb/pg_wchar.h" >> >>> #define MAX_L10N_DATA 80 >> Please stick to the convention of including include files in >> alphabetical order. > > Check. > > >>> + strftime_win32(char *dst, size_t dstlen, const char *format, const struct tm *tm) >>> + { >>> + size_t len; >>> + wchar_t wbuf[MAX_L10N_DATA]; >>> + int encoding; >>> + >>> + encoding = GetDatabaseEncoding(); >>> + if (encoding == PG_SQL_ASCII) >>> + return len; >> Surely this is returning an uninitialized variable, not to mention >> failing to accomplish any of the goals of the function. I don't think >> breaking things completely for SQL_ASCII was part of the plan. > > Gah, true, that's me breaking it. That was correct in Hiroshi-san's > patch. My bad, sorry. > > >>> + ereport(ERROR, >>> + (errmsg("could not convert string to UTF-8:error %lu", GetLastError()))); >> This is not exactly per message style guidelines. Maybe it's just a >> can't-happen case, but if so make it elog not ereport. > > Check. Forgot the attachment. //Magnus --------------010101050005070208080009 Content-Type: text/x-diff; name="pg_locale.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="pg_locale.diff" *** a/src/backend/utils/adt/pg_locale.c --- b/src/backend/utils/adt/pg_locale.c *************** *** 51,56 **** --- 51,57 ---- #include #include "catalog/pg_control.h" + #include "mb/pg_wchar.h" #include "utils/memutils.h" #include "utils/pg_locale.h" *************** *** 452,457 **** PGLC_localeconv(void) --- 453,507 ---- return &CurrentLocaleConv; } + #ifdef WIN32 + /* + * On win32, strftime() returns the encoding in CP_ACP, which is likely + * different from SERVER_ENCODING. This is especially important in Japanese + * versions of Windows which will use SJIS encoding, which we don't support + * as a server encoding. + * + * Replace strftime() with a version that gets the string in UTF16 and then + * converts it to the appropriate encoding as necessary. + */ + static size_t + strftime_win32(char *dst, size_t dstlen, const char *format, const struct tm *tm) + { + size_t len; + wchar_t wbuf[MAX_L10N_DATA]; + int encoding; + + encoding = GetDatabaseEncoding(); + if (encoding == PG_SQL_ASCII) + return strftime(dst, dstlen, format, tm); + + len = wcsftime(wbuf, sizeof(wbuf), format, tm); + if (len == 0) + /* strftime call failed - return 0 with the contents of dst unspecified */ + return 0; + + len = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, dst, dstlen, NULL, NULL); + 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) + { + StrNCpy(dst, convstr, dstlen); + len = strlen(dst); + } + } + + return len; + } + + #define strftime(a,b,c,d) strftime_win32(a,b,c,d) + + #endif /* WIN32 */ + /* * Update the lc_time localization cache variables if needed. --------------010101050005070208080009--