 contrib/sepgsql/hooks.c                    |    8 +-
 src/backend/bootstrap/bootparse.y          |    4 +-
 src/backend/catalog/heap.c                 |   30 +++--
 src/backend/catalog/index.c                |    4 +-
 src/backend/catalog/pg_collation.c         |    5 +-
 src/backend/catalog/pg_constraint.c        |    4 +-
 src/backend/catalog/pg_conversion.c        |    5 +-
 src/backend/catalog/pg_largeobject.c       |    5 +
 src/backend/catalog/pg_namespace.c         |    4 +-
 src/backend/catalog/pg_operator.c          |   13 +-
 src/backend/catalog/pg_proc.c              |    7 +-
 src/backend/catalog/pg_type.c              |   11 +-
 src/backend/catalog/toasting.c             |    4 +-
 src/backend/commands/cluster.c             |    4 +-
 src/backend/commands/dbcommands.c          |    5 +-
 src/backend/commands/extension.c           |    7 +-
 src/backend/commands/foreigncmds.c         |   22 ++--
 src/backend/commands/functioncmds.c        |    4 +-
 src/backend/commands/opclasscmds.c         |   16 +-
 src/backend/commands/proclang.c            |    5 +-
 src/backend/commands/tablecmds.c           |   13 +-
 src/backend/commands/tablespace.c          |    9 +-
 src/backend/commands/trigger.c             |   31 +++--
 src/backend/commands/tsearchcmds.c         |   17 ++-
 src/backend/commands/user.c                |    4 +-
 src/backend/executor/execMain.c            |    4 +-
 src/backend/rewrite/rewriteDefine.c        |    8 +-
 src/backend/storage/large_object/inv_api.c |    5 -
 src/include/catalog/heap.h                 |    6 +-
 src/include/catalog/objectaccess.h         |  214 +++++++++++++++++++++++++++-
 30 files changed, 374 insertions(+), 104 deletions(-)

diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c
index 7797ccb..6e5c2d4 100644
--- a/contrib/sepgsql/hooks.c
+++ b/contrib/sepgsql/hooks.c
@@ -115,10 +115,14 @@ static void
 sepgsql_object_access(ObjectAccessType access,
 					  Oid classId,
 					  Oid objectId,
-					  int subId)
+					  int subId,
+					  int nargs,
+					  Datum argv[])
 {
 	if (next_object_access_hook)
-		(*next_object_access_hook) (access, classId, objectId, subId);
+		(*next_object_access_hook) (access,
+									classId, objectId, subId,
+									nargs, argv);
 
 	switch (access)
 	{
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index d0a0e92..a303454 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -248,7 +248,9 @@ Boot_CreateStmt:
 													  ONCOMMIT_NOOP,
 													  (Datum) 0,
 													  false,
-													  true);
+													  true,
+													  false,
+													  false);
 						elog(DEBUG4, "relation created with OID %u", id);
 					}
 					do_end();
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 7ec6581..3b16126 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -80,7 +80,7 @@
 Oid			binary_upgrade_next_heap_pg_class_oid = InvalidOid;
 Oid			binary_upgrade_next_toast_pg_class_oid = InvalidOid;
 
-static void AddNewRelationTuple(Relation pg_class_desc,
+static HeapTuple AddNewRelationTuple(Relation pg_class_desc,
 					Relation new_rel_desc,
 					Oid new_rel_oid,
 					Oid new_type_oid,
@@ -752,7 +752,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
  * to NULL.
  * --------------------------------
  */
-void
+HeapTuple
 InsertPgClassTuple(Relation pg_class_desc,
 				   Relation new_rel_desc,
 				   Oid new_rel_oid,
@@ -814,7 +814,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 
 	CatalogUpdateIndexes(pg_class_desc, tup);
 
-	heap_freetuple(tup);
+	return tup;	/* to be freed in the caller side */
 }
 
 /* --------------------------------
@@ -824,7 +824,7 @@ InsertPgClassTuple(Relation pg_class_desc,
  *		adding a tuple to pg_class.
  * --------------------------------
  */
-static void
+static HeapTuple
 AddNewRelationTuple(Relation pg_class_desc,
 					Relation new_rel_desc,
 					Oid new_rel_oid,
@@ -894,8 +894,8 @@ AddNewRelationTuple(Relation pg_class_desc,
 	new_rel_desc->rd_att->tdtypeid = new_type_oid;
 
 	/* Now build and insert the tuple */
-	InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
-					   relacl, reloptions);
+	return InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
+							  relacl, reloptions);
 }
 
 
@@ -972,6 +972,9 @@ AddNewRelationType(const char *typeName,
  *	use_user_acl: TRUE if should look for user-defined default permissions;
  *		if FALSE, relacl is always set NULL
  *	allow_system_table_mods: TRUE to allow creation in system namespaces
+ *	is_rebuilt_relation : TRUE if the relation is defined to rebuild
+ *		a particular existing relation.
+ *	is_select_into : TRUE if the relation is created by SELECT INTO.
  *
  * Returns the OID of the new relation
  * --------------------------------
@@ -995,10 +998,13 @@ heap_create_with_catalog(const char *relname,
 						 OnCommitAction oncommit,
 						 Datum reloptions,
 						 bool use_user_acl,
-						 bool allow_system_table_mods)
+						 bool allow_system_table_mods,
+						 bool is_rebuilt_relation,
+						 bool is_select_into)
 {
 	Relation	pg_class_desc;
 	Relation	new_rel_desc;
+	HeapTuple	new_rel_tup;
 	Acl		   *relacl;
 	Oid			existing_relid;
 	Oid			old_type_oid;
@@ -1209,7 +1215,7 @@ heap_create_with_catalog(const char *relname,
 	 * creating the same relation name in parallel but hadn't committed yet
 	 * when we checked for a duplicate name above.
 	 */
-	AddNewRelationTuple(pg_class_desc,
+	new_rel_tup = AddNewRelationTuple(pg_class_desc,
 						new_rel_desc,
 						relid,
 						new_type_oid,
@@ -1281,7 +1287,12 @@ heap_create_with_catalog(const char *relname,
 	}
 
 	/* Post creation hook for new relation */
-	InvokeObjectAccessHook(OAT_POST_CREATE, RelationRelationId, relid, 0);
+	InvokeObjectAccessHook4(OAT_POST_CREATE,
+							RelationRelationId, relid, 0,
+							PointerGetDatum(GETSTRUCT(new_rel_tup)),
+							PointerGetDatum(tupdesc),
+							BoolGetDatum(is_rebuilt_relation),
+							BoolGetDatum(is_select_into));
 
 	/*
 	 * Store any supplied constraints and defaults.
@@ -1322,6 +1333,7 @@ heap_create_with_catalog(const char *relname,
 	 * ok, the relation has been cataloged, so close our relations and return
 	 * the OID of the newly created relation.
 	 */
+	heap_freetuple(new_rel_tup);
 	heap_close(new_rel_desc, NoLock);	/* do not unlock till end of xact */
 	heap_close(pg_class_desc, RowExclusiveLock);
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 75b4c14..3a0dd67 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -697,6 +697,7 @@ index_create(Relation heapRelation,
 	Relation	pg_class;
 	Relation	indexRelation;
 	TupleDesc	indexTupDesc;
+	HeapTuple	indexTup;
 	bool		shared_relation;
 	bool		mapped_relation;
 	bool		is_exclusion;
@@ -847,10 +848,11 @@ index_create(Relation heapRelation,
 	/*
 	 * store index's pg_class entry
 	 */
-	InsertPgClassTuple(pg_class, indexRelation,
+	indexTup = InsertPgClassTuple(pg_class, indexRelation,
 					   RelationGetRelid(indexRelation),
 					   (Datum) 0,
 					   reloptions);
+	heap_freetuple(indexTup);
 
 	/* done with pg_class */
 	heap_close(pg_class, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index ce9bfae..9b6a0f0 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -135,8 +135,9 @@ CollationCreate(const char *collname, Oid collnamespace,
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new collation */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   CollationRelationId, oid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							CollationRelationId, oid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 	heap_close(rel, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 6997994..084743e 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -364,7 +364,9 @@ CreateConstraintEntry(const char *constraintName,
 	}
 
 	/* Post creation hook for new constraint */
-	InvokeObjectAccessHook(OAT_POST_CREATE, ConstraintRelationId, conOid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ConstraintRelationId, conOid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	return conOid;
 }
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index c84dbc6..72acc17 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -136,8 +136,9 @@ ConversionCreate(const char *conname, Oid connamespace,
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new conversion */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   ConversionRelationId, HeapTupleGetOid(tup), 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ConversionRelationId, HeapTupleGetOid(tup), 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 	heap_close(rel, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 6d6c9e9..75867dc 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -20,6 +20,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_largeobject.h"
 #include "catalog/pg_largeobject_metadata.h"
@@ -71,6 +72,10 @@ LargeObjectCreate(Oid loid)
 
 	CatalogUpdateIndexes(pg_lo_meta, ntup);
 
+	/* Post creation hook for new large object */
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							LargeObjectRelationId, loid_new, 0,
+							PointerGetDatum(GETSTRUCT(ntup)));
 	heap_freetuple(ntup);
 
 	heap_close(pg_lo_meta, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c
index ceebac2..a21cefe 100644
--- a/src/backend/catalog/pg_namespace.c
+++ b/src/backend/catalog/pg_namespace.c
@@ -86,7 +86,9 @@ NamespaceCreate(const char *nspName, Oid ownerId)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new schema */
-	InvokeObjectAccessHook(OAT_POST_CREATE, NamespaceRelationId, nspoid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							NamespaceRelationId, nspoid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	return nspoid;
 }
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 772e5d4..4571293 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -271,11 +271,11 @@ OperatorShellMake(const char *operatorName,
 	/* Add dependencies for the entry */
 	makeOperatorDependencies(tup);
 
-	heap_freetuple(tup);
-
 	/* Post creation hook for new shell operator */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   OperatorRelationId, operatorObjectId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							OperatorRelationId, operatorObjectId, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
+	heap_freetuple(tup);
 
 	/*
 	 * Make sure the tuple is visible for subsequent lookups/updates.
@@ -543,8 +543,9 @@ OperatorCreate(const char *operatorName,
 	makeOperatorDependencies(tup);
 
 	/* Post creation hook for new operator */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   OperatorRelationId, operatorObjectId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							OperatorRelationId, operatorObjectId, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_close(pg_operator_desc, RowExclusiveLock);
 
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index f2f08721..d31f21c 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -620,10 +620,11 @@ ProcedureCreate(const char *procedureName,
 	/* dependency on extension */
 	recordDependencyOnCurrentExtension(&myself, is_update);
 
-	heap_freetuple(tup);
-
 	/* Post creation hook for new function */
-	InvokeObjectAccessHook(OAT_POST_CREATE, ProcedureRelationId, retval, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ProcedureRelationId, retval, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
+	heap_freetuple(tup);
 
 	heap_close(rel, RowExclusiveLock);
 
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index ea52f67..9e8049e 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -161,7 +161,10 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 								 false);
 
 	/* Post creation hook for new shell type */
-	InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typoid, 0);
+	InvokeObjectAccessHook2(OAT_POST_CREATE,
+							TypeRelationId, typoid, 0,
+							PointerGetDatum(GETSTRUCT(tup)),
+							BoolGetDatum(false));	/* not an implicit array */
 
 	/*
 	 * clean up and return the type-oid
@@ -465,8 +468,10 @@ TypeCreate(Oid newTypeOid,
 								 rebuildDeps);
 
 	/* Post creation hook for new type */
-	InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typeObjectId, 0);
-
+	InvokeObjectAccessHook2(OAT_POST_CREATE,
+							TypeRelationId, typeObjectId, 0,
+							PointerGetDatum(GETSTRUCT(tup)),
+							BoolGetDatum(isImplicitArray));
 	/*
 	 * finish up
 	 */
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index a09a3ad..e8b42f1 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -228,7 +228,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
 										   ONCOMMIT_NOOP,
 										   reloptions,
 										   false,
-										   true);
+										   true,
+										   false,
+										   false);
 	Assert(toast_relid != InvalidOid);
 
 	/* make the toast relation visible, else heap_open will fail */
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 670d29e..8c8ba71 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -653,7 +653,9 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace)
 										  ONCOMMIT_NOOP,
 										  reloptions,
 										  false,
-										  true);
+										  true,
+										  true,
+										  false);
 	Assert(OIDNewHeap != InvalidOid);
 
 	ReleaseSysCache(tuple);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 93240ef..59a17f7 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -520,7 +520,10 @@ createdb(const CreatedbStmt *stmt)
 	copyTemplateDependencies(src_dboid, dboid);
 
 	/* Post creation hook for new database */
-	InvokeObjectAccessHook(OAT_POST_CREATE, DatabaseRelationId, dboid, 0);
+	InvokeObjectAccessHook2(OAT_POST_CREATE,
+							DatabaseRelationId, dboid, 0,
+							PointerGetDatum(GETSTRUCT(tuple)),
+							ObjectIdGetDatum(src_dboid));
 
 	/*
 	 * Force a checkpoint before starting the copy. This will force dirty
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 9b9bb7d..d6ef9eb 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1519,7 +1519,6 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	extensionOid = simple_heap_insert(rel, tuple);
 	CatalogUpdateIndexes(rel, tuple);
 
-	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
 
 	/*
@@ -1549,8 +1548,10 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 		recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL);
 	}
 	/* Post creation hook for new extension */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   ExtensionRelationId, extensionOid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ExtensionRelationId, extensionOid, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
+	heap_freetuple(tuple);
 
 	return extensionOid;
 }
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 3a3c131..f03fa23 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -489,8 +489,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	fdwId = simple_heap_insert(rel, tuple);
 	CatalogUpdateIndexes(rel, tuple);
 
-	heap_freetuple(tuple);
-
 	/* record dependencies */
 	myself.classId = ForeignDataWrapperRelationId;
 	myself.objectId = fdwId;
@@ -518,9 +516,11 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new foreign data wrapper */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   ForeignDataWrapperRelationId, fdwId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ForeignDataWrapperRelationId, fdwId, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
 
+	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
 }
 
@@ -841,8 +841,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 
 	CatalogUpdateIndexes(rel, tuple);
 
-	heap_freetuple(tuple);
-
 	/* record dependencies */
 	myself.classId = ForeignServerRelationId;
 	myself.objectId = srvId;
@@ -859,8 +857,11 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new foreign server */
-	InvokeObjectAccessHook(OAT_POST_CREATE, ForeignServerRelationId, srvId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							ForeignServerRelationId, srvId, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
 
+	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
 }
 
@@ -1116,8 +1117,6 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 
 	CatalogUpdateIndexes(rel, tuple);
 
-	heap_freetuple(tuple);
-
 	/* Add dependency on the server */
 	myself.classId = UserMappingRelationId;
 	myself.objectId = umId;
@@ -1138,8 +1137,11 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new user mapping */
-	InvokeObjectAccessHook(OAT_POST_CREATE, UserMappingRelationId, umId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							UserMappingRelationId, umId, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
 
+	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
 }
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 92abd44..601b034 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1769,7 +1769,9 @@ CreateCast(CreateCastStmt *stmt)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new cast */
-	InvokeObjectAccessHook(OAT_POST_CREATE, CastRelationId, castid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							CastRelationId, castid, 0,
+							PointerGetDatum(tuple));
 
 	heap_freetuple(tuple);
 
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 2bb0d4c..056deb7 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -289,8 +289,6 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
 
 	CatalogUpdateIndexes(rel, tup);
 
-	heap_freetuple(tup);
-
 	/*
 	 * Create dependencies for the opfamily proper.  Note: we do not create a
 	 * dependency link to the AM, because we don't currently support DROP
@@ -313,9 +311,11 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new operator family */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   OperatorFamilyRelationId, opfamilyoid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							OperatorFamilyRelationId, opfamilyoid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
+	heap_freetuple(tup);
 	heap_close(rel, RowExclusiveLock);
 
 	return opfamilyoid;
@@ -662,8 +662,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
 
 	CatalogUpdateIndexes(rel, tup);
 
-	heap_freetuple(tup);
-
 	/*
 	 * Now add tuples to pg_amop and pg_amproc tying in the operators and
 	 * functions.  Dependencies on them are inserted, too.
@@ -716,9 +714,11 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new operator class */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   OperatorClassRelationId, opclassoid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							OperatorClassRelationId, opclassoid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
+	heap_freetuple(tup);
 	heap_close(rel, RowExclusiveLock);
 }
 
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 98770c5..3a1cc74 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -430,8 +430,9 @@ create_proc_lang(const char *languageName, bool replace,
 	}
 
 	/* Post creation hook for new procedural language */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   LanguageRelationId, myself.objectId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							LanguageRelationId, myself.objectId, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_close(rel, RowExclusiveLock);
 }
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 4509cda..441e42b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -600,7 +600,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 										  stmt->oncommit,
 										  reloptions,
 										  true,
-										  allowSystemTableMods);
+										  allowSystemTableMods,
+										  false,
+										  false);
 
 	/* Store inheritance information for new rel. */
 	StoreCatalogInheritance(relationId, inheritOids);
@@ -4367,12 +4369,13 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	/* keep catalog indexes current */
 	CatalogUpdateIndexes(pgclass, reltup);
 
-	heap_freetuple(reltup);
-
 	/* Post creation hook for new attribute */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   RelationRelationId, myrelid, newattnum);
+	InvokeObjectAccessHook2(OAT_POST_CREATE,
+							RelationRelationId, myrelid, newattnum,
+							PointerGetDatum(&attribute),
+							PointerGetDatum(GETSTRUCT(reltup)));
 
+	heap_freetuple(reltup);
 	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 09ecabb..4372eaa 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -330,14 +330,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 
 	CatalogUpdateIndexes(rel, tuple);
 
-	heap_freetuple(tuple);
-
 	/* Record dependency on owner */
 	recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId);
 
 	/* Post creation hook for new tablespace */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   TableSpaceRelationId, tablespaceoid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							TableSpaceRelationId, tablespaceoid, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
+
+	heap_freetuple(tuple);
 
 	create_tablespace_directories(location, tablespaceoid);
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 4c31f19..85ae505 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -134,6 +134,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	ScanKeyData key;
 	Relation	pgrel;
 	HeapTuple	tuple;
+	HeapTuple	reltup;
 	Oid			fargtypes[1];	/* dummy */
 	Oid			funcoid;
 	Oid			funcrettype;
@@ -630,32 +631,27 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 
 	CatalogUpdateIndexes(tgrel, tuple);
 
-	heap_freetuple(tuple);
 	heap_close(tgrel, RowExclusiveLock);
 
-	pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
-	pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
-	pfree(DatumGetPointer(values[Anum_pg_trigger_tgattr - 1]));
-
 	/*
 	 * Update relation's pg_class entry.  Crucial side-effect: other backends
 	 * (and this one too!) are sent SI message to make them rebuild relcache
 	 * entries.
 	 */
 	pgrel = heap_open(RelationRelationId, RowExclusiveLock);
-	tuple = SearchSysCacheCopy1(RELOID,
+	reltup = SearchSysCacheCopy1(RELOID,
 								ObjectIdGetDatum(RelationGetRelid(rel)));
-	if (!HeapTupleIsValid(tuple))
+	if (!HeapTupleIsValid(reltup))
 		elog(ERROR, "cache lookup failed for relation %u",
 			 RelationGetRelid(rel));
 
-	((Form_pg_class) GETSTRUCT(tuple))->relhastriggers = true;
+	((Form_pg_class) GETSTRUCT(reltup))->relhastriggers = true;
 
-	simple_heap_update(pgrel, &tuple->t_self, tuple);
+	simple_heap_update(pgrel, &reltup->t_self, reltup);
 
-	CatalogUpdateIndexes(pgrel, tuple);
+	CatalogUpdateIndexes(pgrel, reltup);
 
-	heap_freetuple(tuple);
+	heap_freetuple(reltup);
 	heap_close(pgrel, RowExclusiveLock);
 
 	/*
@@ -747,8 +743,17 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 							   DEPENDENCY_NORMAL);
 
 	/* Post creation hook for new trigger */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   TriggerRelationId, trigoid, 0);
+	InvokeObjectAccessHook2(OAT_POST_CREATE,
+							TriggerRelationId, trigoid, 0,
+							PointerGetDatum(GETSTRUCT(tuple)),
+							BoolGetDatum(isInternal));
+
+	/* Release contents of pg_trigger tuple */
+	pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
+	pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
+	pfree(DatumGetPointer(values[Anum_pg_trigger_tgattr - 1]));
+
+	heap_freetuple(tuple);
 
 	/* 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 deac106..ec48d97 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -275,7 +275,9 @@ DefineTSParser(List *names, List *parameters)
 	makeParserDependencies(tup);
 
 	/* Post creation hook for new text search parser */
-	InvokeObjectAccessHook(OAT_POST_CREATE, TSParserRelationId, prsOid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							TSParserRelationId, prsOid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 
@@ -627,8 +629,9 @@ DefineTSDictionary(List *names, List *parameters)
 	makeDictionaryDependencies(tup);
 
 	/* Post creation hook for new text search dictionary */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   TSDictionaryRelationId, dictOid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							TSDictionaryRelationId, dictOid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 
@@ -1169,7 +1172,9 @@ DefineTSTemplate(List *names, List *parameters)
 	makeTSTemplateDependencies(tup);
 
 	/* Post creation hook for new text search template */
-	InvokeObjectAccessHook(OAT_POST_CREATE, TSTemplateRelationId, dictOid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							TSTemplateRelationId, dictOid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 
@@ -1611,7 +1616,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);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							TSConfigRelationId, cfgOid, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
 	heap_freetuple(tup);
 
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 0367b20..505a010 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -434,7 +434,9 @@ CreateRole(CreateRoleStmt *stmt)
 				GetUserId(), false);
 
 	/* Post creation hook for new role */
-	InvokeObjectAccessHook(OAT_POST_CREATE, AuthIdRelationId, roleid, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							AuthIdRelationId, roleid, 0,
+							PointerGetDatum(GETSTRUCT(tuple)));
 
 	/*
 	 * Close pg_authid, but keep lock till commit.
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index eacd863..092473c 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2486,7 +2486,9 @@ OpenIntoRel(QueryDesc *queryDesc)
 											  into->onCommit,
 											  reloptions,
 											  true,
-											  allowSystemTableMods);
+											  allowSystemTableMods,
+											  false,
+											  true);
 	Assert(intoRelationId != InvalidOid);
 
 	/*
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 17db70e..a5cb7f7 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -137,8 +137,6 @@ InsertRule(char *rulname,
 	/* Need to update indexes in either case */
 	CatalogUpdateIndexes(pg_rewrite_desc, tup);
 
-	heap_freetuple(tup);
-
 	/* If replacing, get rid of old dependencies and make new ones */
 	if (is_update)
 		deleteDependencyRecordsFor(RewriteRelationId, rewriteObjectId, false);
@@ -177,9 +175,11 @@ InsertRule(char *rulname,
 	}
 
 	/* Post creation hook for new rule */
-	InvokeObjectAccessHook(OAT_POST_CREATE,
-						   RewriteRelationId, rewriteObjectId, 0);
+	InvokeObjectAccessHook1(OAT_POST_CREATE,
+							RewriteRelationId, rewriteObjectId, 0,
+							PointerGetDatum(GETSTRUCT(tup)));
 
+	heap_freetuple(tup);
 	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 e0441f5..0c2a2f1 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -38,7 +38,6 @@
 #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"
@@ -219,10 +218,6 @@ 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/include/catalog/heap.h b/src/include/catalog/heap.h
index aee2d88..8b013df 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -65,7 +65,9 @@ extern Oid heap_create_with_catalog(const char *relname,
 						 OnCommitAction oncommit,
 						 Datum reloptions,
 						 bool use_user_acl,
-						 bool allow_system_table_mods);
+						 bool allow_system_table_mods,
+						 bool is_rebuilt_relation,
+						 bool is_select_into);
 
 extern void heap_drop_with_catalog(Oid relid);
 
@@ -81,7 +83,7 @@ extern void InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
 					   CatalogIndexState indstate);
 
-extern void InsertPgClassTuple(Relation pg_class_desc,
+extern HeapTuple InsertPgClassTuple(Relation pg_class_desc,
 				   Relation new_rel_desc,
 				   Oid new_rel_oid,
 				   Datum relacl,
diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h
index 2925475..3d14e79 100644
--- a/src/include/catalog/objectaccess.h
+++ b/src/include/catalog/objectaccess.h
@@ -23,7 +23,7 @@
  */
 typedef enum ObjectAccessType
 {
-	OAT_POST_CREATE,
+	OAT_POST_CREATE,	/* Post-creation of database object */
 } ObjectAccessType;
 
 /*
@@ -33,14 +33,216 @@ typedef enum ObjectAccessType
 typedef void (*object_access_hook_type) (ObjectAccessType access,
 													 Oid classId,
 													 Oid objectId,
-													 int subId);
+													 int subId,
+													 int nargs,
+													 Datum argv[]);
 
 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 InvokeObjectAccessHook0(access,classId,objectId,subId)	\
+	do {														\
+		if (object_access_hook)									\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId),	\
+								  0, NULL);						\
+	} while(0)
+
+#define InvokeObjectAccessHook1(access,classId,objectId,subId,	\
+								arg0)							\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[1];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  1, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook2(access,classId,objectId,subId,	\
+								arg0, arg1)						\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[2];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  2, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook3(access,classId,objectId,subId,	\
+								arg0, arg1, arg2)				\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[3];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  3, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook4(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3)			\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[4];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  4, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook5(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4)	\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[5];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  5, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook6(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4,	\
+								arg5)							\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[6];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+			____temp_arg_buf[5] = (arg5);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  6, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook7(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4,	\
+								arg5, arg6)						\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[7];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+			____temp_arg_buf[5] = (arg5);						\
+			____temp_arg_buf[6] = (arg6);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  7, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook8(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4,	\
+								arg5, arg6, arg7)				\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[8];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+			____temp_arg_buf[5] = (arg5);						\
+			____temp_arg_buf[6] = (arg6);						\
+			____temp_arg_buf[7] = (arg7);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  8, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook8(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4,	\
+								arg5, arg6, arg7)				\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[8];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+			____temp_arg_buf[5] = (arg5);						\
+			____temp_arg_buf[6] = (arg6);						\
+			____temp_arg_buf[7] = (arg7);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  8, ____temp_arg_buf);			\
+		}														\
+	} while(0)
+
+#define InvokeObjectAccessHook9(access,classId,objectId,subId,	\
+								arg0, arg1, arg2, arg3, arg4,	\
+								arg5, arg6, arg7, arg8)			\
+	do {														\
+		if (object_access_hook)									\
+		{														\
+			Datum	____temp_arg_buf[9];						\
+																\
+			____temp_arg_buf[0] = (arg0);						\
+			____temp_arg_buf[1] = (arg1);						\
+			____temp_arg_buf[2] = (arg2);						\
+			____temp_arg_buf[3] = (arg3);						\
+			____temp_arg_buf[4] = (arg4);						\
+			____temp_arg_buf[5] = (arg5);						\
+			____temp_arg_buf[6] = (arg6);						\
+			____temp_arg_buf[7] = (arg7);						\
+			____temp_arg_buf[8] = (arg8);						\
+																\
+			(*object_access_hook)((access),						\
+								  (classId),(objectId),(subId), \
+								  9, ____temp_arg_buf);			\
+		}														\
 	} while(0)
 
 #endif   /* OBJECTACCESS_H */