From 7845bfc095547a7ef16844236e76ffc5bec50c70 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 6 Jun 2004 22:17:01 +0000
Subject: [PATCH] Dept of second thoughts: don't use the new wide-character
 upper/lower code if we are running in a single-byte encoding.  No point in
 the extra overhead in that case.

---
 src/backend/utils/adt/oracle_compat.c | 192 +++++++++++++-------------
 1 file changed, 99 insertions(+), 93 deletions(-)

diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index ddbe890dd5..18a0e9e804 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	$PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.52 2004/05/26 16:16:03 tgl Exp $
+ *	$PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.53 2004/06/06 22:17:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -166,40 +166,44 @@ Datum
 lower(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-	text	   *string = PG_GETARG_TEXT_P(0);
-	text	   *result;
-	wchar_t	   *workspace;
-	int			i;
-
-	workspace = texttowcs(string);
+	/* use wide char code only when max encoding length > one */
+	if (pg_database_encoding_max_length() > 1)
+	{
+		text	   *string = PG_GETARG_TEXT_P(0);
+		text	   *result;
+		wchar_t	   *workspace;
+		int			i;
 
-	for (i = 0; workspace[i] != 0; i++)
-		workspace[i] = towlower(workspace[i]);
+		workspace = texttowcs(string);
 
-	result = wcstotext(workspace, i);
+		for (i = 0; workspace[i] != 0; i++)
+			workspace[i] = towlower(workspace[i]);
 
-	pfree(workspace);
+		result = wcstotext(workspace, i);
 
-	PG_RETURN_TEXT_P(result);
+		pfree(workspace);
 
-#else /* !USE_WIDE_UPPER_LOWER */
+		PG_RETURN_TEXT_P(result);
+	}
+	else
+#endif /* USE_WIDE_UPPER_LOWER */
+	{
+		text	   *string = PG_GETARG_TEXT_P_COPY(0);
+		char	   *ptr;
+		int			m;
 
-	text	   *string = PG_GETARG_TEXT_P_COPY(0);
-	char	   *ptr;
-	int			m;
+		/* Since we copied the string, we can scribble directly on the value */
+		ptr = VARDATA(string);
+		m = VARSIZE(string) - VARHDRSZ;
 
-	/* Since we copied the string, we can scribble directly on the value */
-	ptr = VARDATA(string);
-	m = VARSIZE(string) - VARHDRSZ;
+		while (m-- > 0)
+		{
+			*ptr = tolower((unsigned char) *ptr);
+			ptr++;
+		}
 
-	while (m-- > 0)
-	{
-		*ptr = tolower((unsigned char) *ptr);
-		ptr++;
+		PG_RETURN_TEXT_P(string);
 	}
-
-	PG_RETURN_TEXT_P(string);
-#endif /* USE_WIDE_UPPER_LOWER */
 }
 
 
@@ -221,40 +225,44 @@ Datum
 upper(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-	text	   *string = PG_GETARG_TEXT_P(0);
-	text	   *result;
-	wchar_t	   *workspace;
-	int			i;
-
-	workspace = texttowcs(string);
+	/* use wide char code only when max encoding length > one */
+	if (pg_database_encoding_max_length() > 1)
+	{
+		text	   *string = PG_GETARG_TEXT_P(0);
+		text	   *result;
+		wchar_t	   *workspace;
+		int			i;
 
-	for (i = 0; workspace[i] != 0; i++)
-		workspace[i] = towupper(workspace[i]);
+		workspace = texttowcs(string);
 
-	result = wcstotext(workspace, i);
+		for (i = 0; workspace[i] != 0; i++)
+			workspace[i] = towupper(workspace[i]);
 
-	pfree(workspace);
+		result = wcstotext(workspace, i);
 
-	PG_RETURN_TEXT_P(result);
+		pfree(workspace);
 
-#else /* !USE_WIDE_UPPER_LOWER */
+		PG_RETURN_TEXT_P(result);
+	}
+	else
+#endif /* USE_WIDE_UPPER_LOWER */
+	{
+		text	   *string = PG_GETARG_TEXT_P_COPY(0);
+		char	   *ptr;
+		int			m;
 
-	text	   *string = PG_GETARG_TEXT_P_COPY(0);
-	char	   *ptr;
-	int			m;
+		/* Since we copied the string, we can scribble directly on the value */
+		ptr = VARDATA(string);
+		m = VARSIZE(string) - VARHDRSZ;
 
-	/* Since we copied the string, we can scribble directly on the value */
-	ptr = VARDATA(string);
-	m = VARSIZE(string) - VARHDRSZ;
+		while (m-- > 0)
+		{
+			*ptr = toupper((unsigned char) *ptr);
+			ptr++;
+		}
 
-	while (m-- > 0)
-	{
-		*ptr = toupper((unsigned char) *ptr);
-		ptr++;
+		PG_RETURN_TEXT_P(string);
 	}
-
-	PG_RETURN_TEXT_P(string);
-#endif /* USE_WIDE_UPPER_LOWER */
 }
 
 
@@ -279,58 +287,56 @@ Datum
 initcap(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-	text	   *string = PG_GETARG_TEXT_P(0);
-	text	   *result;
-	wchar_t	   *workspace;
-	int			wasalnum = 0;
-	int			i;
-
-	workspace = texttowcs(string);
-
-	for (i = 0; workspace[i] != 0; i++)
+	/* use wide char code only when max encoding length > one */
+	if (pg_database_encoding_max_length() > 1)
 	{
-		if (wasalnum)
-			workspace[i] = towlower(workspace[i]);
-		else
-			workspace[i] = towupper(workspace[i]);
-		wasalnum = iswalnum(workspace[i]);
-	}
+		text	   *string = PG_GETARG_TEXT_P(0);
+		text	   *result;
+		wchar_t	   *workspace;
+		int			wasalnum = 0;
+		int			i;
 
-	result = wcstotext(workspace, i);
+		workspace = texttowcs(string);
 
-	pfree(workspace);
+		for (i = 0; workspace[i] != 0; i++)
+		{
+			if (wasalnum)
+				workspace[i] = towlower(workspace[i]);
+			else
+				workspace[i] = towupper(workspace[i]);
+			wasalnum = iswalnum(workspace[i]);
+		}
 
-	PG_RETURN_TEXT_P(result);
+		result = wcstotext(workspace, i);
 
-#else /* !USE_WIDE_UPPER_LOWER */
+		pfree(workspace);
 
-	text	   *string = PG_GETARG_TEXT_P_COPY(0);
-	char	   *ptr;
-	int			m;
+		PG_RETURN_TEXT_P(result);
+	}
+	else
+#endif /* USE_WIDE_UPPER_LOWER */
+	{
+		text	   *string = PG_GETARG_TEXT_P_COPY(0);
+		int			wasalnum = 0;
+		char	   *ptr;
+		int			m;
 
-	/* Since we copied the string, we can scribble directly on the value */
-	ptr = VARDATA(string);
-	m = VARSIZE(string) - VARHDRSZ;
+		/* Since we copied the string, we can scribble directly on the value */
+		ptr = VARDATA(string);
+		m = VARSIZE(string) - VARHDRSZ;
 
-	if (m > 0)
-	{
-		*ptr = toupper((unsigned char) *ptr);
-		ptr++;
-		m--;
-	}
+		while (m-- > 0)
+		{
+			if (wasalnum)
+				*ptr = tolower((unsigned char) *ptr);
+			else
+				*ptr = toupper((unsigned char) *ptr);
+			wasalnum = isalnum((unsigned char) *ptr);
+			ptr++;
+		}
 
-	while (m-- > 0)
-	{
-		/* Oracle capitalizes after all non-alphanumeric */
-		if (!isalnum((unsigned char) ptr[-1]))
-			*ptr = toupper((unsigned char) *ptr);
-		else
-			*ptr = tolower((unsigned char) *ptr);
-		ptr++;
+		PG_RETURN_TEXT_P(string);
 	}
-
-	PG_RETURN_TEXT_P(string);
-#endif /* USE_WIDE_UPPER_LOWER */
 }
 
 
-- 
2.40.0