Prevent locale-aware handling of upper, lower, and initcap when the
authorBruce Momjian <bruce@momjian.us>
Wed, 16 Mar 2005 00:02:49 +0000 (00:02 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 16 Mar 2005 00:02:49 +0000 (00:02 +0000)
locale is C.

Backpatch to 8.0.X because some operating systems were throwing errors
for such operations, rather than ignoring the locale when it was C.

src/backend/utils/adt/oracle_compat.c
src/backend/utils/adt/pg_locale.c
src/include/utils/pg_locale.h

index 870ed42d072edbc054a2c459f50502ca08a7f0a3..0d4828d79c2d5e30e93826e6b10951d7aaf6d5e3 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.57 2004/12/31 22:01:22 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.58 2005/03/16 00:02:48 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -166,8 +166,8 @@ Datum
 lower(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-   /* use wide char code only when max encoding length > one */
-   if (pg_database_encoding_max_length() > 1)
+   /* use wide char code only when max encoding length > 1 and ctype != C */
+   if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
    {
        text       *string = PG_GETARG_TEXT_P(0);
        text       *result;
@@ -228,8 +228,8 @@ Datum
 upper(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-   /* use wide char code only when max encoding length > one */
-   if (pg_database_encoding_max_length() > 1)
+   /* use wide char code only when max encoding length > 1 and ctype != C */
+   if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
    {
        text       *string = PG_GETARG_TEXT_P(0);
        text       *result;
@@ -293,8 +293,8 @@ Datum
 initcap(PG_FUNCTION_ARGS)
 {
 #ifdef USE_WIDE_UPPER_LOWER
-   /* use wide char code only when max encoding length > one */
-   if (pg_database_encoding_max_length() > 1)
+   /* use wide char code only when max encoding length > 1 and ctype != C */
+   if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
    {
        text       *string = PG_GETARG_TEXT_P(0);
        text       *result;
index 5b8d8e881027d0c317fe951b29477c1642d7809a..7c9c774d91b85a99926f3fd7aacbe6234b0fa4f7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.30 2005/01/01 05:43:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.31 2005/03/16 00:02:49 momjian Exp $
  *
  *-----------------------------------------------------------------------
  */
@@ -196,6 +196,33 @@ lc_collate_is_c(void)
 }
 
 
+/*
+ * We'd like to cache whether LC_CTYPE is C (or POSIX), so we can
+ * optimize a few code paths in various places.
+ */
+bool
+lc_ctype_is_c(void)
+{
+   /* Cache result so we only have to compute it once */
+   static int  result = -1;
+   char       *localeptr;
+
+   if (result >= 0)
+       return (bool) result;
+   localeptr = setlocale(LC_CTYPE, NULL);
+   if (!localeptr)
+       elog(ERROR, "invalid LC_CTYPE setting");
+
+   if (strcmp(localeptr, "C") == 0)
+       result = true;
+   else if (strcmp(localeptr, "POSIX") == 0)
+       result = true;
+   else
+       result = false;
+   return (bool) result;
+}
+
+
 /*
  * Frees the malloced content of a struct lconv.  (But not the struct
  * itself.)
index 6be1df3ab14b1639434e207ac1ad4a5977484337..ef138d1bcbf6a850da5eae37a8a7e4a91139fefb 100644 (file)
@@ -2,7 +2,7 @@
  *
  * PostgreSQL locale utilities
  *
- * $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.19 2005/01/01 05:43:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.20 2005/03/16 00:02:49 momjian Exp $
  *
  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
@@ -32,6 +32,7 @@ extern const char *locale_time_assign(const char *value,
                   bool doit, GucSource source);
 
 extern bool lc_collate_is_c(void);
+extern bool lc_ctype_is_c(void);
 
 /*
  * Return the POSIX lconv struct (contains number/money formatting