aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-05-06 16:15:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-05-06 16:15:21 +0000
commit421c66b76c3d51e764bd3d8ea25acae89a5b222d (patch)
treee6355dfede0300cfde11dc78fdbb8e25557c3061 /src/backend/commands/dbcommands.c
parentab4e386a8069e3228536f1044f23bbf09f85204b (diff)
downloadpostgresql-421c66b76c3d51e764bd3d8ea25acae89a5b222d.tar.gz
postgresql-421c66b76c3d51e764bd3d8ea25acae89a5b222d.zip
Modify CREATE DATABASE to enforce that the source database's encoding setting
must be used for the new database, except when copying from template0. This is the same rule that we now enforce for locale settings, and it has the same motivation: databases other than template0 might contain data that would be invalid according to a different setting. This represents another step in a continuing process of locking down ways in which encoding violations could occur inside the backend. Per discussion of a few days ago. In passing, fix pre-existing breakage of mbregress.sh, and fix up a couple of ereport() calls in dbcommands.c that failed to specify sqlstate codes.
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index cf6e7400985..8d5972dfa51 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.223 2009/05/05 23:39:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.224 2009/05/06 16:15:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -361,7 +361,8 @@ createdb(const CreatedbStmt *stmt)
#endif
(encoding == PG_SQL_ASCII && superuser())))
ereport(ERROR,
- (errmsg("encoding %s does not match locale %s",
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("encoding %s does not match locale %s",
pg_encoding_to_char(encoding),
dbctype),
errdetail("The chosen LC_CTYPE setting requires encoding %s.",
@@ -374,29 +375,45 @@ createdb(const CreatedbStmt *stmt)
#endif
(encoding == PG_SQL_ASCII && superuser())))
ereport(ERROR,
- (errmsg("encoding %s does not match locale %s",
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("encoding %s does not match locale %s",
pg_encoding_to_char(encoding),
dbcollate),
errdetail("The chosen LC_COLLATE setting requires encoding %s.",
pg_encoding_to_char(collate_encoding))));
/*
- * Check that the new locale is compatible with the source database.
+ * Check that the new encoding and locale settings match the source
+ * database. We insist on this because we simply copy the source data ---
+ * any non-ASCII data would be wrongly encoded, and any indexes sorted
+ * according to the source locale would be wrong.
*
- * We know that template0 doesn't contain any indexes that depend on
- * collation or ctype, so template0 can be used as template for
- * any locale.
+ * However, we assume that template0 doesn't contain any non-ASCII data
+ * nor any indexes that depend on collation or ctype, so template0 can be
+ * used as template for creating a database with any encoding or locale.
*/
if (strcmp(dbtemplate, "template0") != 0)
{
+ if (encoding != src_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("new encoding (%s) is incompatible with the encoding of the template database (%s)",
+ pg_encoding_to_char(encoding),
+ pg_encoding_to_char(src_encoding)),
+ errhint("Use the same encoding as in the template database, or use template0 as template.")));
+
if (strcmp(dbcollate, src_collate) != 0)
ereport(ERROR,
- (errmsg("new collation is incompatible with the collation of the template database (%s)", src_collate),
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("new collation (%s) is incompatible with the collation of the template database (%s)",
+ dbcollate, src_collate),
errhint("Use the same collation as in the template database, or use template0 as template.")));
if (strcmp(dbctype, src_ctype) != 0)
ereport(ERROR,
- (errmsg("new LC_CTYPE is incompatible with LC_CTYPE of the template database (%s)", src_ctype),
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)",
+ dbctype, src_ctype),
errhint("Use the same LC_CTYPE as in the template database, or use template0 as template.")));
}
@@ -1099,7 +1116,8 @@ movedb(const char *dbname, const char *tblspcname)
continue;
ereport(ERROR,
- (errmsg("some relations of database \"%s\" are already in tablespace \"%s\"",
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("some relations of database \"%s\" are already in tablespace \"%s\"",
dbname, tblspcname),
errhint("You must move them back to the database's default tablespace before using this command.")));
}