Commit 05f3f9c7 authored by Robert Haas's avatar Robert Haas

Extend object-access hook machinery to support post-alter events.

This also slightly widens the scope of what we support in terms of
post-create events.

KaiGai Kohei, with a few changes, mostly to the comments, by me
parent 6ac7facd
......@@ -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))
......
......@@ -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++;
......
......@@ -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);
......
......@@ -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);
}
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
}
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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);
}
/*
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
......@@ -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;
......
This diff is collapsed.
......@@ -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. */
......
......@@ -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);
......
......@@ -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);
......
......@@ -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, &copyTuple->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);
......
......@@ -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);
/*
......
......@@ -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);
......
......@@ -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,
......
......@@ -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);
......
......@@ -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 */
......@@ -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);
......
......@@ -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);
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment