diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2013-01-15 13:23:43 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2013-01-15 13:23:43 -0300 |
commit | 7ac5760fa283bc090c25e4ea495a0d2bb41db7b5 (patch) | |
tree | 023eec06b6465fd108a7dbfca628ab7de872c995 /src/backend/commands/collationcmds.c | |
parent | ffda05977a93f9b3f8a6b05657ba2f16decb6b23 (diff) |
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
Diffstat (limited to 'src/backend/commands/collationcmds.c')
-rw-r--r-- | src/backend/commands/collationcmds.c | 87 |
1 files changed, 14 insertions, 73 deletions
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index b763f15b30d..67200f87ba5 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -167,27 +167,7 @@ RenameCollation(List *name, const char *newname) namespaceOid = ((Form_pg_collation) GETSTRUCT(tup))->collnamespace; /* make sure the new name doesn't exist */ - if (SearchSysCacheExists3(COLLNAMEENCNSP, - CStringGetDatum(newname), - Int32GetDatum(GetDatabaseEncoding()), - ObjectIdGetDatum(namespaceOid))) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"", - newname, - GetDatabaseEncodingName(), - get_namespace_name(namespaceOid)))); - - /* mustn't match an any-encoding entry, either */ - if (SearchSysCacheExists3(COLLNAMEENCNSP, - CStringGetDatum(newname), - Int32GetDatum(-1), - ObjectIdGetDatum(namespaceOid))) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("collation \"%s\" already exists in schema \"%s\"", - newname, - get_namespace_name(namespaceOid)))); + IsThereCollationInNamespace(newname, namespaceOid); /* must be owner */ if (!pg_collation_ownercheck(collationOid, GetUserId())) @@ -213,71 +193,32 @@ RenameCollation(List *name, const char *newname) } /* - * Execute ALTER COLLATION SET SCHEMA - */ -Oid -AlterCollationNamespace(List *name, const char *newschema) -{ - Oid collOid, - nspOid; - - collOid = get_collation_oid(name, false); - - nspOid = LookupCreationNamespace(newschema); - - AlterCollationNamespace_oid(collOid, nspOid); - - return collOid; -} - -/* - * Change collation schema, by oid + * Subroutine for ALTER COLLATION SET SCHEMA and RENAME + * + * Is there a collation with the same name of the given collation already in + * the given namespace? If so, raise an appropriate error message. */ -Oid -AlterCollationNamespace_oid(Oid collOid, Oid newNspOid) +void +IsThereCollationInNamespace(const char *collname, Oid nspOid) { - Oid oldNspOid; - Relation rel; - char *collation_name; - - rel = heap_open(CollationRelationId, RowExclusiveLock); - - /* - * We have to check for name collision ourselves, because - * AlterObjectNamespace_internal doesn't know how to deal with the encoding - * considerations. - */ - collation_name = get_collation_name(collOid); - if (!collation_name) - elog(ERROR, "cache lookup failed for collation %u", collOid); - /* make sure the name doesn't already exist in new schema */ if (SearchSysCacheExists3(COLLNAMEENCNSP, - CStringGetDatum(collation_name), + CStringGetDatum(collname), Int32GetDatum(GetDatabaseEncoding()), - ObjectIdGetDatum(newNspOid))) + ObjectIdGetDatum(nspOid))) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"", - collation_name, - GetDatabaseEncodingName(), - get_namespace_name(newNspOid)))); + collname, GetDatabaseEncodingName(), + get_namespace_name(nspOid)))); /* mustn't match an any-encoding entry, either */ if (SearchSysCacheExists3(COLLNAMEENCNSP, - CStringGetDatum(collation_name), + CStringGetDatum(collname), Int32GetDatum(-1), - ObjectIdGetDatum(newNspOid))) + ObjectIdGetDatum(nspOid))) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("collation \"%s\" already exists in schema \"%s\"", - collation_name, - get_namespace_name(newNspOid)))); - - /* OK, do the work */ - oldNspOid = AlterObjectNamespace_internal(rel, collOid, newNspOid); - - heap_close(rel, RowExclusiveLock); - - return oldNspOid; + collname, get_namespace_name(nspOid)))); } |