1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Further consolidation of DROP statement handling.

This gets rid of an impressive amount of duplicative code, with only
minimal behavior changes.  DROP FOREIGN DATA WRAPPER now requires object
ownership rather than superuser privileges, matching the documentation
we already have.  We also eliminate the historical warning about dropping
a built-in function as unuseful.  All operations are now performed in the
same order for all object types handled by dropcmds.c.

KaiGai Kohei, with minor revisions by me
This commit is contained in:
Robert Haas
2011-11-17 21:31:29 -05:00
parent 709aca5960
commit fc6d1006bd
21 changed files with 241 additions and 1148 deletions

View File

@ -1543,104 +1543,6 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
}
}
/*
* RemoveOpClass
* Deletes an opclass.
*/
void
RemoveOpClass(RemoveOpClassStmt *stmt)
{
Oid amID,
opcID;
HeapTuple tuple;
ObjectAddress object;
/* Get the access method's OID. */
amID = get_am_oid(stmt->amname, false);
/* Look up the opclass. */
tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
if (!HeapTupleIsValid(tuple))
{
ereport(NOTICE,
(errmsg("operator class \"%s\" does not exist for access method \"%s\", skipping",
NameListToString(stmt->opclassname), stmt->amname)));
return;
}
opcID = HeapTupleGetOid(tuple);
/* Permission check: must own opclass or its namespace */
if (!pg_opclass_ownercheck(opcID, GetUserId()) &&
!pg_namespace_ownercheck(((Form_pg_opclass) GETSTRUCT(tuple))->opcnamespace,
GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
NameListToString(stmt->opclassname));
ReleaseSysCache(tuple);
/*
* Do the deletion
*/
object.classId = OperatorClassRelationId;
object.objectId = opcID;
object.objectSubId = 0;
performDeletion(&object, stmt->behavior);
}
/*
* RemoveOpFamily
* Deletes an opfamily.
*/
void
RemoveOpFamily(RemoveOpFamilyStmt *stmt)
{
Oid amID,
opfID;
HeapTuple tuple;
ObjectAddress object;
/*
* Get the access method's OID.
*/
amID = get_am_oid(stmt->amname, false);
/*
* Look up the opfamily.
*/
tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
if (!HeapTupleIsValid(tuple))
{
ereport(NOTICE,
(errmsg("operator family \"%s\" does not exist for access method \"%s\", skipping",
NameListToString(stmt->opfamilyname), stmt->amname)));
return;
}
opfID = HeapTupleGetOid(tuple);
/* Permission check: must own opfamily or its namespace */
if (!pg_opfamily_ownercheck(opfID, GetUserId()) &&
!pg_namespace_ownercheck(((Form_pg_opfamily) GETSTRUCT(tuple))->opfnamespace,
GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
NameListToString(stmt->opfamilyname));
ReleaseSysCache(tuple);
/*
* Do the deletion
*/
object.classId = OperatorFamilyRelationId;
object.objectId = opfID;
object.objectSubId = 0;
performDeletion(&object, stmt->behavior);
}
/*
* Deletion subroutines for use by dependency.c.
*/