aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/adt/oracle_compat.c14
-rw-r--r--src/backend/utils/adt/pg_locale.c29
-rw-r--r--src/include/utils/pg_locale.h3
3 files changed, 37 insertions, 9 deletions
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 870ed42d072..0d4828d79c2 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.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;
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 5b8d8e88102..7c9c774d91b 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -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 $
*
*-----------------------------------------------------------------------
*/
@@ -197,6 +197,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.)
*/
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 6be1df3ab14..ef138d1bcbf 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -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