Re: [PATCHES] Solve a problem of LC_TIME of windows. - Mailing list pgsql-hackers

From Magnus Hagander
Subject Re: [PATCHES] Solve a problem of LC_TIME of windows.
Date
Msg-id 492AC19A.6090401@hagander.net
Whole thread Raw
In response to Re: [PATCHES] Solve a problem of LC_TIME of windows.  (Magnus Hagander <magnus@hagander.net>)
List pgsql-hackers
Magnus Hagander wrote:
> Tom Lane wrote:
>> Magnus Hagander <magnus@hagander.net> 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

*** a/src/backend/utils/adt/pg_locale.c
--- b/src/backend/utils/adt/pg_locale.c
***************
*** 51,56 ****
--- 51,57 ----
  #include <time.h>

  #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.

pgsql-hackers by date:

Previous
From: Magnus Hagander
Date:
Subject: Re: [COMMITTERS] pgsql: Add support for matching wildcard server certificates to the new
Next
From: "Robert Haas"
Date:
Subject: Re: blatantly a bug in the documentation