diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 340350fa3950d09a67cb03cb525a8d67bd217328..976f2d204cd2cafcf3a960dabb2d37647472f447 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -25,6 +25,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_collation.h" #include "catalog/pg_conversion.h" @@ -1290,6 +1291,13 @@ SetDefaultACL(InternalDefaultACL *iacls) iacls->roleid, noldmembers, oldmembers, nnewmembers, newmembers); + + if (isNew) + InvokeObjectPostCreateHook(DefaultAclRelationId, + HeapTupleGetOid(newtuple), 0); + else + InvokeObjectPostAlterHook(DefaultAclRelationId, + HeapTupleGetOid(newtuple), 0); } if (HeapTupleIsValid(tuple)) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 04a927dd0c6f15917c5d38d30392a547bcd886c7..0b4c659ff0751a48e69c4b7886a7ba38804eb46a 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -96,8 +96,9 @@ static Oid AddNewRelationType(const char *typeName, static void RelationRemoveInheritance(Oid relid); static void StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, - bool is_no_inherit); -static void StoreConstraints(Relation rel, List *cooked_constraints); + bool is_no_inherit, bool is_internal); +static void StoreConstraints(Relation rel, List *cooked_constraints, + bool is_internal); static bool MergeWithExistingConstraint(Relation rel, char *ccname, Node *expr, bool allow_merge, bool is_local, bool is_no_inherit); @@ -1302,7 +1303,7 @@ heap_create_with_catalog(const char *relname, * entry, so the relation must be valid and self-consistent at this point. * In particular, there are not yet constraints and defaults anywhere. */ - StoreConstraints(new_rel_desc, cooked_constraints); + StoreConstraints(new_rel_desc, cooked_constraints, is_internal); /* * If there's a special on-commit action, remember it @@ -1836,7 +1837,8 @@ heap_drop_with_catalog(Oid relid) * Store a default expression for column attnum of relation rel. */ void -StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr) +StoreAttrDefault(Relation rel, AttrNumber attnum, + Node *expr, bool is_internal) { char *adbin; char *adsrc; @@ -1928,6 +1930,17 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr) * Record dependencies on objects used in the expression, too. */ recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL); + + /* + * Post creation hook for attribute defaults. + * + * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented + * with a couple of deletion/creation of the attribute's default entry, + * so the callee should check existence of an older version of this + * entry if it needs to distinguish. + */ + InvokeObjectPostCreateHookArg(AttrDefaultRelationId, + RelationGetRelid(rel), attnum, is_internal); } /* @@ -1939,7 +1952,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr) static void StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, - bool is_no_inherit) + bool is_no_inherit, bool is_internal) { char *ccbin; char *ccsrc; @@ -2023,7 +2036,8 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr, ccsrc, /* Source form of check constraint */ is_local, /* conislocal */ inhcount, /* coninhcount */ - is_no_inherit); /* connoinherit */ + is_no_inherit, /* connoinherit */ + is_internal); /* internally constructed? */ pfree(ccbin); pfree(ccsrc); @@ -2038,7 +2052,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr, * and StoreRelCheck (see AddRelationNewConstraints()). */ static void -StoreConstraints(Relation rel, List *cooked_constraints) +StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal) { int numchecks = 0; ListCell *lc; @@ -2060,11 +2074,12 @@ StoreConstraints(Relation rel, List *cooked_constraints) switch (con->contype) { case CONSTR_DEFAULT: - StoreAttrDefault(rel, con->attnum, con->expr); + StoreAttrDefault(rel, con->attnum, con->expr, is_internal); break; case CONSTR_CHECK: StoreRelCheck(rel, con->name, con->expr, !con->skip_validation, - con->is_local, con->inhcount, con->is_no_inherit); + con->is_local, con->inhcount, + con->is_no_inherit, is_internal); numchecks++; break; default: @@ -2090,6 +2105,7 @@ StoreConstraints(Relation rel, List *cooked_constraints) * newConstraints: list of Constraint nodes * allow_merge: TRUE if check constraints may be merged with existing ones * is_local: TRUE if definition is local, FALSE if it's inherited + * is_internal: TRUE if result of some internal process, not a user request * * All entries in newColDefaults will be processed. Entries in newConstraints * will be processed only if they are CONSTR_CHECK type. @@ -2107,7 +2123,8 @@ AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, - bool is_local) + bool is_local, + bool is_internal) { List *cookedConstraints = NIL; TupleDesc tupleDesc; @@ -2170,7 +2187,7 @@ AddRelationNewConstraints(Relation rel, (IsA(expr, Const) &&((Const *) expr)->constisnull)) continue; - StoreAttrDefault(rel, colDef->attnum, expr); + StoreAttrDefault(rel, colDef->attnum, expr, is_internal); cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint)); cooked->contype = CONSTR_DEFAULT; @@ -2296,7 +2313,7 @@ AddRelationNewConstraints(Relation rel, * OK, store it. */ StoreRelCheck(rel, ccname, expr, !cdef->skip_validation, is_local, - is_local ? 0 : 1, cdef->is_no_inherit); + is_local ? 0 : 1, cdef->is_no_inherit, is_internal); numchecks++; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 33a18030b797797df7b1f2f30706b8ab2ab42886..7966558218f4f24cd9bf8953b473f212a0454fc1 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -933,7 +933,8 @@ index_create(Relation heapRelation, false, /* already marked primary */ false, /* pg_index entry is OK */ false, /* no old dependencies */ - allow_system_table_mods); + allow_system_table_mods, + is_internal); } else { @@ -1107,6 +1108,7 @@ index_create(Relation heapRelation, * remove_old_dependencies: if true, remove existing dependencies of index * on table's columns * allow_system_table_mods: allow table to be a system catalog + * is_internal: index is constructed due to internal process */ void index_constraint_create(Relation heapRelation, @@ -1119,7 +1121,8 @@ index_constraint_create(Relation heapRelation, bool mark_as_primary, bool update_pgindex, bool remove_old_dependencies, - bool allow_system_table_mods) + bool allow_system_table_mods, + bool is_internal) { Oid namespaceId = RelationGetNamespace(heapRelation); ObjectAddress myself, @@ -1184,7 +1187,8 @@ index_constraint_create(Relation heapRelation, NULL, true, /* islocal */ 0, /* inhcount */ - true); /* noinherit */ + true, /* noinherit */ + is_internal); /* * Register the index as internally dependent on the constraint. @@ -1293,6 +1297,9 @@ index_constraint_create(Relation heapRelation, { simple_heap_update(pg_index, &indexTuple->t_self, indexTuple); CatalogUpdateIndexes(pg_index, indexTuple); + + InvokeObjectPostAlterHookArg(IndexRelationId, indexRelationId, 0, + InvalidOid, is_internal); } heap_freetuple(indexTuple); diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c index 09f9db5aaf83f2c0b61c7df6e3ad2ce3dca67d24..bc565ebe497f3ef72ff67e9f6142394a9523cfe1 100644 --- a/src/backend/catalog/objectaccess.c +++ b/src/backend/catalog/objectaccess.c @@ -61,3 +61,26 @@ RunObjectDropHook(Oid classId, Oid objectId, int subId, classId, objectId, subId, (void *) &drop_arg); } + +/* + * RunObjectPostAlterHook + * + * It is entrypoint of OAT_POST_ALTER event + */ +void +RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, + Oid auxiliaryId, bool is_internal) +{ + ObjectAccessPostAlter pa_arg; + + /* caller should check, but just in case... */ + Assert(object_access_hook != NULL); + + memset(&pa_arg, 0, sizeof(ObjectAccessPostAlter)); + pa_arg.auxiliary_id = auxiliaryId; + pa_arg.is_internal = is_internal; + + (*object_access_hook)(OAT_POST_ALTER, + classId, objectId, subId, + (void *) &pa_arg); +} diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 547c7ee00c623e160e708c39105ba539c6efcdbf..7ddadcce4da96b9f28cc9c7455d94d93cf64b1a7 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -68,7 +68,8 @@ CreateConstraintEntry(const char *constraintName, const char *conSrc, bool conIsLocal, int conInhCount, - bool conNoInherit) + bool conNoInherit, + bool is_internal) { Relation conDesc; Oid conOid; @@ -367,7 +368,8 @@ CreateConstraintEntry(const char *constraintName, } /* Post creation hook for new constraint */ - InvokeObjectPostCreateHook(ConstraintRelationId, conOid, 0); + InvokeObjectPostCreateHookArg(ConstraintRelationId, conOid, 0, + is_internal); return conOid; } @@ -665,6 +667,8 @@ RenameConstraintById(Oid conId, const char *newname) /* update the system catalog indexes */ CatalogUpdateIndexes(conDesc, tuple); + InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0); + heap_freetuple(tuple); heap_close(conDesc, RowExclusiveLock); } @@ -737,6 +741,8 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, */ } + InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0); + add_exact_object_address(&thisobj, objsMoved); } diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c index 337ccdd633b4c4afefab843251e8781d0a044a6f..45949129cfbe38a57c34c425ba0c719b1d5cfb60 100644 --- a/src/backend/catalog/pg_db_role_setting.c +++ b/src/backend/catalog/pg_db_role_setting.c @@ -14,6 +14,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_db_role_setting.h" #include "utils/fmgroids.h" #include "utils/rel.h" @@ -160,6 +161,9 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt) CatalogUpdateIndexes(rel, newtuple); } + InvokeObjectPostAlterHookArg(DbRoleSettingRelationId, + databaseid, 0, roleid, false); + systable_endscan(scan); /* Close pg_db_role_setting, but keep lock till commit */ diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index b044400d993af128fb0a73e546b3e4bc68dbf692..23ac3dd33657006838e796825eaa601d1a103eac 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -712,6 +712,8 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) /* update the system catalog indexes */ CatalogUpdateIndexes(pg_type_desc, tuple); + InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + heap_freetuple(tuple); heap_close(pg_type_desc, RowExclusiveLock); diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 416a068fc755a6f2a8a610c36b5705521c65caa9..2d2ab1bcfb148079757e7789853388fb6228f44e 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -19,6 +19,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_collation.h" #include "catalog/pg_conversion.h" #include "catalog/pg_event_trigger.h" @@ -281,6 +282,8 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) simple_heap_update(rel, &oldtup->t_self, newtup); CatalogUpdateIndexes(rel, newtup); + InvokeObjectPostAlterHook(classId, objectId, 0); + /* Release memory */ pfree(values); pfree(nulls); @@ -657,6 +660,8 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) changeDependencyFor(classId, objid, NamespaceRelationId, oldNspOid, nspOid); + InvokeObjectPostAlterHook(classId, objid, 0); + return oldNspOid; } @@ -934,4 +939,6 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) pfree(nulls); pfree(replaces); } + + InvokeObjectPostAlterHook(classId, objectId, 0); } diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 8ab8c1751952aa9c01a477f6aa80806cb67d2793..ef9c5f1adc7242cf504f40878c4eee87019a3e06 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -27,6 +27,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/toasting.h" #include "commands/cluster.h" #include "commands/matview.h" @@ -481,7 +482,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMOD * otherwise concurrent executions of RelationGetIndexList could miss indexes. */ void -mark_index_clustered(Relation rel, Oid indexOid) +mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) { HeapTuple indexTuple; Form_pg_index indexForm; @@ -541,6 +542,10 @@ mark_index_clustered(Relation rel, Oid indexOid) simple_heap_update(pg_index, &indexTuple->t_self, indexTuple); CatalogUpdateIndexes(pg_index, indexTuple); } + + InvokeObjectPostAlterHookArg(IndexRelationId, thisIndexOid, 0, + InvalidOid, is_internal); + heap_freetuple(indexTuple); } @@ -569,7 +574,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid, /* Mark the correct index as clustered */ if (OidIsValid(indexOid)) - mark_index_clustered(OldHeap, indexOid); + mark_index_clustered(OldHeap, indexOid, true); /* Remember if it's a system catalog */ is_system_catalog = IsSystemRelation(OldHeap); @@ -590,7 +595,8 @@ rebuild_relation(Relation OldHeap, Oid indexOid, * rebuild the target's indexes and throw away the transient table. */ finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog, - swap_toast_by_content, false, frozenXid, frozenMulti); + swap_toast_by_content, false, true, + frozenXid, frozenMulti); } @@ -1120,6 +1126,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, static void swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, bool swap_toast_by_content, + bool is_internal, TransactionId frozenXid, MultiXactId frozenMulti, Oid *mapped_tables) @@ -1283,6 +1290,15 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, CacheInvalidateRelcacheByTuple(reltup2); } + /* + * Post alter hook for modified relations. The change to r2 is always + * internal, but r1 depends on the invocation context. + */ + InvokeObjectPostAlterHookArg(RelationRelationId, r1, 0, + InvalidOid, is_internal); + InvokeObjectPostAlterHookArg(RelationRelationId, r2, 0, + InvalidOid, true); + /* * If we have toast tables associated with the relations being swapped, * deal with them too. @@ -1298,6 +1314,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, relform2->reltoastrelid, target_is_pg_class, swap_toast_by_content, + is_internal, frozenXid, frozenMulti, mapped_tables); @@ -1388,6 +1405,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, relform2->reltoastidxid, target_is_pg_class, swap_toast_by_content, + is_internal, InvalidTransactionId, InvalidMultiXactId, mapped_tables); @@ -1427,6 +1445,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, bool is_system_catalog, bool swap_toast_by_content, bool check_constraints, + bool is_internal, TransactionId frozenXid, MultiXactId frozenMulti) { @@ -1444,8 +1463,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, */ swap_relation_files(OIDOldHeap, OIDNewHeap, (OIDOldHeap == RelationRelationId), - swap_toast_by_content, frozenXid, frozenMulti, - mapped_tables); + swap_toast_by_content, is_internal, + frozenXid, frozenMulti, mapped_tables); /* * If it's a system catalog, queue an sinval message to flush all @@ -1526,13 +1545,13 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u", OIDOldHeap); RenameRelationInternal(newrel->rd_rel->reltoastrelid, - NewToastName); + NewToastName, true); /* ... and its index too */ snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u_index", OIDOldHeap); RenameRelationInternal(toastidx, - NewToastName); + NewToastName, true); } relation_close(newrel, NoLock); } diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 76ef23a1f44ade7f3bbc12162808f048c80546de..b3911bff350e625b4be2c2f02302cb2a82423f8c 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -997,6 +997,8 @@ RenameDatabase(const char *oldname, const char *newname) simple_heap_update(rel, &newtup->t_self, newtup); CatalogUpdateIndexes(rel, newtup); + InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0); + /* * Close pg_database, but keep lock till commit. */ @@ -1234,6 +1236,9 @@ movedb(const char *dbname, const char *tblspcname) /* Update indexes */ CatalogUpdateIndexes(pgdbrel, newtuple); + InvokeObjectPostAlterHook(DatabaseRelationId, + HeapTupleGetOid(newtuple), 0); + systable_endscan(sysscan); /* @@ -1431,6 +1436,9 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel) /* Update indexes */ CatalogUpdateIndexes(rel, newtuple); + InvokeObjectPostAlterHook(DatabaseRelationId, + HeapTupleGetOid(newtuple), 0); + systable_endscan(scan); /* Close pg_database, but keep lock till commit */ @@ -1570,6 +1578,8 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) newOwnerId); } + InvokeObjectPostAlterHook(DatabaseRelationId, HeapTupleGetOid(tuple), 0); + systable_endscan(scan); /* Close pg_database, but keep lock till commit */ diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 2c3b6bf1dfaf68954c296cf58c666bda536a0180..fbe8f49a9e71c2fea6b4915ac2f7f1977747c588 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -412,6 +412,9 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) simple_heap_update(tgrel, &tup->t_self, tup); CatalogUpdateIndexes(tgrel, tup); + InvokeObjectPostAlterHook(EventTriggerRelationId, + trigoid, 0); + /* clean up */ heap_freetuple(tup); heap_close(tgrel, RowExclusiveLock); @@ -507,6 +510,9 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) changeDependencyOnOwner(EventTriggerRelationId, HeapTupleGetOid(tup), newOwnerId); + + InvokeObjectPostAlterHook(EventTriggerRelationId, + HeapTupleGetOid(tup), 0); } /* diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 6b7cb5bc84237a1962e8cb2248c99f3a81af5291..36df8bddcad8c94a59d91b0c7115dbcb4b5949f0 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2573,6 +2573,8 @@ AlterExtensionNamespace(List *names, const char *newschema) changeDependencyFor(ExtensionRelationId, extensionOid, NamespaceRelationId, oldNspOid, nspOid); + InvokeObjectPostAlterHook(ExtensionRelationId, extensionOid, 0); + return extensionOid; } @@ -2856,6 +2858,8 @@ ApplyExtensionUpdates(Oid extensionOid, recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL); } + InvokeObjectPostAlterHook(ExtensionRelationId, extensionOid, 0); + /* * Finally, execute the update script file */ @@ -2969,6 +2973,8 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) extension_config_remove(extension.objectId, object.objectId); } + InvokeObjectPostAlterHook(ExtensionRelationId, extension.objectId, 0); + /* * If get_object_address() opened the relation for us, we close it to keep * the reference count correct - but we retain any locks acquired by diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 83cdf9e3c51e90154198547394645ef419177aeb..fb311185c8beeb38a8f1144b84875b9eb8642427 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -241,6 +241,9 @@ AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerI HeapTupleGetOid(tup), newOwnerId); } + + InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, + HeapTupleGetOid(tup), 0); } /* @@ -349,6 +352,9 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup), newOwnerId); } + + InvokeObjectPostAlterHook(ForeignServerRelationId, + HeapTupleGetOid(tup), 0); } /* @@ -764,6 +770,8 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) } } + InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, fdwId, 0); + heap_close(rel, RowExclusiveLock); return fdwId; @@ -994,6 +1002,8 @@ AlterForeignServer(AlterForeignServerStmt *stmt) simple_heap_update(rel, &tp->t_self, tp); CatalogUpdateIndexes(rel, tp); + InvokeObjectPostAlterHook(ForeignServerRelationId, srvId, 0); + heap_freetuple(tp); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index fda379a75df3b995ec3cf8d48f621e0d315d5209..9f0ac9bd50a86d8387011415c7d146e1f824f6cf 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1169,6 +1169,8 @@ AlterFunction(AlterFunctionStmt *stmt) simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); + InvokeObjectPostAlterHook(ProcedureRelationId, funcOid, 0); + heap_close(rel, NoLock); heap_freetuple(tup); diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 6a0643828a4f728689c9c3057cb10a459b372823..e20fedaeaf77772a47b34f423ddeb062b429bf1f 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -198,8 +198,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, * Swap the physical files of the target and transient tables, then * rebuild the target's indexes and throw away the transient table. */ - finish_heap_swap(matviewOid, OIDNewHeap, false, false, true, RecentXmin, - ReadNextMultiXactId()); + finish_heap_swap(matviewOid, OIDNewHeap, false, false, true, true, + RecentXmin, ReadNextMultiXactId()); RelationCacheInvalidateEntry(matviewOid); } diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index e9563fbfab4bda3af3b44296572b144785fddeb5..68ec57ac4b6d683b5ce796524e4b89433b07aead 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -1374,6 +1374,9 @@ storeOperators(List *opfamilyname, Oid amoid, referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + /* Post create hook of this access method operator */ + InvokeObjectPostCreateHook(AccessMethodOperatorRelationId, + entryoid, 0); } heap_close(rel, RowExclusiveLock); @@ -1473,6 +1476,9 @@ storeProcedures(List *opfamilyname, Oid amoid, referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); } + /* Post create hook of access method procedure */ + InvokeObjectPostCreateHook(AccessMethodProcedureRelationId, + entryoid, 0); } heap_close(rel, RowExclusiveLock); diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 1e857d988fed089ba2be2570b1cc49416f3f8674..21d7e608df43bf48f045e2a20af2d269d739e94c 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -21,6 +21,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "commands/dbcommands.h" #include "commands/schemacmds.h" @@ -240,6 +241,8 @@ RenameSchema(const char *oldname, const char *newname) simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); + InvokeObjectPostAlterHook(NamespaceRelationId, HeapTupleGetOid(tup), 0); + heap_close(rel, NoLock); heap_freetuple(tup); @@ -376,4 +379,6 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) newOwnerId); } + InvokeObjectPostAlterHook(NamespaceRelationId, + HeapTupleGetOid(tup), 0); } diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index de41c8a1c71500d3f430110037d161432cf78802..225edd9f9b7c8e317c4c6e66151444ce6a947aed 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -20,6 +20,7 @@ #include "access/xlogutils.h" #include "catalog/dependency.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_type.h" #include "commands/defrem.h" #include "commands/sequence.h" @@ -487,6 +488,8 @@ AlterSequence(AlterSeqStmt *stmt) if (owned_by) process_owned_by(seqrel, owned_by); + InvokeObjectPostAlterHook(RelationRelationId, relid, 0); + relation_close(seqrel, NoLock); return relid; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8bb8f54ae52d23f398e085872c4729dd013a5c78..51bf13944b2a6a54d65c7f58a7b521b9287f3e57 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -669,7 +669,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) */ if (rawDefaults || stmt->constraints) AddRelationNewConstraints(rel, rawDefaults, stmt->constraints, - true, true); + true, true, false); /* * Clean up. We keep lock on new relation (although it shouldn't be @@ -1975,6 +1975,15 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid, recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL); + /* + * Post creation hook of this inheritance. Since object_access_hook + * doesn't take multiple object identifiers, we relay oid of parent + * relation using auxiliary_id argument. + */ + InvokeObjectPostAlterHookArg(InheritsRelationId, + relationId, 0, + parentOid, false); + /* * Mark the parent as having subclasses. */ @@ -2234,6 +2243,8 @@ renameatt_internal(Oid myrelid, /* keep system catalog indexes current */ CatalogUpdateIndexes(attrelation, atttup); + InvokeObjectPostAlterHook(RelationRelationId, myrelid, attnum); + heap_freetuple(atttup); heap_close(attrelation, RowExclusiveLock); @@ -2381,7 +2392,7 @@ rename_constraint_internal(Oid myrelid, || con->contype == CONSTRAINT_UNIQUE || con->contype == CONSTRAINT_EXCLUSION)) /* rename the index; this renames the constraint as well */ - RenameRelationInternal(con->conindid, newconname); + RenameRelationInternal(con->conindid, newconname, false); else RenameConstraintById(constraintOid, newconname); @@ -2461,7 +2472,7 @@ RenameRelation(RenameStmt *stmt) } /* Do the work */ - RenameRelationInternal(relid, stmt->newname); + RenameRelationInternal(relid, stmt->newname, false); return relid; } @@ -2476,7 +2487,7 @@ RenameRelation(RenameStmt *stmt) * sequence, AFAIK there's no need for it to be there. */ void -RenameRelationInternal(Oid myrelid, const char *newrelname) +RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal) { Relation targetrelation; Relation relrelation; /* for RELATION relation */ @@ -2518,6 +2529,9 @@ RenameRelationInternal(Oid myrelid, const char *newrelname) /* keep the system catalog indexes current */ CatalogUpdateIndexes(relrelation, reltup); + InvokeObjectPostAlterHookArg(RelationRelationId, myrelid, 0, + InvalidOid, is_internal); + heap_freetuple(reltup); heap_close(relrelation, RowExclusiveLock); @@ -3531,7 +3545,9 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode) * interest in letting this code work on system catalogs. */ finish_heap_swap(tab->relid, OIDNewHeap, - false, false, true, RecentXmin, + false, false, true, + !OidIsValid(tab->newTableSpace), + RecentXmin, ReadNextMultiXactId()); } else @@ -4531,7 +4547,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, * This function is intended for CREATE TABLE, so it processes a * _list_ of defaults, but we just do one. */ - AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true); + AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, + false, true, false); /* Make the additional catalog changes visible */ CommandCounterIncrement(); @@ -4869,6 +4886,9 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) CatalogUpdateIndexes(attr_rel, tuple); } + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), attnum); + heap_close(attr_rel, RowExclusiveLock); } @@ -4921,6 +4941,9 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, tab->new_notnull = true; } + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), attnum); + heap_close(attr_rel, RowExclusiveLock); } @@ -4975,7 +4998,8 @@ ATExecColumnDefault(Relation rel, const char *colName, * This function is intended for CREATE TABLE, so it processes a * _list_ of defaults, but we just do one. */ - AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true); + AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, + false, true, false); } } @@ -5060,6 +5084,9 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE /* keep system catalog indexes current */ CatalogUpdateIndexes(attrelation, tuple); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + attrtuple->attnum); heap_freetuple(tuple); heap_close(attrelation, RowExclusiveLock); @@ -5117,13 +5144,18 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, repl_repl[Anum_pg_attribute_attoptions - 1] = true; newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation), repl_val, repl_null, repl_repl); - ReleaseSysCache(tuple); /* Update system catalog. */ simple_heap_update(attrelation, &newtuple->t_self, newtuple); CatalogUpdateIndexes(attrelation, newtuple); + + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + attrtuple->attnum); heap_freetuple(newtuple); + ReleaseSysCache(tuple); + heap_close(attrelation, RowExclusiveLock); } @@ -5193,6 +5225,10 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc /* keep system catalog indexes current */ CatalogUpdateIndexes(attrelation, tuple); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + attrtuple->attnum); + heap_freetuple(tuple); heap_close(attrelation, RowExclusiveLock); @@ -5507,7 +5543,7 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, ereport(NOTICE, (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"", indexName, constraintName))); - RenameRelationInternal(index_oid, constraintName); + RenameRelationInternal(index_oid, constraintName, false); } /* Extra checks needed if making primary key */ @@ -5531,7 +5567,8 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, stmt->primary, true, /* update pg_index */ true, /* remove old dependencies */ - allowSystemTableMods); + allowSystemTableMods, + false); /* is_internal */ index_close(indexRel, NoLock); } @@ -5643,7 +5680,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, newcons = AddRelationNewConstraints(rel, NIL, list_make1(copyObject(constr)), recursing, /* allow_merge */ - !recursing); /* is_local */ + !recursing, /* is_local */ + is_readd); /* is_internal */ /* Add each to-be-validated constraint to Phase 3's queue */ foreach(lcon, newcons) @@ -6097,7 +6135,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, NULL, true, /* islocal */ 0, /* inhcount */ - true); /* isnoinherit */ + true, /* isnoinherit */ + false); /* is_internal */ /* * Create the triggers that will enforce the constraint. @@ -6279,6 +6318,10 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, copy_con->convalidated = true; simple_heap_update(conrel, ©Tuple->t_self, copyTuple); CatalogUpdateIndexes(conrel, copyTuple); + + InvokeObjectPostAlterHook(ConstraintRelationId, + HeapTupleGetOid(tuple), 0); + heap_freetuple(copyTuple); } @@ -7707,6 +7750,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, */ RemoveStatistics(RelationGetRelid(rel), attnum); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), attnum); + /* * Update the default, if present, by brute force --- remove and re-add * the default. Probably unsafe to take shortcuts, since the new version @@ -7726,7 +7772,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true, true); - StoreAttrDefault(rel, attnum, defaultexpr); + StoreAttrDefault(rel, attnum, defaultexpr, true); } /* Cleanup */ @@ -7817,11 +7863,16 @@ ATExecAlterColumnGenericOptions(Relation rel, newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel), repl_val, repl_null, repl_repl); - ReleaseSysCache(tuple); simple_heap_update(attrel, &newtuple->t_self, newtuple); CatalogUpdateIndexes(attrel, newtuple); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + atttableform->attnum); + + ReleaseSysCache(tuple); + heap_close(attrel, RowExclusiveLock); heap_freetuple(newtuple); @@ -8296,6 +8347,8 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock } } + InvokeObjectPostAlterHook(RelationRelationId, relationOid, 0); + ReleaseSysCache(tuple); heap_close(class_rel, RowExclusiveLock); relation_close(target_rel, NoLock); @@ -8457,7 +8510,7 @@ ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode) check_index_is_clusterable(rel, indexOid, false, lockmode); /* And do the work */ - mark_index_clustered(rel, indexOid); + mark_index_clustered(rel, indexOid, false); } /* @@ -8469,7 +8522,7 @@ ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode) static void ATExecDropCluster(Relation rel, LOCKMODE lockmode) { - mark_index_clustered(rel, InvalidOid); + mark_index_clustered(rel, InvalidOid, false); } /* @@ -8590,6 +8643,8 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, CatalogUpdateIndexes(pgclass, newtuple); + InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0); + heap_freetuple(newtuple); ReleaseSysCache(tuple); @@ -8647,6 +8702,10 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, CatalogUpdateIndexes(pgclass, newtuple); + InvokeObjectPostAlterHookArg(RelationRelationId, + RelationGetRelid(toastrel), 0, + InvalidOid, true); + heap_freetuple(newtuple); ReleaseSysCache(tuple); @@ -8688,6 +8747,9 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) if (newTableSpace == oldTableSpace || (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0)) { + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), 0); + relation_close(rel, NoLock); return; } @@ -8785,6 +8847,8 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) simple_heap_update(pg_class, &tuple->t_self, tuple); CatalogUpdateIndexes(pg_class, tuple); + InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0); + heap_freetuple(tuple); heap_close(pg_class, RowExclusiveLock); @@ -9487,6 +9551,15 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) RelationRelationId, RelationGetRelid(parent_rel)); + /* + * Post alter hook of this inherits. Since object_access_hook doesn't + * take multiple object identifiers, we relay oid of parent relation + * using auxiliary_id argument. + */ + InvokeObjectPostAlterHookArg(InheritsRelationId, + RelationGetRelid(rel), 0, + RelationGetRelid(parent_rel), false); + /* keep our lock on the parent relation until commit */ heap_close(parent_rel, NoLock); } @@ -9669,6 +9742,9 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) ((Form_pg_class) GETSTRUCT(classtuple))->reloftype = typeid; simple_heap_update(relationRelation, &classtuple->t_self, classtuple); CatalogUpdateIndexes(relationRelation, classtuple); + + InvokeObjectPostAlterHook(RelationRelationId, relid, 0); + heap_freetuple(classtuple); heap_close(relationRelation, RowExclusiveLock); @@ -9709,6 +9785,9 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode) ((Form_pg_class) GETSTRUCT(tuple))->reloftype = InvalidOid; simple_heap_update(relationRelation, &tuple->t_self, tuple); CatalogUpdateIndexes(relationRelation, tuple); + + InvokeObjectPostAlterHook(RelationRelationId, relid, 0); + heap_freetuple(tuple); heap_close(relationRelation, RowExclusiveLock); } @@ -9778,6 +9857,9 @@ ATExecGenericOptions(Relation rel, List *options) simple_heap_update(ftrel, &tuple->t_self, tuple); CatalogUpdateIndexes(ftrel, tuple); + InvokeObjectPostAlterHook(ForeignTableRelationId, + RelationGetRelid(rel), 0); + heap_close(ftrel, RowExclusiveLock); heap_freetuple(tuple); @@ -9935,6 +10017,8 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid, NameStr(classForm->relname)); add_exact_object_address(&thisobj, objsMoved); + + InvokeObjectPostAlterHook(RelationRelationId, relOid, 0); } heap_freetuple(classTup); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index dfcc829b85fb04d33b957450fed4c1ab1ac127bf..8589512998a2218f8a8cca6af8e26da975018836 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -877,6 +877,8 @@ RenameTableSpace(const char *oldname, const char *newname) simple_heap_update(rel, &newtuple->t_self, newtuple); CatalogUpdateIndexes(rel, newtuple); + InvokeObjectPostAlterHook(TableSpaceRelationId, tspId, 0); + heap_close(rel, NoLock); return tspId; @@ -945,6 +947,9 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) /* Update system catalog. */ simple_heap_update(rel, &newtuple->t_self, newtuple); CatalogUpdateIndexes(rel, newtuple); + + InvokeObjectPostAlterHook(TableSpaceRelationId, HeapTupleGetOid(tup), 0); + heap_freetuple(newtuple); /* Conclude heap scan. */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index f79cef508c13987c32a3133d87e5c9f750648904..bebb551f7fa75dbef370925472467713eae3faca 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -446,7 +446,8 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, NULL, true, /* islocal */ 0, /* inhcount */ - true); /* isnoinherit */ + true, /* isnoinherit */ + isInternal); /* is_internal */ } /* @@ -742,7 +743,8 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, DEPENDENCY_NORMAL); /* Post creation hook for new trigger */ - InvokeObjectPostCreateHook(TriggerRelationId, trigoid, 0); + InvokeObjectPostCreateHookArg(TriggerRelationId, trigoid, 0, + isInternal); /* Keep lock on target rel until end of xact */ heap_close(rel, NoLock); @@ -1276,6 +1278,9 @@ renametrig(RenameStmt *stmt) /* keep system catalog indexes current */ CatalogUpdateIndexes(tgrel, tuple); + InvokeObjectPostAlterHook(TriggerRelationId, + HeapTupleGetOid(tuple), 0); + /* * Invalidate relation's relcache entry so that other backends (and * this one too!) are sent SI message to make them rebuild relcache @@ -1391,6 +1396,9 @@ EnableDisableTrigger(Relation rel, const char *tgname, changed = true; } + + InvokeObjectPostAlterHook(TriggerRelationId, + HeapTupleGetOid(tuple), 0); } systable_endscan(tgscan); diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 821fdc6b31e60f918fe333b93f0a672663404e22..57b69f88ab09dcd499627d040df4258183edf40b 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -612,6 +612,8 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) CatalogUpdateIndexes(rel, newtup); + InvokeObjectPostAlterHook(TSDictionaryRelationId, dictId, 0); + /* * NOTE: because we only support altering the options, not the template, * there is no need to update dependencies. This might have to change if @@ -1184,6 +1186,9 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) /* Update dependencies */ makeConfigurationDependencies(tup, true, relMap); + InvokeObjectPostAlterHook(TSConfigMapRelationId, + HeapTupleGetOid(tup), 0); + heap_close(relMap, RowExclusiveLock); ReleaseSysCache(tup); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 1ba6d5e6e99c0132ed2d220800b67819e2848fd6..2c4c6cbced17f8ca2251bc17ff15798de51f7a6f 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -39,6 +39,7 @@ #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/indexing.h" +#include "catalog/objectaccess.h" #include "catalog/pg_authid.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -1214,6 +1215,8 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) stmt->newValNeighbor, stmt->newValIsAfter, stmt->skipIfExists); + InvokeObjectPostAlterHook(TypeRelationId, enum_type_oid, 0); + ReleaseSysCache(tup); return enum_type_oid; @@ -2190,6 +2193,8 @@ AlterDomainDefault(List *names, Node *defaultRaw) defaultExpr, true); /* Rebuild is true */ + InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0); + /* Clean up */ heap_close(rel, NoLock); heap_freetuple(newtuple); @@ -2299,6 +2304,8 @@ AlterDomainNotNull(List *names, bool notNull) CatalogUpdateIndexes(typrel, tup); + InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0); + /* Clean up */ heap_freetuple(tup); heap_close(typrel, RowExclusiveLock); @@ -2586,6 +2593,10 @@ AlterDomainValidateConstraint(List *names, char *constrName) copy_con->convalidated = true; simple_heap_update(conrel, ©Tuple->t_self, copyTuple); CatalogUpdateIndexes(conrel, copyTuple); + + InvokeObjectPostAlterHook(ConstraintRelationId, + HeapTupleGetOid(copyTuple), 0); + heap_freetuple(copyTuple); systable_endscan(scan); @@ -2993,7 +3004,8 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, ccsrc, /* Source form of check constraint */ true, /* is local */ 0, /* inhcount */ - false); /* connoinherit */ + false, /* connoinherit */ + false); /* is_internal */ /* * Return the compiled constraint expression so the calling routine can @@ -3188,7 +3200,7 @@ RenameType(RenameStmt *stmt) * RenameRelationInternal will call RenameTypeInternal automatically. */ if (typTup->typtype == TYPTYPE_COMPOSITE) - RenameRelationInternal(typTup->typrelid, newTypeName); + RenameRelationInternal(typTup->typrelid, newTypeName, false); else RenameTypeInternal(typeOid, newTypeName, typTup->typnamespace); @@ -3311,6 +3323,8 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) /* Update owner dependency reference */ changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId); + InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + /* If it has an array type, update that too */ if (OidIsValid(typTup->typarray)) AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false); @@ -3333,6 +3347,8 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) * * hasDependEntry should be TRUE if type is expected to have a pg_shdepend * entry (ie, it's not a table rowtype nor an array type). + * is_primary_ops should be TRUE if this function is invoked with user's + * direct operation (e.g, shdepReassignOwned). Elsewhere, */ void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, @@ -3366,6 +3382,8 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, if (OidIsValid(typTup->typarray)) AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false); + InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + /* Clean up */ heap_close(rel, RowExclusiveLock); } @@ -3553,6 +3571,8 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, elog(ERROR, "failed to change schema dependency for type %s", format_type_be(typeOid)); + InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 9302416375583ac62d41651f4f150ff85376b64e..c7886ed799e6bc7be60886f15bd9984073a0d0e2 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -777,6 +777,8 @@ AlterRole(AlterRoleStmt *stmt) /* Update indexes */ CatalogUpdateIndexes(pg_authid_rel, new_tuple); + InvokeObjectPostAlterHook(AuthIdRelationId, roleid, 0); + ReleaseSysCache(tuple); heap_freetuple(new_tuple); @@ -1161,6 +1163,8 @@ RenameRole(const char *oldname, const char *newname) CatalogUpdateIndexes(rel, newtuple); + InvokeObjectPostAlterHook(AuthIdRelationId, roleid, 0); + ReleaseSysCache(oldtuple); /* diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index ca92fb56417cb44c9f8add3e37bfcf9cd8e57ae8..cb59f139e143097acdf8fae5076a4bf4232e7e83 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -815,6 +815,9 @@ EnableDisableRule(Relation rel, const char *rulename, changed = true; } + InvokeObjectPostAlterHook(RewriteRelationId, + HeapTupleGetOid(ruletup), 0); + heap_freetuple(ruletup); heap_close(pg_rewrite_desc, RowExclusiveLock); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 989089a25afe80d7e8d4d91eb6b7dea9774d8198..97d507e4c2321fbd3c35fd6a2ff58fadc99f33df 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -96,9 +96,11 @@ extern List *AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, - bool is_local); + bool is_local, + bool is_internal); -extern void StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr); +extern void StoreAttrDefault(Relation rel, AttrNumber attnum, + Node *expr, bool is_internal); extern Node *cookDefault(ParseState *pstate, Node *raw_default, diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index fb323f7201112d553c32be11b54486b7982fee7c..e6972752448351c10b2315d5d236a9cfd3e1b124 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -72,7 +72,8 @@ extern void index_constraint_create(Relation heapRelation, bool mark_as_primary, bool update_pgindex, bool remove_old_dependencies, - bool allow_system_table_mods); + bool allow_system_table_mods, + bool is_internal); extern void index_drop(Oid indexId, bool concurrent); diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h index b9bb1bcd2f5efa2ebd291bbcfd1b9bca69d2254a..25f963b0748f13f661b3ae3154529cca2a36ae68 100644 --- a/src/include/catalog/objectaccess.h +++ b/src/include/catalog/objectaccess.h @@ -22,6 +22,11 @@ * OAT_DROP should be invoked just before deletion of objects; typically * deleteOneObject(). Its arguments are packed within ObjectAccessDrop. * + * OAT_POST_ALTER should be invoked just after the object is altered, + * but before the command counter is incremented. An extension using the + * hook can use SnapshotNow and SnapshotSelf to get the old and new + * versions of the tuple. + * * Other types may be added in the future. */ typedef enum ObjectAccessType @@ -57,20 +62,51 @@ typedef struct } ObjectAccessDrop; /* - * Hook, and a macro to invoke it. + * Arguments of OAT_POST_ALTER event */ +typedef struct +{ + /* + * This identifier is used when system catalog takes two IDs + * to identify a particular tuple of the catalog. + * It is only used when the caller want to identify an entry + * of pg_inherits, pg_db_role_setting or pg_user_mapping. + * Elsewhere, InvalidOid should be set. + */ + Oid auxiliary_id; + + /* + * If this flag is set, the user hasn't requested that the object be + * altered, but we're doing it anyway for some internal reason. + * Permissions-checking hooks may want to skip checks if, say, we're + * alter the constraints of a temporary heap during CLUSTER. + */ + bool is_internal; +} ObjectAccessPostAlter; + +/* Plugin provides a hook function matching this signature. */ typedef void (*object_access_hook_type) (ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg); +/* Plugin sets this variable to a suitable hook function. */ extern PGDLLIMPORT object_access_hook_type object_access_hook; +/* Core code uses these functions to call the hook (see macros below). */ extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, bool is_internal); extern void RunObjectDropHook(Oid classId, Oid objectId, int subId, int dropflags); +extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, + Oid auxiliaryId, bool is_internal); + +/* + * The following macros are wrappers around the functions above; these should + * normally be used to invoke the hook in lieu of calling the above functions + * directly. + */ #define InvokeObjectPostCreateHook(classId,objectId,subId) \ InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false) @@ -90,4 +126,15 @@ extern void RunObjectDropHook(Oid classId, Oid objectId, int subId, (dropflags)); \ } while(0) +#define InvokeObjectPostAlterHook(classId,objectId,subId) \ + InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \ + InvalidOid,false) +#define InvokeObjectPostAlterHookArg(classId,objectId,subId, \ + auxiliaryId,is_internal) \ + do { \ + if (object_access_hook) \ + RunObjectPostAlterHook((classId),(objectId),(subId), \ + (auxiliaryId),(is_internal)); \ + } while(0) + #endif /* OBJECTACCESS_H */ diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 29f71f1be5d7e51e9554bb55e3015e1ef0a3810c..4a6a18f0e7ace857b9b88243c90895ef866a6fd4 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -232,7 +232,8 @@ extern Oid CreateConstraintEntry(const char *constraintName, const char *conSrc, bool conIsLocal, int conInhCount, - bool conNoInherit); + bool conNoInherit, + bool is_internal); extern void RemoveConstraintById(Oid conId); extern void RenameConstraintById(Oid conId, const char *newname); diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h index 73c701fe53eed0b47346eacf82d1eefd05b868e8..aa6d332e9d2e7e2b90fd4fd0e9c840c6f80a446d 100644 --- a/src/include/commands/cluster.h +++ b/src/include/commands/cluster.h @@ -23,13 +23,14 @@ extern void cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose, int freeze_min_age, int freeze_table_age); extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMODE lockmode); -extern void mark_index_clustered(Relation rel, Oid indexOid); +extern void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal); extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace); extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, bool is_system_catalog, bool swap_toast_by_content, bool check_constraints, + bool is_internal, TransactionId frozenXid, MultiXactId frozenMulti); diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 031c77c9efd0278767ba610874e99a46031235e3..7b86c444f66a46294ad344cc3df6c4d3b4cbabba 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -58,7 +58,7 @@ extern Oid RenameConstraint(RenameStmt *stmt); extern Oid RenameRelation(RenameStmt *stmt); extern void RenameRelationInternal(Oid myrelid, - const char *newrelname); + const char *newrelname, bool is_internal); extern void find_composite_type_dependencies(Oid typeOid, Relation origRelation,