Search Postgresql Archives

Re: trouble with to_char('L')

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux