The attached patch is a revised patch. - The utils/hooks.h was renamed to catalog/objectaccess.h - Numeric in the tail of InvokeObjectAccessHook0() has gone. - Fixed bug in ATExecAddColumn; it gave AttributeRelationId to the hook instead of RelationRelationId.
In addition, I found that we didn't put post-creation hook on foreign data wrapper, foreign server and user mapping exceptionally. So, I put this hook around their command handler like any other object classes. Thanks, (2010/11/24 12:07), Robert Haas wrote: > 2010/11/23 KaiGai Kohei<kai...@ak.jp.nec.com>: >>> What >>> I'm not quite sure about is where to put the definitions you've added >>> to a new file utils/hooks.h; I don't feel that's a very appropriate >>> location. It's tempting to put them in utils/acl.h just because this >>> is vaguely access-control related and that header is already included >>> in most of the right places, but maybe that's too much of a stretch; >>> or perhaps catalog/catalog.h, although that doesn't feel quite right >>> either. If we are going to add a new header file, I still don't like >>> utils/hooks.h much - it's considerably more generic than can be >>> justified by its contents. >>> >> I don't think utils/acl.h is long-standing right place, because we >> intended not to restrict the purpose of this hooks to access controls >> as you mentioned. >> >> I think somewhere under the catalog/ directory is a good idea because >> it hooks events that user wants (eventually) to modify system catalogs. >> How about catalog/hooks.h, instead of utils/hooks.h? > > Well, if we're going to create a new header file for this, I think it > should be called something like catalog/objectaccess.h, rather than > just hooks.h. But I'd rather reuse something that's already there, > all things being equal. > -- KaiGai Kohei <kai...@ak.jp.nec.com>
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index dcc53e1..9a38207 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -40,6 +40,7 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" @@ -1188,6 +1189,10 @@ heap_create_with_catalog(const char *relname, } } + /* Post creation of new relation */ + InvokeObjectAccessHook(OAT_POST_CREATE, + RelationRelationId, relid, 0); + /* * Store any supplied constraints and defaults. * diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 8b4f8c6..1ed108f 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -18,6 +18,7 @@ #include "access/heapam.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_constraint.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" @@ -360,6 +361,10 @@ CreateConstraintEntry(const char *constraintName, DEPENDENCY_NORMAL); } + /* Post creation of a new constraint */ + InvokeObjectAccessHook(OAT_POST_CREATE, + ConstraintRelationId, conOid, 0); + return conOid; } diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index 9578184..853ed0e 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -18,6 +18,7 @@ #include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_conversion.h" #include "catalog/pg_conversion_fn.h" #include "catalog/pg_namespace.h" @@ -131,6 +132,10 @@ ConversionCreate(const char *conname, Oid connamespace, recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup), conowner); + /* Post creation of a new conversion */ + InvokeObjectAccessHook(OAT_POST_CREATE, + ConversionRelationId, HeapTupleGetOid(tup), 0); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index 71ebd7a..978be51 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -17,6 +17,7 @@ #include "access/heapam.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "utils/builtins.h" #include "utils/rel.h" @@ -75,5 +76,9 @@ NamespaceCreate(const char *nspName, Oid ownerId) /* Record dependency on owner */ recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId); + /* Post creation of new schema */ + InvokeObjectAccessHook(OAT_POST_CREATE, + NamespaceRelationId, nspoid, 0); + return nspoid; } diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 73de672..cd169a6 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -22,6 +22,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" @@ -271,6 +272,10 @@ OperatorShellMake(const char *operatorName, /* Add dependencies for the entry */ makeOperatorDependencies(tup); + /* Post creation of a new shell operator */ + InvokeObjectAccessHook(OAT_POST_CREATE, + OperatorRelationId, operatorObjectId, 0); + heap_freetuple(tup); /* @@ -539,6 +544,10 @@ OperatorCreate(const char *operatorName, /* Add dependencies for the entry */ makeOperatorDependencies(tup); + /* Post creation of a new operator */ + InvokeObjectAccessHook(OAT_POST_CREATE, + OperatorRelationId, operatorObjectId, 0); + heap_close(pg_operator_desc, RowExclusiveLock); /* diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 34cd862..6ef8cc7 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -18,6 +18,7 @@ #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_language.h" #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" @@ -614,6 +615,10 @@ ProcedureCreate(const char *procedureName, nnewmembers, newmembers); } + /* Post creation of new procedure */ + InvokeObjectAccessHook(OAT_POST_CREATE, + ProcedureRelationId, retval, 0); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index d7fccdf..61ba83e 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -18,6 +18,7 @@ #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -155,6 +156,10 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) NULL, false); + /* Post creation of new shell type */ + InvokeObjectAccessHook(OAT_POST_CREATE, + TypeRelationId, typoid, 0); + /* * clean up and return the type-oid */ @@ -455,6 +460,10 @@ TypeCreate(Oid newTypeOid, NULL), rebuildDeps); + /* Post creation of new type */ + InvokeObjectAccessHook(OAT_POST_CREATE, + TypeRelationId, typeObjectId, 0); + /* * finish up */ diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 8cbd754..8dece96 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -32,6 +32,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_authid.h" #include "catalog/pg_database.h" #include "catalog/pg_db_role_setting.h" @@ -572,6 +573,10 @@ createdb(const CreatedbStmt *stmt) /* Create pg_shdepend entries for objects within database */ copyTemplateDependencies(src_dboid, dboid); + /* Post creation of new database */ + InvokeObjectAccessHook(OAT_POST_CREATE, + DatabaseRelationId, dboid, 0); + /* * Force a checkpoint before starting the copy. This will force dirty * buffers out to disk, to ensure source database is up-to-date on disk diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 4e6367c..6d9da5d 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -18,6 +18,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_foreign_data_wrapper.h" #include "catalog/pg_foreign_server.h" #include "catalog/pg_proc.h" @@ -415,6 +416,10 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId); + /* Post creation of new foreign data wrapper */ + InvokeObjectAccessHook(OAT_POST_CREATE, + ForeignDataWrapperRelationId, fdwId, 0); + heap_close(rel, NoLock); } @@ -696,6 +701,10 @@ CreateForeignServer(CreateForeignServerStmt *stmt) recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId); + /* Post creation of new foreign server */ + InvokeObjectAccessHook(OAT_POST_CREATE, + ForeignServerRelationId, srvId, 0); + heap_close(rel, NoLock); } @@ -967,6 +976,10 @@ CreateUserMapping(CreateUserMappingStmt *stmt) /* Record the mapped user dependency */ recordDependencyOnOwner(UserMappingRelationId, umId, useId); + /* Post creation of new shell type */ + InvokeObjectAccessHook(OAT_POST_CREATE, + UserMappingRelationId, umId, 0); + heap_close(rel, NoLock); } diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 62a2110..571649e 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -37,6 +37,7 @@ #include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_cast.h" #include "catalog/pg_language.h" @@ -1761,6 +1762,10 @@ CreateCast(CreateCastStmt *stmt) recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + /* Post creation of a new cast */ + InvokeObjectAccessHook(OAT_POST_CREATE, + CastRelationId, myself.objectId, 0); + heap_freetuple(tuple); heap_close(relation, RowExclusiveLock); diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 132c4ee..26cb0a4 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -22,6 +22,7 @@ #include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_namespace.h" @@ -307,6 +308,10 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) /* dependency on owner */ recordDependencyOnOwner(OperatorFamilyRelationId, opfamilyoid, GetUserId()); + /* Post creation of a new operator family */ + InvokeObjectAccessHook(OAT_POST_CREATE, + OperatorFamilyRelationId, opfamilyoid, 0); + heap_close(rel, RowExclusiveLock); return opfamilyoid; @@ -703,6 +708,10 @@ DefineOpClass(CreateOpClassStmt *stmt) /* dependency on owner */ recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId()); + /* Post creation of a new operator class */ + InvokeObjectAccessHook(OAT_POST_CREATE, + OperatorClassRelationId, opclassoid, 0); + heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index a2e653a..163b10f 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -17,6 +17,7 @@ #include "access/heapam.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_language.h" #include "catalog/pg_namespace.h" #include "catalog/pg_pltemplate.h" @@ -425,6 +426,10 @@ create_proc_lang(const char *languageName, bool replace, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + /* Post creation of a new procedural language */ + InvokeObjectAccessHook(OAT_POST_CREATE, + LanguageRelationId, myself.objectId, 0); + heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e8808e2..5575607 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -26,6 +26,7 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" #include "catalog/pg_inherits.h" @@ -4082,6 +4083,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, heap_close(pgclass, RowExclusiveLock); + /* Post creation of new attribute */ + InvokeObjectAccessHook(OAT_POST_CREATE, + RelationRelationId, myrelid, newattnum); + /* Make the attribute's catalog entry visible */ CommandCounterIncrement(); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 305ac46..6637cec 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -59,6 +59,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_tablespace.h" #include "commands/comment.h" #include "commands/defrem.h" @@ -333,6 +334,10 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) /* Record dependency on owner */ recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId); + /* Post creation of a new tablespace */ + InvokeObjectAccessHook(OAT_POST_CREATE, + TableSpaceRelationId, tablespaceoid, 0); + create_tablespace_directories(location, tablespaceoid); /* Record the filesystem change in XLOG */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index d69fdcf..ef841b2 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -20,6 +20,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_constraint.h" #include "catalog/pg_proc.h" #include "catalog/pg_trigger.h" @@ -735,6 +736,10 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, recordDependencyOnExpr(&myself, whenClause, whenRtable, DEPENDENCY_NORMAL); + /* Post creation of a new trigger */ + InvokeObjectAccessHook(OAT_POST_CREATE, + TriggerRelationId, trigoid, 0); + /* 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 73b8c92..2ea6dc1 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -23,6 +23,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_ts_config.h" @@ -263,6 +264,9 @@ DefineTSParser(List *names, List *parameters) makeParserDependencies(tup); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSParserRelationId, prsOid, 0); + heap_freetuple(tup); heap_close(prsRel, RowExclusiveLock); @@ -563,6 +567,9 @@ DefineTSDictionary(List *names, List *parameters) makeDictionaryDependencies(tup); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSDictionaryRelationId, dictOid, 0); + heap_freetuple(tup); heap_close(dictRel, RowExclusiveLock); @@ -1050,6 +1057,9 @@ DefineTSTemplate(List *names, List *parameters) makeTSTemplateDependencies(tup); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSTemplateRelationId, dictOid, 0); + heap_freetuple(tup); heap_close(tmplRel, RowExclusiveLock); @@ -1440,6 +1450,9 @@ DefineTSConfiguration(List *names, List *parameters) makeConfigurationDependencies(tup, false, mapRel); + InvokeObjectAccessHook(OAT_POST_CREATE, + TSConfigRelationId, cfgOid, 0); + heap_freetuple(tup); if (mapRel) diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index f1ff839..a9f97ce 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -17,6 +17,7 @@ #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_auth_members.h" #include "catalog/pg_authid.h" #include "catalog/pg_database.h" @@ -402,6 +403,10 @@ CreateRole(CreateRoleStmt *stmt) rolemembers, roleNamesToIds(rolemembers), GetUserId(), false); + /* Post creation of a new role */ + InvokeObjectAccessHook(OAT_POST_CREATE, + AuthIdRelationId, roleid, 0); + /* * Close pg_authid, but keep lock till commit. */ diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 029a288..c2e4f89 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -19,6 +19,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_rewrite.h" #include "catalog/storage.h" #include "miscadmin.h" @@ -177,6 +178,10 @@ InsertRule(char *rulname, DEPENDENCY_NORMAL); } + /* Post creation of a new rule */ + InvokeObjectAccessHook(OAT_POST_CREATE, + RewriteRelationId, rewriteObjectId, 0); + heap_close(pg_rewrite_desc, RowExclusiveLock); return rewriteObjectId; diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index e2faf95..a028988 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -38,6 +38,7 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_largeobject.h" #include "catalog/pg_largeobject_metadata.h" #include "commands/comment.h" @@ -218,6 +219,10 @@ inv_create(Oid lobjId) recordDependencyOnOwner(LargeObjectRelationId, lobjId_new, GetUserId()); + /* Post creation of a new large object */ + InvokeObjectAccessHook(OAT_POST_CREATE, + LargeObjectRelationId, lobjId_new, 0); + /* * Advance command counter to make new tuple visible to later operations. */ diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 9aa2c0a..a132edb 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -18,6 +18,7 @@ */ #include "postgres.h" +#include "catalog/objectaccess.h" #include "libpq/pqcomm.h" #include "miscadmin.h" #include "storage/backendid.h" @@ -117,3 +118,9 @@ int VacuumCostBalance = 0; /* working state for vacuum */ bool VacuumCostActive = false; int GinFuzzySearchLimit = 0; + +/* + * Hooks on object accesses what can be applied for external security + * providers and so on. + */ +PGDLLIMPORT object_access_hook_type object_access_hook = NULL; diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h new file mode 100644 index 0000000..6b7e82e --- /dev/null +++ b/src/include/catalog/objectaccess.h @@ -0,0 +1,50 @@ +/* + * objectaccess.h + * + * Definitions and introductions for object access hooks. + * This hooks allows plugins to handle events on accesses + * to database objects with user's query. + * + * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + */ +#ifndef OBJECTACCESS_H +#define OBJECTACCESS_H + +typedef enum ObjectAccessType +{ + OAT_POST_CREATE, /* Post object creation */ +} ObjectAccessType; + +/* + * Introduction of every access types + * ----------------------------------- + * + * OAT_POST_CREATE + * + * This access type shall be invoked just after object creations. + * Typically, the hook is put just after setting up dependency of + * the new object. Right now, it does not take any arguments except + * for object identifiers. + */ + +/* + * Definition of the object access hook. + */ +typedef void (*object_access_hook_type)(ObjectAccessType access, + Oid classId, + Oid objectId, + int subId); + +extern PGDLLIMPORT object_access_hook_type object_access_hook; + +/* + * Utility macros + */ +#define InvokeObjectAccessHook(access,classId,objectId,subId) \ + do { \ + if (object_access_hook) \ + (*object_access_hook)((access),(classId),(objectId),(subId)); \ + } while(0) + +#endif /* OBJECTACCESS_H */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers