This short patch is too short. I send (I hope) last correct version. Multibyte lower, upper functions are called only for localized names, for others we call pg_tolower or pg_toupper still.

Regards
Pavel Stehule


Hello,

it's more correct patch and more short.

Regards
Pavel Stehule




Would you please modify this patch to use the functions in
oracle_compat.c?

---------------------------------------------------------------------------

Pavel Stehule wrote:
> Hello,
>
> this patch correct bug in to_char function with incorrect uppercased month's
> or day's name.
>
> Regards
> Pavel Stehule
>
> _________________________________________________________________
> Najdete si svou lasku a nove pratele na Match.com. http://www.msn.cz/

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
>                http://archives.postgresql.org

--
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

_________________________________________________________________
Citite se osamele? Poznejte nekoho vyjmecneho diky Match.com. http://www.msn.cz/


<< multibyte_upper.diff >>



---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
       subscribe-nomail command to [EMAIL PROTECTED] so that your
       message can get through to the mailing list cleanly

_________________________________________________________________
Citite se osamele? Poznejte nekoho vyjmecneho diky Match.com. http://www.msn.cz/
*** ./adt/formatting.c.orig	2007-02-04 13:09:09.000000000 +0100
--- ./adt/formatting.c	2007-02-04 15:58:52.000000000 +0100
***************
*** 82,87 ****
--- 82,88 ----
  #include "utils/int8.h"
  #include "utils/numeric.h"
  #include "utils/pg_locale.h"
+ #include "mb/pg_wchar.h"
  
  #define _(x)	gettext((x))
  
***************
*** 113,118 ****
--- 114,128 ----
  #define MAXFLOATWIDTH	64
  #define MAXDOUBLEWIDTH	128
  
+ /*
+  * External (defined in oracle_compat.c 
+  */
+ #if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
+ #define USE_WIDE_UPPER_LOWER
+ extern int upper_str(char *str);
+ extern int lower_str(char *str);
+ #endif
+ 
  /* ----------
   * External (defined in PgSQL datetime.c (timestamp utils))
   * ----------
***************
*** 946,951 ****
--- 956,970 ----
  static char *localize_day_full(int index);
  static char *localize_day(int index);
  
+ #ifdef USE_WIDE_UPPER_LOWER
+ static char *localized_str_toupper(char *buff);
+ static char *localized_str_tolower(char *buff);
+ #else
+ #define localized_str_toupper str_toupper
+ #define localized_str_tolower str_tolower
+ #endif /* USE_WIDE_UPPER_LOWER */
+ 
+ 
  /* ----------
   * Fast sequential search, use index for data selection which
   * go to seq. cycle (it is very fast for unwanted strings)
***************
*** 1500,1505 ****
--- 1519,1525 ----
  		*p_buff = pg_toupper((unsigned char) *p_buff);
  		++p_buff;
  	}
+ 
  	return buff;
  }
  
***************
*** 1523,1528 ****
--- 1543,1603 ----
  	return buff;
  }
  
+ 
+ #ifdef USE_WIDE_UPPER_LOWER
+ /* ----------
+  * Convert localized string to upper string. Input string is modified in place.
+  * ----------
+  */
+ static char *
+ localized_str_toupper(char *buff)
+ {
+ 	if (!buff)
+ 		return NULL;
+ 
+ 	if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
+ 		upper_str(buff);
+ 	else
+ 	{
+ 		char	   *p_buff = buff;
+ 
+ 		while (*p_buff)
+ 		{
+ 			*p_buff = pg_toupper((unsigned char) *p_buff);
+ 			++p_buff;
+ 		}
+ 	}
+ 
+ 	return buff;
+ }
+ 
+ /* ----------
+  * Convert localized string to upper string. Input string is modified in place.
+  * ----------
+  */
+ static char *
+ localized_str_tolower(char *buff)
+ {
+ 	if (!buff)
+ 		return NULL;
+ 
+ 	if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
+ 		lower_str(buff);
+ 	else
+ 	{
+ 		char	   *p_buff = buff;
+ 
+ 		while (*p_buff)
+ 		{
+ 			*p_buff = pg_toupper((unsigned char) *p_buff);
+ 			++p_buff;
+ 		}
+ 	}
+ 
+ 	return buff;
+ }
+ #endif /* USE_WIDE_UPPER_LOWER */
+ 
  /* ----------
   * Sequential search with to upper/lower conversion
   * ----------
***************
*** 2188,2197 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
  			else
  				strcpy(workbuff, months_full[tm->tm_mon - 1]);
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
  			return strlen(p_inout);
  
  		case DCH_Month:
--- 2263,2278 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
+ 				localized_str_toupper(workbuff);
+ 			}
  			else
+ 			{
  				strcpy(workbuff, months_full[tm->tm_mon - 1]);
! 				str_toupper(workbuff);
! 			}
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, workbuff);
  			return strlen(p_inout);
  
  		case DCH_Month:
***************
*** 2209,2218 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_month_full(tm->tm_mon - 1));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_MON:
--- 2290,2305 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
! 			{
! 				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
! 				localized_str_tolower(workbuff);
! 				sprintf(inout, "%*s", 0, workbuff);
! 			}
  			else
+ 			{
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_MON:
***************
*** 2220,2229 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(inout, localize_month(tm->tm_mon - 1));
  			else
  				strcpy(inout, months[tm->tm_mon - 1]);
! 			str_toupper(inout);
  			return strlen(p_inout);
  
  		case DCH_Mon:
--- 2307,2321 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_month(tm->tm_mon - 1));
+ 				localized_str_toupper(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, months[tm->tm_mon - 1]);
! 				str_toupper(inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_Mon:
***************
*** 2241,2250 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(inout, localize_month(tm->tm_mon - 1));
  			else
  				strcpy(inout, months[tm->tm_mon - 1]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_MM:
--- 2333,2347 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_month(tm->tm_mon - 1));
+ 				localized_str_tolower(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, months[tm->tm_mon - 1]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_MM:
***************
*** 2272,2287 ****
  		case DCH_DAY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(workbuff, localize_day_full(tm->tm_wday));
  			else
  				strcpy(workbuff, days[tm->tm_wday]);
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
  			return strlen(p_inout);
  
  		case DCH_Day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
  			return strlen(p_inout);
--- 2369,2390 ----
  		case DCH_DAY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(workbuff, localize_day_full(tm->tm_wday));
+ 				localized_str_toupper(workbuff);
+ 			}
  			else
+ 			{
  				strcpy(workbuff, days[tm->tm_wday]);
! 				str_toupper(workbuff);
! 			}
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, workbuff);
  			return strlen(p_inout);
  
  		case DCH_Day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));		    
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
  			return strlen(p_inout);
***************
*** 2289,2307 ****
  		case DCH_day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_DY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(inout, localize_day(tm->tm_wday));
  			else
  				strcpy(inout, days_short[tm->tm_wday]);
! 			str_toupper(inout);
  			return strlen(p_inout);
  
  		case DCH_Dy:
--- 2392,2423 ----
  		case DCH_day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 			{
! 				strcpy(workbuff, localize_day_full(tm->tm_wday));
! 				localized_str_tolower(workbuff);
! 				sprintf(inout, "%*s", 0, workbuff);
! 				
! 			}
  			else
+ 			{
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_DY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_day(tm->tm_wday));
+ 				localized_str_toupper(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, days_short[tm->tm_wday]);
! 				str_toupper(inout);
! 			}
! 			
  			return strlen(p_inout);
  
  		case DCH_Dy:
***************
*** 2315,2324 ****
  		case DCH_dy:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(inout, localize_day(tm->tm_wday));
  			else
  				strcpy(inout, days_short[tm->tm_wday]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_DDD:
--- 2431,2446 ----
  		case DCH_dy:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_day(tm->tm_wday));
+ 				localized_str_tolower(inout);
+ 				
+ 			}
  			else
+ 			{
  				strcpy(inout, days_short[tm->tm_wday]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_DDD:
*** ./adt/oracle_compat.c.orig	2007-02-04 12:35:14.000000000 +0100
--- ./adt/oracle_compat.c	2007-02-04 16:06:18.000000000 +0100
***************
*** 46,51 ****
--- 46,53 ----
   */
  #if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
  #define USE_WIDE_UPPER_LOWER
+ int upper_str(char *str);
+ int lower_str(char *str);
  #endif
  
  static text *dotrim(const char *string, int stringlen,
***************
*** 258,263 ****
--- 260,333 ----
  #define wcstotext	win32_wcstotext
  #endif   /* WIN32 */
  
+ #ifdef USE_WIDE_UPPER_LOWER
+ /* 
+  * upper_text is used for correct multibyte upper function str_toupper.
+  * Expected safety long buffer (used only for internal purpouse). 
+  * Returns length of converted string. lower_str is similar.
+  */
+ int
+ upper_str(char *str)
+ {
+ 	wchar_t	  *workspace;
+ 	text 	  *txt;
+ 	text	  *result;
+ 	int 		nbytes = strlen(str);
+ 	int	   	i;
+ 	
+ 	txt = palloc(nbytes + VARHDRSZ);
+ 	memcpy(VARDATA(txt), str, nbytes);
+ 	VARATT_SIZEP(txt) = nbytes + VARHDRSZ;
+ 
+ 	workspace = texttowcs(txt);
+ 
+ 	for (i = 0; workspace[i] != 0; i++)
+ 		workspace[i] = towupper(workspace[i]);
+ 
+ 	result = wcstotext(workspace, i);
+ 
+ 	/* copy back result */	
+ 	nbytes = VARSIZE(result) - VARHDRSZ;
+ 	memcpy(str, VARDATA(result), nbytes);
+ 	str[nbytes] = '\0';
+ 
+ 	pfree(workspace);
+ 	pfree(result);
+ 	
+ 	return nbytes;
+ }
+ 
+ int
+ lower_str(char *str)
+ {
+ 	wchar_t	  *workspace;
+ 	text 	  *txt;
+ 	text	  *result;
+ 	int 		nbytes = strlen(str);
+ 	int	   	i;
+ 	
+ 	txt = palloc(nbytes + VARHDRSZ);
+ 	memcpy(VARDATA(txt), str, nbytes);
+ 	VARATT_SIZEP(txt) = nbytes + VARHDRSZ;
+ 
+ 	workspace = texttowcs(txt);
+ 
+ 	for (i = 0; workspace[i] != 0; i++)
+ 		workspace[i] = towlower(workspace[i]);
+ 
+ 	result = wcstotext(workspace, i);
+ 
+ 	/* copy back result */	
+ 	nbytes = VARSIZE(result) - VARHDRSZ;
+ 	memcpy(str, VARDATA(result), nbytes);
+ 	str[nbytes] = '\0';
+ 
+ 	pfree(workspace);
+ 	pfree(result);
+ 	
+ 	return nbytes;
+ }
+ #endif	/* USE_WIDE_UPPER_LOWER */
  
  /********************************************************************
   *

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Reply via email to