diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/pg_locale.c | 43 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 26 |
2 files changed, 53 insertions, 16 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index dfc6c886a52..4b57d5791e0 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-2008, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.41 2008/05/19 18:08:16 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.42 2008/09/23 09:20:36 heikki Exp $ * *----------------------------------------------------------------------- */ @@ -76,7 +76,7 @@ static bool CurrentLCTimeValid = false; /* Environment variable storage area */ -#define LC_ENV_BUFSIZE (LOCALE_NAME_BUFLEN + 20) +#define LC_ENV_BUFSIZE (NAMEDATALEN + 20) static char lc_collate_envbuf[LC_ENV_BUFSIZE]; static char lc_ctype_envbuf[LC_ENV_BUFSIZE]; @@ -189,6 +189,31 @@ pg_perm_setlocale(int category, const char *locale) } +/* + * Is the locale name valid for the locale category? + */ +bool +check_locale(int category, const char *value) +{ + char *save; + bool ret; + + save = setlocale(category, NULL); + if (!save) + return false; /* won't happen, we hope */ + + /* save may be pointing at a modifiable scratch variable, see above */ + save = pstrdup(save); + + /* set the locale with setlocale, to see if it accepts it. */ + ret = (setlocale(category, value) != NULL); + + setlocale(category, save); /* assume this won't fail */ + pfree(save); + + return ret; +} + /* GUC assign hooks */ /* @@ -203,21 +228,9 @@ pg_perm_setlocale(int category, const char *locale) static const char * locale_xxx_assign(int category, const char *value, bool doit, GucSource source) { - char *save; - - save = setlocale(category, NULL); - if (!save) - return NULL; /* won't happen, we hope */ - - /* save may be pointing at a modifiable scratch variable, see above */ - save = pstrdup(save); - - if (!setlocale(category, value)) + if (!check_locale(category, value)) value = NULL; /* set failure return marker */ - setlocale(category, save); /* assume this won't fail */ - pfree(save); - /* need to reload cache next time? */ if (doit && value != NULL) { diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 6b66b2e3926..b6f9718b7aa 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.185 2008/09/11 14:01:09 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.186 2008/09/23 09:20:36 heikki Exp $ * * *------------------------------------------------------------------------- @@ -159,6 +159,8 @@ CheckMyDatabase(const char *name, bool am_superuser) { HeapTuple tup; Form_pg_database dbform; + char *collate; + char *ctype; /* Fetch our real pg_database row */ tup = SearchSysCache(DATABASEOID, @@ -240,6 +242,28 @@ CheckMyDatabase(const char *name, bool am_superuser) /* If we have no other source of client_encoding, use server encoding */ SetConfigOption("client_encoding", GetDatabaseEncodingName(), PGC_BACKEND, PGC_S_DEFAULT); + + /* assign locale variables */ + collate = NameStr(dbform->datcollate); + ctype = NameStr(dbform->datctype); + + if (setlocale(LC_COLLATE, collate) == NULL) + ereport(FATAL, + (errmsg("database locale is incompatible with operating system"), + errdetail("The database was initialized with LC_COLLATE \"%s\", " + " which is not recognized by setlocale().", collate), + errhint("Recreate the database with another locale or install the missing locale."))); + + if (setlocale(LC_CTYPE, ctype) == NULL) + ereport(FATAL, + (errmsg("database locale is incompatible with operating system"), + errdetail("The database was initialized with LC_CTYPE \"%s\", " + " which is not recognized by setlocale().", ctype), + errhint("Recreate the database with another locale or install the missing locale."))); + + /* Make the locale settings visible as GUC variables, too */ + SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE); + SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE); /* * Lastly, set up any database-specific configuration variables. |