aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-03-25 21:47:22 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-03-25 21:47:22 -0400
commitc7cea267de3ca05b29a57b9d113b95ef3793c8d8 (patch)
tree87c2c9b6c660a843287e0ac8ac0567d31c5ab2ed /src/backend/commands/dbcommands.c
parent8279eb4191c7ab9920c72ec8eec5df0e7b8c7530 (diff)
downloadpostgresql-c7cea267de3ca05b29a57b9d113b95ef3793c8d8.tar.gz
postgresql-c7cea267de3ca05b29a57b9d113b95ef3793c8d8.zip
Replace empty locale name with implied value in CREATE DATABASE and initdb.
setlocale() accepts locale name "" as meaning "the locale specified by the process's environment variables". Historically we've accepted that for Postgres' locale settings, too. However, it's fairly unsafe to store an empty string in a new database's pg_database.datcollate or datctype fields, because then the interpretation could vary across postmaster restarts, possibly resulting in index corruption and other unpleasantness. Instead, we should expand "" to whatever it means at the moment of calling CREATE DATABASE, which we can do by saving the value returned by setlocale(). For consistency, make initdb set up the initial lc_xxx parameter values the same way. initdb was already doing the right thing for empty locale names, but it did not replace non-empty names with setlocale results. On a platform where setlocale chooses to canonicalize the spellings of locale names, this would result in annoying inconsistency. (It seems that popular implementations of setlocale don't do such canonicalization, which is a pity, but the POSIX spec certainly allows it to be done.) The same risk of inconsistency leads me to not venture back-patching this, although it could certainly be seen as a longstanding bug. Per report from Jeff Davis, though this is not his proposed patch.
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 91d74815287..9721ce9e0a6 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -123,6 +123,7 @@ createdb(const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
+ char *canonname;
int encoding = -1;
int dbconnlimit = -1;
int notherbackends;
@@ -318,15 +319,17 @@ createdb(const CreatedbStmt *stmt)
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid server encoding %d", encoding)));
- /* Check that the chosen locales are valid */
- if (!check_locale(LC_COLLATE, dbcollate))
+ /* Check that the chosen locales are valid, and get canonical spellings */
+ if (!check_locale(LC_COLLATE, dbcollate, &canonname))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid locale name %s", dbcollate)));
- if (!check_locale(LC_CTYPE, dbctype))
+ dbcollate = canonname;
+ if (!check_locale(LC_CTYPE, dbctype, &canonname))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid locale name %s", dbctype)));
+ dbctype = canonname;
check_encoding_locale_matches(encoding, dbcollate, dbctype);