aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-28 22:25:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-28 22:25:49 +0000
commit70b9b9b788ceb8d16479fb3e6c5a4a5784a45766 (patch)
tree38f09e2adecd5159ac0a0b36524844b8c9f2abd8 /src/backend/commands/dbcommands.c
parentae0b90f223b5cddce80353793340e77c58e215c1 (diff)
downloadpostgresql-70b9b9b788ceb8d16479fb3e6c5a4a5784a45766.tar.gz
postgresql-70b9b9b788ceb8d16479fb3e6c5a4a5784a45766.zip
Change initdb and CREATE DATABASE to actively reject attempts to create
databases with encodings that are incompatible with the server's LC_CTYPE locale, when we can determine that (which we can on most modern platforms, I believe). C/POSIX locale is compatible with all encodings, of course, so there is still some usefulness to CREATE DATABASE's ENCODING option, but this will insulate us against all sorts of recurring complaints caused by mismatched settings. I moved initdb's existing LC_CTYPE-to-encoding mapping knowledge into a new src/port/ file so it could be shared by CREATE DATABASE.
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index f6274803622..094f51b5cc9 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -13,13 +13,14 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.198 2007/09/03 18:46:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.199 2007/09/28 22:25:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <fcntl.h>
+#include <locale.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -96,6 +97,7 @@ createdb(const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
int encoding = -1;
int dbconnlimit = -1;
+ int ctype_encoding;
/* Extract options from the statement node tree */
foreach(option, stmt->options)
@@ -254,6 +256,32 @@ createdb(const CreatedbStmt *stmt)
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid server encoding %d", encoding)));
+ /*
+ * Check whether encoding matches server locale settings. We allow
+ * mismatch in two cases:
+ *
+ * 1. ctype_encoding = SQL_ASCII, which means either that the locale
+ * is C/POSIX which works with any encoding, or that we couldn't determine
+ * the locale's encoding and have to trust the user to get it right.
+ *
+ * 2. selected encoding is SQL_ASCII, but only if you're a superuser.
+ * This is risky but we have historically allowed it --- notably, the
+ * regression tests require it.
+ *
+ * Note: if you change this policy, fix initdb to match.
+ */
+ ctype_encoding = pg_get_encoding_from_locale(NULL);
+
+ if (!(ctype_encoding == encoding ||
+ ctype_encoding == PG_SQL_ASCII ||
+ (encoding == PG_SQL_ASCII && superuser())))
+ ereport(ERROR,
+ (errmsg("encoding %s does not match server's locale %s",
+ pg_encoding_to_char(encoding),
+ setlocale(LC_CTYPE, NULL)),
+ errdetail("The server's LC_CTYPE setting requires encoding %s.",
+ pg_encoding_to_char(ctype_encoding))));
+
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
{