diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index dcc53e13a1a7523128aa7622c47df5c283f9374b..9b7668c133ef8dba82450e74ef37d9a13ea11061 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,9 @@ heap_create_with_catalog(const char *relname,
 		}
 	}
 
+	/* Post creation hook for 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 8b4f8c636fc1d32c015e3ea399c7f6b603d48c4f..db0507b8c7332c3462b5c561f47138bc6ec73900 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,9 @@ CreateConstraintEntry(const char *constraintName,
 										DEPENDENCY_NORMAL);
 	}
 
+	/* Post creation hook for 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 957818403ff2775f3e44592e657029b3c71d3f54..5f1f1de45180c10926026914b99c30f894d833b6 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 hook for 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 71ebd7aa8278deb48af930fe9b938ff4f0bc5280..0387423d9fb117ac0016ca655efe5e82706be68b 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,8 @@ NamespaceCreate(const char *nspName, Oid ownerId)
 	/* Record dependency on owner */
 	recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
 
+	/* Post creation hook for 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 73de67252003783ced5c929b718e2280c4f90636..3e9737437160a9969f49e6517f460a66c5b7ba29 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"
@@ -273,6 +274,10 @@ OperatorShellMake(const char *operatorName,
 
 	heap_freetuple(tup);
 
+	/* Post creation hook for new shell operator */
+	InvokeObjectAccessHook(OAT_POST_CREATE,
+						   OperatorRelationId, operatorObjectId, 0);
+
 	/*
 	 * Make sure the tuple is visible for subsequent lookups/updates.
 	 */
@@ -539,6 +544,10 @@ OperatorCreate(const char *operatorName,
 	/* Add dependencies for the entry */
 	makeOperatorDependencies(tup);
 
+	/* Post creation hook for 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 34cd862d27e7f9992c840bb031673da8ce8193b6..d464979bc744877d875c846803d44a34551093b6 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"
@@ -616,6 +617,9 @@ ProcedureCreate(const char *procedureName,
 
 	heap_freetuple(tup);
 
+	/* Post creation hook for new function */
+	InvokeObjectAccessHook(OAT_POST_CREATE, ProcedureRelationId, retval, 0);
+
 	heap_close(rel, RowExclusiveLock);
 
 	/* Verify function body */
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index d7fccdf07b1b3ad69dd2e731e03becf27f4e6499..85368202d8d7b11bb303060b520c9f912973ce85 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,9 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 								 NULL,
 								 false);
 
+	/* Post creation hook for new shell type */
+	InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typoid, 0);
+
 	/*
 	 * clean up and return the type-oid
 	 */
@@ -455,6 +459,9 @@ TypeCreate(Oid newTypeOid,
 								  NULL),
 								 rebuildDeps);
 
+	/* Post creation hook for 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 8cbd7548f97a303ffcf2ad01e65b6f4cb78c59b0..09c6632a3b773a9b05641aa05e9e25112694bfb3 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,9 @@ createdb(const CreatedbStmt *stmt)
 	/* Create pg_shdepend entries for objects within database */
 	copyTemplateDependencies(src_dboid, dboid);
 
+	/* Post creation hook for 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 4e6367c5268c05a36a707a0781e30799a3469833..71ba806851bbe2b565dd0a7446e80d40acfd4325 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 hook for new foreign data wrapper */
+	InvokeObjectAccessHook(OAT_POST_CREATE,
+						   ForeignDataWrapperRelationId, fdwId, 0);
+
 	heap_close(rel, NoLock);
 }
 
@@ -696,6 +701,9 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 
 	recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId);
 
+	/* Post creation hook for new foreign server */
+	InvokeObjectAccessHook(OAT_POST_CREATE, ForeignServerRelationId, srvId, 0);
+
 	heap_close(rel, NoLock);
 }
 
@@ -967,6 +975,9 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 		/* Record the mapped user dependency */
 		recordDependencyOnOwner(UserMappingRelationId, umId, useId);
 
+	/* Post creation hook for new user mapping */
+	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 62a21102512a324b44244f903e70fc198cf83112..2347cad69417eb0f2db4c3ee47a86f4374f4b29c 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 hook for 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 132c4ee1e539892ea8de8b0c54561ba810dbf695..5055fb17cde0964c26b12a4917de2e9af0f42875 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 hook for 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 hook for 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 a2e653af80a1a141e223674a3593a6e3da082acd..9d0d3b215466cef6284c87b2354557cedcdd1cc3 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 hook for 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 e8808e28c68ce397d0e87ce73122d94efe924570..937992ba585e41751bcaed784dcce4ee75819910 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"
@@ -4080,6 +4081,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
 
 	heap_freetuple(reltup);
 
+	/* Post creation hook for new attribute */
+	InvokeObjectAccessHook(OAT_POST_CREATE,
+						   RelationRelationId, myrelid, newattnum);
+
 	heap_close(pgclass, RowExclusiveLock);
 
 	/* Make the attribute's catalog entry visible */
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 305ac46b4071ca73a9058c200813400982a5d187..5ba0f1ca9da6081a7bafb63ac14817f6f7df61ef 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 hook for 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 d69fdcf410a3f6b83a85e88a5b59a86af786bb56..8195392f16939004526dafa7e6b178c42ec628bf 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 hook for 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 73b8c9248b04f73050e1e59a09e2718bdf449e39..412b1d278d5876cd90958478dc4740e361cfd776 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);
 
+	/* Post creation hook for new text search parser */
+	InvokeObjectAccessHook(OAT_POST_CREATE, TSParserRelationId, prsOid, 0);
+
 	heap_freetuple(tup);
 
 	heap_close(prsRel, RowExclusiveLock);
@@ -563,6 +567,10 @@ DefineTSDictionary(List *names, List *parameters)
 
 	makeDictionaryDependencies(tup);
 
+	/* Post creation hook for new text search dictionary */
+	InvokeObjectAccessHook(OAT_POST_CREATE,
+						   TSDictionaryRelationId, dictOid, 0);
+
 	heap_freetuple(tup);
 
 	heap_close(dictRel, RowExclusiveLock);
@@ -1050,6 +1058,9 @@ DefineTSTemplate(List *names, List *parameters)
 
 	makeTSTemplateDependencies(tup);
 
+	/* Post creation hook for new text search template */
+	InvokeObjectAccessHook(OAT_POST_CREATE, TSTemplateRelationId, dictOid, 0);
+
 	heap_freetuple(tup);
 
 	heap_close(tmplRel, RowExclusiveLock);
@@ -1440,6 +1451,9 @@ DefineTSConfiguration(List *names, List *parameters)
 
 	makeConfigurationDependencies(tup, false, mapRel);
 
+	/* Post creation hook for new text search configuration */
+	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 f1ff83987732d6b0fd914056045c7b182af514cd..2634ca10e6460b126ffc8e8ecb16f0fdf93b8126 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,9 @@ CreateRole(CreateRoleStmt *stmt)
 				rolemembers, roleNamesToIds(rolemembers),
 				GetUserId(), false);
 
+	/* Post creation hook for 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 029a2888a72871ef3203bd1d3d5ce9efdf27ca68..4354897981a8d6f15064b4031728297f3d7a85ee 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 hook for 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 e2faf95d9355a1d95b816b2aa1640cb2f74a93b6..686770cd45e988aa1bb6040e18a668d52cebc894 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 hook for 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 9aa2c0a498fae0b2e87521dd923adcfefb837969..5855fe466632400f3123e109c10231d2a275b57f 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;
+
+/*
+ * Hook on object accesses.  This is intended as infrastructure for security
+ * and logging plugins.
+ */
+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 0000000000000000000000000000000000000000..88508b0103e979b73949ea2dd0f8a4126af2dac3
--- /dev/null
+++ b/src/include/catalog/objectaccess.h
@@ -0,0 +1,46 @@
+/*
+ * objectaccess.h
+ *
+ *		Object access hooks.
+ *
+ * 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
+
+/*
+ * Object access hooks are intended to be called just before or just after
+ * performing certain actions on a SQL object.  This is intended as
+ * infrastructure for security or logging pluggins.
+ *
+ * OAT_POST_CREATE should be invoked just after the the object is created.
+ * Typically, this is done after inserting the primary catalog records and
+ * associated dependencies.
+ *
+ * Other types may be added in the future.
+ */
+typedef enum ObjectAccessType
+{
+	OAT_POST_CREATE,
+} ObjectAccessType;
+
+/*
+ * Hook, and a macro to invoke it.
+ */
+
+typedef void (*object_access_hook_type)(ObjectAccessType access,
+										Oid classId,
+										Oid objectId,
+										int subId);
+
+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)); \
+	} while(0)
+
+#endif	/* OBJECTACCESS_H */