1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

refactor: split ATExecAlterConstrRecurse()

This splits out a couple of subroutines from
ATExecAlterConstrRecurse().  This makes the main function a bit
smaller, and a future patch (NOT ENFORCED foreign-key constraints)
will also want to call some of the pieces separately.

Author: Amul Sul <amul.sul@enterprisedb.com>
Reviewed-by: jian he <jian.universality@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA%40mail.gmail.com
This commit is contained in:
Peter Eisentraut
2025-01-16 13:22:01 +01:00
parent d278541be4
commit 7a947ed25b

View File

@ -394,6 +394,12 @@ static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
static bool ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
Relation rel, HeapTuple contuple, List **otherrelids,
LOCKMODE lockmode);
static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
bool deferrable, bool initdeferred,
List **otherrelids);
static void ATExecAlterChildConstr(Constraint *cmdcon, Relation conrel, Relation tgrel,
Relation rel, HeapTuple contuple, List **otherrelids,
LOCKMODE lockmode);
static ObjectAddress ATExecValidateConstraint(List **wqueue,
Relation rel, char *constrName,
bool recurse, bool recursing, LOCKMODE lockmode);
@ -11861,9 +11867,6 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
{
HeapTuple copyTuple;
Form_pg_constraint copy_con;
HeapTuple tgtuple;
ScanKeyData tgkey;
SysScanDesc tgscan;
copyTuple = heap_copytuple(contuple);
copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
@ -11884,6 +11887,42 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
* Now we need to update the multiple entries in pg_trigger that
* implement the constraint.
*/
AlterConstrTriggerDeferrability(conoid, tgrel, rel, cmdcon->deferrable,
cmdcon->initdeferred, otherrelids);
}
/*
* If the table at either end of the constraint is partitioned, we need to
* recurse and handle every constraint that is a child of this one.
*
* (This assumes that the recurse flag is forcibly set for partitioned
* tables, and not set for legacy inheritance, though we don't check for
* that here.)
*/
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE)
ATExecAlterChildConstr(cmdcon, conrel, tgrel, rel, contuple,
otherrelids, lockmode);
return changed;
}
/*
* A subroutine of ATExecAlterConstrRecurse that updated constraint trigger's
* deferrability.
*
* The arguments to this function have the same meaning as the arguments to
* ATExecAlterConstrRecurse.
*/
static void
AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
bool deferrable, bool initdeferred,
List **otherrelids)
{
HeapTuple tgtuple;
ScanKeyData tgkey;
SysScanDesc tgscan;
ScanKeyInit(&tgkey,
Anum_pg_trigger_tgconstraint,
BTEqualStrategyNumber, F_OIDEQ,
@ -11898,19 +11937,19 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
/*
* Remember OIDs of other relation(s) involved in FK constraint.
* (Note: it's likely that we could skip forcing a relcache inval
* for other rels that don't have a trigger whose properties
* change, but let's be conservative.)
* (Note: it's likely that we could skip forcing a relcache inval for
* other rels that don't have a trigger whose properties change, but
* let's be conservative.)
*/
if (tgform->tgrelid != RelationGetRelid(rel))
*otherrelids = list_append_unique_oid(*otherrelids,
tgform->tgrelid);
/*
* Update deferrability of RI_FKey_noaction_del,
* Update enable status and deferrability of RI_FKey_noaction_del,
* RI_FKey_noaction_upd, RI_FKey_check_ins and RI_FKey_check_upd
* triggers, but not others; see createForeignKeyActionTriggers
* and CreateFKCheckTrigger.
* triggers, but not others; see createForeignKeyActionTriggers and
* CreateFKCheckTrigger.
*/
if (tgform->tgfoid != F_RI_FKEY_NOACTION_DEL &&
tgform->tgfoid != F_RI_FKEY_NOACTION_UPD &&
@ -11921,8 +11960,8 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
tgCopyTuple = heap_copytuple(tgtuple);
copy_tg = (Form_pg_trigger) GETSTRUCT(tgCopyTuple);
copy_tg->tgdeferrable = cmdcon->deferrable;
copy_tg->tginitdeferred = cmdcon->initdeferred;
copy_tg->tgdeferrable = deferrable;
copy_tg->tginitdeferred = initdeferred;
CatalogTupleUpdate(tgrel, &tgCopyTuple->t_self, tgCopyTuple);
InvokeObjectPostAlterHook(TriggerRelationId, tgform->oid, 0);
@ -11934,20 +11973,26 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
}
/*
* If the table at either end of the constraint is partitioned, we need to
* recurse and handle every constraint that is a child of this one.
* Invokes ATExecAlterConstrRecurse for each constraint that is a child of the
* specified constraint.
*
* (This assumes that the recurse flag is forcibly set for partitioned
* tables, and not set for legacy inheritance, though we don't check for
* that here.)
* The arguments to this function have the same meaning as the arguments to
* ATExecAlterConstrRecurse.
*/
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE)
static void
ATExecAlterChildConstr(Constraint *cmdcon, Relation conrel, Relation tgrel,
Relation rel, HeapTuple contuple, List **otherrelids,
LOCKMODE lockmode)
{
Form_pg_constraint currcon;
Oid conoid;
ScanKeyData pkey;
SysScanDesc pscan;
HeapTuple childtup;
currcon = (Form_pg_constraint) GETSTRUCT(contuple);
conoid = currcon->oid;
ScanKeyInit(&pkey,
Anum_pg_constraint_conparentid,
BTEqualStrategyNumber, F_OIDEQ,
@ -11970,9 +12015,6 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
systable_endscan(pscan);
}
return changed;
}
/*
* ALTER TABLE VALIDATE CONSTRAINT
*