mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Record parents of triggers
This let us get rid of a recently introduced ugly hack (commit
1fa846f1c9
).
Author: Álvaro Herrera
Reviewed-by: Amit Langote, Tom Lane
Discussion: https://postgr.es/m/20200217215641.GA29784@alvherre.pgsql
This commit is contained in:
@ -16447,54 +16447,6 @@ out:
|
||||
MemoryContextDelete(cxt);
|
||||
}
|
||||
|
||||
/*
|
||||
* isPartitionTrigger
|
||||
* Subroutine for CloneRowTriggersToPartition: determine whether
|
||||
* the given trigger has been cloned from another one.
|
||||
*
|
||||
* We use pg_depend as a proxy for this, since we don't have any direct
|
||||
* evidence. This is an ugly hack to cope with a catalog deficiency.
|
||||
* Keep away from children. Do not stare with naked eyes. Do not propagate.
|
||||
*/
|
||||
static bool
|
||||
isPartitionTrigger(Oid trigger_oid)
|
||||
{
|
||||
Relation pg_depend;
|
||||
ScanKeyData key[2];
|
||||
SysScanDesc scan;
|
||||
HeapTuple tup;
|
||||
bool found = false;
|
||||
|
||||
pg_depend = table_open(DependRelationId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&key[0], Anum_pg_depend_classid,
|
||||
BTEqualStrategyNumber,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(TriggerRelationId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid,
|
||||
BTEqualStrategyNumber,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(trigger_oid));
|
||||
|
||||
scan = systable_beginscan(pg_depend, DependDependerIndexId,
|
||||
true, NULL, 2, key);
|
||||
while ((tup = systable_getnext(scan)) != NULL)
|
||||
{
|
||||
Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(tup);
|
||||
|
||||
if (dep->refclassid == TriggerRelationId)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
systable_endscan(scan);
|
||||
table_close(pg_depend, AccessShareLock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* CloneRowTriggersToPartition
|
||||
* subroutine for ATExecAttachPartition/DefineRelation to create row
|
||||
@ -16537,11 +16489,10 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
|
||||
|
||||
/*
|
||||
* Internal triggers require careful examination. Ideally, we don't
|
||||
* clone them.
|
||||
*
|
||||
* However, if our parent is a partitioned relation, there might be
|
||||
* internal triggers that need cloning. In that case, we must skip
|
||||
* clone it if the trigger on parent depends on another trigger.
|
||||
* clone them. However, if our parent is itself a partition, there
|
||||
* might be internal triggers that must not be skipped; for example,
|
||||
* triggers on our parent that are in turn clones from its parent (our
|
||||
* grandparent) are marked internal, yet they are to be cloned.
|
||||
*
|
||||
* Note we dare not verify that the other trigger belongs to an
|
||||
* ancestor relation of our parent, because that creates deadlock
|
||||
@ -16549,7 +16500,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
|
||||
*/
|
||||
if (trigForm->tgisinternal &&
|
||||
(!parent->rd_rel->relispartition ||
|
||||
!isPartitionTrigger(trigForm->oid)))
|
||||
!OidIsValid(trigForm->tgparentid)))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -847,6 +847,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
|
||||
|
||||
values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
|
||||
values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
|
||||
values[Anum_pg_trigger_tgparentid - 1] = ObjectIdGetDatum(parentTriggerOid);
|
||||
values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
|
||||
CStringGetDatum(trigname));
|
||||
values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
|
||||
|
Reference in New Issue
Block a user