diff options
Diffstat (limited to 'src/backend/commands/schemacmds.c')
-rw-r--r-- | src/backend/commands/schemacmds.c | 95 |
1 files changed, 57 insertions, 38 deletions
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index d77294ccc22..8029013e2cc 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.49 2008/01/03 21:23:15 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.50 2008/06/14 18:04:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -148,57 +148,76 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) /* - * RemoveSchema - * Removes a schema. + * RemoveSchemas + * Implements DROP SCHEMA. */ void -RemoveSchema(List *names, DropBehavior behavior, bool missing_ok) +RemoveSchemas(DropStmt *drop) { - char *namespaceName; - Oid namespaceId; - ObjectAddress object; + ObjectAddresses *objects; + ListCell *cell; - if (list_length(names) != 1) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("schema name cannot be qualified"))); - namespaceName = strVal(linitial(names)); - - namespaceId = GetSysCacheOid(NAMESPACENAME, - CStringGetDatum(namespaceName), - 0, 0, 0); - if (!OidIsValid(namespaceId)) + /* + * First we identify all the schemas, then we delete them in a single + * performMultipleDeletions() call. This is to avoid unwanted + * DROP RESTRICT errors if one of the schemas depends on another. + */ + objects = new_object_addresses(); + + foreach(cell, drop->objects) { - if (!missing_ok) - { + List *names = (List *) lfirst(cell); + char *namespaceName; + Oid namespaceId; + ObjectAddress object; + + if (list_length(names) != 1) ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("schema \"%s\" does not exist", namespaceName))); - } - else + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("schema name cannot be qualified"))); + namespaceName = strVal(linitial(names)); + + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(namespaceName), + 0, 0, 0); + + if (!OidIsValid(namespaceId)) { - ereport(NOTICE, - (errmsg("schema \"%s\" does not exist, skipping", - namespaceName))); + if (!drop->missing_ok) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("schema \"%s\" does not exist", + namespaceName))); + } + else + { + ereport(NOTICE, + (errmsg("schema \"%s\" does not exist, skipping", + namespaceName))); + } + continue; } - return; - } + /* Permission check */ + if (!pg_namespace_ownercheck(namespaceId, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, + namespaceName); - /* Permission check */ - if (!pg_namespace_ownercheck(namespaceId, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, - namespaceName); + object.classId = NamespaceRelationId; + object.objectId = namespaceId; + object.objectSubId = 0; + + add_exact_object_address(&object, objects); + } /* - * Do the deletion. Objects contained in the schema are removed by means - * of their dependency links to the schema. + * Do the deletions. Objects contained in the schema(s) are removed by + * means of their dependency links to the schema. */ - object.classId = NamespaceRelationId; - object.objectId = namespaceId; - object.objectSubId = 0; + performMultipleDeletions(objects, drop->behavior); - performDeletion(&object, behavior); + free_object_addresses(objects); } |