diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index eca064f0cdef7ee6367b76a4da785e29a9cfdbc6..1b92f5c38a1efa97dc644cb769ba1feae55e35a5 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -20,6 +20,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_attrdef.h" @@ -991,6 +992,15 @@ deleteOneObject(const ObjectAddress *object, Relation depRel, int flags) SysScanDesc scan; HeapTuple tup; + /* DROP hook of the objects being removed */ + if (object_access_hook) + { + ObjectAccessDrop drop_arg; + drop_arg.dropflags = flags; + InvokeObjectAccessHook(OAT_DROP, object->classId, object->objectId, + object->objectSubId, &drop_arg); + } + /* * First remove any pg_depend records that link from this object to * others. (Any records linking to this object should be gone already.) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index d1d458d7fa485606f1c0e877fdd558b42f6ea273..8bd5a9296e1be06bbfc944c08c1d42863a7dc142 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1286,7 +1286,8 @@ heap_create_with_catalog(const char *relname, } /* Post creation hook for new relation */ - InvokeObjectAccessHook(OAT_POST_CREATE, RelationRelationId, relid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + RelationRelationId, relid, 0, NULL); /* * Store any supplied constraints and defaults. diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c index 511d70c044d6ba18c809296befb5035e8bc19493..18c7acf0e81ffe2582cea769dfe2b8122a2fab4d 100644 --- a/src/backend/catalog/pg_collation.c +++ b/src/backend/catalog/pg_collation.c @@ -136,7 +136,7 @@ CollationCreate(const char *collname, Oid collnamespace, /* Post creation hook for new collation */ InvokeObjectAccessHook(OAT_POST_CREATE, - CollationRelationId, oid, 0); + CollationRelationId, oid, 0, NULL); heap_freetuple(tup); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 0bad4d99cb42f5018578d124856605f2116992a0..342cf75270a3f4b6b19d35d4394d27ca06708055 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -366,7 +366,8 @@ CreateConstraintEntry(const char *constraintName, } /* Post creation hook for new constraint */ - InvokeObjectAccessHook(OAT_POST_CREATE, ConstraintRelationId, conOid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + ConstraintRelationId, conOid, 0, NULL); return conOid; } diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index 8194cd6c2671f9131d581aa8e5a6c03293ac76a0..f86c84fc4bb239e7cf83844794d86e51bb43711b 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -134,8 +134,8 @@ ConversionCreate(const char *conname, Oid connamespace, recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new conversion */ - InvokeObjectAccessHook(OAT_POST_CREATE, - ConversionRelationId, HeapTupleGetOid(tup), 0); + InvokeObjectAccessHook(OAT_POST_CREATE, ConversionRelationId, + HeapTupleGetOid(tup), 0, NULL); heap_freetuple(tup); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index be812a246c09dbc92f762fb50f1a6fac0e074f73..de856760f08b37427bbdda04dd12306a0d629e0f 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -95,7 +95,8 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp) recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new schema */ - InvokeObjectAccessHook(OAT_POST_CREATE, NamespaceRelationId, nspoid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + NamespaceRelationId, nspoid, 0, NULL); return nspoid; } diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 3b727222413ac8e6467723a770904f478660239e..4fd55ae570607d97c538762f1ba0955257741e14 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -275,7 +275,7 @@ OperatorShellMake(const char *operatorName, /* Post creation hook for new shell operator */ InvokeObjectAccessHook(OAT_POST_CREATE, - OperatorRelationId, operatorObjectId, 0); + OperatorRelationId, operatorObjectId, 0, NULL); /* * Make sure the tuple is visible for subsequent lookups/updates. @@ -544,7 +544,7 @@ OperatorCreate(const char *operatorName, /* Post creation hook for new operator */ InvokeObjectAccessHook(OAT_POST_CREATE, - OperatorRelationId, operatorObjectId, 0); + OperatorRelationId, operatorObjectId, 0, NULL); heap_close(pg_operator_desc, RowExclusiveLock); diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 91ead4cb9d266d2be520c0838e7fcc2a482b85b2..1fffe1c6ac313717191fd9427dbcb2ba8af2da15 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -655,7 +655,8 @@ ProcedureCreate(const char *procedureName, heap_freetuple(tup); /* Post creation hook for new function */ - InvokeObjectAccessHook(OAT_POST_CREATE, ProcedureRelationId, retval, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + ProcedureRelationId, retval, 0, NULL); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 2c2e3b3e7cf95f201f6b0760c749a1b79fff7013..5b2ad6bfe0d41d1bf60e2df0aa7cb905e4be0896 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -162,7 +162,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) false); /* Post creation hook for new shell type */ - InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typoid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + TypeRelationId, typoid, 0, NULL); /* * clean up and return the type-oid @@ -474,7 +475,8 @@ TypeCreate(Oid newTypeOid, rebuildDeps); /* Post creation hook for new type */ - InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typeObjectId, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + TypeRelationId, typeObjectId, 0, NULL); /* * finish up diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 42a8b31b2a8263dad3a548a046f1e1999bfabbea..91d74815287c1f6d46359b1a0ad0bddd0fd763be 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -515,7 +515,8 @@ createdb(const CreatedbStmt *stmt) copyTemplateDependencies(src_dboid, dboid); /* Post creation hook for new database */ - InvokeObjectAccessHook(OAT_POST_CREATE, DatabaseRelationId, dboid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + DatabaseRelationId, dboid, 0, NULL); /* * Force a checkpoint before starting the copy. This will force dirty @@ -777,6 +778,15 @@ dropdb(const char *dbname, bool missing_ok) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, dbname); + /* DROP hook for the database being removed */ + if (object_access_hook) + { + ObjectAccessDrop drop_arg; + memset(&drop_arg, 0, sizeof(ObjectAccessDrop)); + InvokeObjectAccessHook(OAT_DROP, + DatabaseRelationId, db_id, 0, &drop_arg); + } + /* * Disallow dropping a DB that is marked istemplate. This is just to * prevent people from accidentally dropping template0 or template1; they diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index a9963ac93b939479617581669377696e56fca1c2..732791cc41366fa9770765d8b24f2b8b74203a97 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -1558,7 +1558,7 @@ InsertExtensionTuple(const char *extName, Oid extOwner, } /* Post creation hook for new extension */ InvokeObjectAccessHook(OAT_POST_CREATE, - ExtensionRelationId, extensionOid, 0); + ExtensionRelationId, extensionOid, 0, NULL); return extensionOid; } diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 5d18bdcf0a972b7da4cd334d584ceab1f9269776..30135e6de8b027b7b932c188f146f545e9af5d89 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -666,7 +666,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) /* Post creation hook for new foreign data wrapper */ InvokeObjectAccessHook(OAT_POST_CREATE, - ForeignDataWrapperRelationId, fdwId, 0); + ForeignDataWrapperRelationId, fdwId, 0, NULL); heap_close(rel, RowExclusiveLock); } @@ -962,7 +962,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt) recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new foreign server */ - InvokeObjectAccessHook(OAT_POST_CREATE, ForeignServerRelationId, srvId, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + ForeignServerRelationId, srvId, 0, NULL); heap_close(rel, RowExclusiveLock); } @@ -1202,7 +1203,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt) recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new user mapping */ - InvokeObjectAccessHook(OAT_POST_CREATE, UserMappingRelationId, umId, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + UserMappingRelationId, umId, 0, NULL); heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index ce866a20a990c664f525908a1eff90c12a1b08d3..4125b97e89eb24e00b95f100024ff2b36b0f94ec 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1759,7 +1759,8 @@ CreateCast(CreateCastStmt *stmt) recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new cast */ - InvokeObjectAccessHook(OAT_POST_CREATE, CastRelationId, castid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + CastRelationId, castid, 0, NULL); heap_freetuple(tuple); diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 5dc131a50e2221d01804ee2a57cf6de68e86bdfd..87c889604e2ad0d40da4a550438c7d203de642b9 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -314,7 +314,7 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) /* Post creation hook for new operator family */ InvokeObjectAccessHook(OAT_POST_CREATE, - OperatorFamilyRelationId, opfamilyoid, 0); + OperatorFamilyRelationId, opfamilyoid, 0, NULL); heap_close(rel, RowExclusiveLock); @@ -717,7 +717,7 @@ DefineOpClass(CreateOpClassStmt *stmt) /* Post creation hook for new operator class */ InvokeObjectAccessHook(OAT_POST_CREATE, - OperatorClassRelationId, opclassoid, 0); + OperatorClassRelationId, opclassoid, 0, NULL); heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 8d6a0416d5ff9ea1d7fe457a3a7c9b6e032f1166..41775fd86745a4538c2e26689e7cbf5ef56f8c26 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -428,7 +428,7 @@ create_proc_lang(const char *languageName, bool replace, /* Post creation hook for new procedural language */ InvokeObjectAccessHook(OAT_POST_CREATE, - LanguageRelationId, myself.objectId, 0); + LanguageRelationId, myself.objectId, 0, NULL); heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index cd4490a1c24e5954213d075d768cb5021cdc11a9..25ca356b867ec799625cae5b215151a0284472f0 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -4382,7 +4382,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Post creation hook for new attribute */ InvokeObjectAccessHook(OAT_POST_CREATE, - RelationRelationId, myrelid, newattnum); + RelationRelationId, myrelid, newattnum, NULL); heap_close(pgclass, RowExclusiveLock); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 5e10f8c9a33b7055ad47566a10ca141dd76a72d8..d66ea3b6c12a953a74e6e5696535ac0e306c5ccd 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -330,7 +330,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) /* Post creation hook for new tablespace */ InvokeObjectAccessHook(OAT_POST_CREATE, - TableSpaceRelationId, tablespaceoid, 0); + TableSpaceRelationId, tablespaceoid, 0, NULL); create_tablespace_directories(location, tablespaceoid); @@ -434,6 +434,15 @@ DropTableSpace(DropTableSpaceStmt *stmt) aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, tablespacename); + /* DROP hook for the tablespace being removed */ + if (object_access_hook) + { + ObjectAccessDrop drop_arg; + memset(&drop_arg, 0, sizeof(ObjectAccessDrop)); + InvokeObjectAccessHook(OAT_DROP, TableSpaceRelationId, + tablespaceoid, 0, &drop_arg); + } + /* * Remove the pg_tablespace tuple (this will roll back if we fail below) */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index caae2dafab159e8adda4ba1b1d02117cb3eb5873..a98d1b884ee5268f0c9b1bf9eef42489877e4a91 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -756,7 +756,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, /* Post creation hook for new trigger */ InvokeObjectAccessHook(OAT_POST_CREATE, - TriggerRelationId, trigoid, 0); + TriggerRelationId, trigoid, 0, NULL); /* Keep lock on target rel until end of xact */ heap_close(rel, NoLock); diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index fe500a6d7f97fd6e44b40dee9c8371696d0e245d..86cb8704da811ed9cd3bd2bbd5e2d7dae1a70c70 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -271,7 +271,8 @@ DefineTSParser(List *names, List *parameters) makeParserDependencies(tup); /* Post creation hook for new text search parser */ - InvokeObjectAccessHook(OAT_POST_CREATE, TSParserRelationId, prsOid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSParserRelationId, prsOid, 0, NULL); heap_freetuple(tup); @@ -565,7 +566,7 @@ DefineTSDictionary(List *names, List *parameters) /* Post creation hook for new text search dictionary */ InvokeObjectAccessHook(OAT_POST_CREATE, - TSDictionaryRelationId, dictOid, 0); + TSDictionaryRelationId, dictOid, 0, NULL); heap_freetuple(tup); @@ -1036,7 +1037,8 @@ DefineTSTemplate(List *names, List *parameters) makeTSTemplateDependencies(tup); /* Post creation hook for new text search template */ - InvokeObjectAccessHook(OAT_POST_CREATE, TSTemplateRelationId, dictOid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSTemplateRelationId, dictOid, 0, NULL); heap_freetuple(tup); @@ -1419,7 +1421,8 @@ DefineTSConfiguration(List *names, List *parameters) makeConfigurationDependencies(tup, false, mapRel); /* Post creation hook for new text search configuration */ - InvokeObjectAccessHook(OAT_POST_CREATE, TSConfigRelationId, cfgOid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSConfigRelationId, cfgOid, 0, NULL); heap_freetuple(tup); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 9a88c907894b6b8ac1d9a11c47c7c5cfb9e414f0..2edbabe7549ba15fad63d85b0f913638c2c82da1 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -425,7 +425,8 @@ CreateRole(CreateRoleStmt *stmt) GetUserId(), false); /* Post creation hook for new role */ - InvokeObjectAccessHook(OAT_POST_CREATE, AuthIdRelationId, roleid, 0); + InvokeObjectAccessHook(OAT_POST_CREATE, + AuthIdRelationId, roleid, 0, NULL); /* * Close pg_authid, but keep lock till commit. @@ -932,6 +933,15 @@ DropRole(DropRoleStmt *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to drop superusers"))); + /* DROP hook for the role being removed */ + if (object_access_hook) + { + ObjectAccessDrop drop_arg; + memset(&drop_arg, 0, sizeof(ObjectAccessDrop)); + InvokeObjectAccessHook(OAT_DROP, + AuthIdRelationId, roleid, 0, &drop_arg); + } + /* * Lock the role, so nobody can add dependencies to her while we drop * her. We keep the lock until the end of transaction. diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 8c87ac599f958804bee25f174273e228b822ad51..645182dbfa4668450b35e3ba73bd2f3167e1eb52 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -178,7 +178,7 @@ InsertRule(char *rulname, /* Post creation hook for new rule */ InvokeObjectAccessHook(OAT_POST_CREATE, - RewriteRelationId, rewriteObjectId, 0); + RewriteRelationId, rewriteObjectId, 0, NULL); heap_close(pg_rewrite_desc, RowExclusiveLock); diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index a14ce442c1c35d3ab2d5e297060491206cc1dd84..3adfb159b8baa49939951da0cecf789575652dbe 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -217,7 +217,7 @@ inv_create(Oid lobjId) /* Post creation hook for new large object */ InvokeObjectAccessHook(OAT_POST_CREATE, - LargeObjectRelationId, lobjId_new, 0); + LargeObjectRelationId, lobjId_new, 0, NULL); /* * Advance command counter to make new tuple visible to later operations. diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h index 5c7a40a31cb77d1f298c09d59e679418050b3ae0..9763280177b81c744c89cb7ff1b8922acaf0dced 100644 --- a/src/include/catalog/objectaccess.h +++ b/src/include/catalog/objectaccess.h @@ -19,28 +19,45 @@ * Typically, this is done after inserting the primary catalog records and * associated dependencies. * + * OAT_DROP should be invoked just before deletion of objects; typically + * deleteOneObject(). Its arguments are packed within ObjectAccessDrop. + * * Other types may be added in the future. */ typedef enum ObjectAccessType { OAT_POST_CREATE, + OAT_DROP, } ObjectAccessType; /* - * Hook, and a macro to invoke it. + * Arguments of OAT_DROP event */ +typedef struct +{ + /* + * Flags to inform extensions the context of this deletion. + * Also see PERFORM_DELETION_* in dependency.h + */ + int dropflags; +} ObjectAccessDrop; +/* + * Hook, and a macro to invoke it. + */ typedef void (*object_access_hook_type) (ObjectAccessType access, Oid classId, Oid objectId, - int subId); + int subId, + void *arg); extern PGDLLIMPORT object_access_hook_type object_access_hook; -#define InvokeObjectAccessHook(access,classId,objectId,subId) \ - do { \ - if (object_access_hook) \ - (*object_access_hook)((access),(classId),(objectId),(subId)); \ +#define InvokeObjectAccessHook(access,classId,objectId,subId,arg) \ + do { \ + if (object_access_hook) \ + (*object_access_hook)((access),(classId), \ + (objectId),(subId),(arg)); \ } while(0) #endif /* OBJECTACCESS_H */