Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7a947ed

Browse files
committed
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 <[email protected]> Reviewed-by: jian he <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA%40mail.gmail.com
1 parent d278541 commit 7a947ed

File tree

1 file changed

+112
-70
lines changed

1 file changed

+112
-70
lines changed

src/backend/commands/tablecmds.c

Lines changed: 112 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,12 @@ static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
394394
static bool ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
395395
Relation rel, HeapTuple contuple, List **otherrelids,
396396
LOCKMODE lockmode);
397+
static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
398+
bool deferrable, bool initdeferred,
399+
List **otherrelids);
400+
static void ATExecAlterChildConstr(Constraint *cmdcon, Relation conrel, Relation tgrel,
401+
Relation rel, HeapTuple contuple, List **otherrelids,
402+
LOCKMODE lockmode);
397403
static ObjectAddress ATExecValidateConstraint(List **wqueue,
398404
Relation rel, char *constrName,
399405
bool recurse, bool recursing, LOCKMODE lockmode);
@@ -11861,9 +11867,6 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
1186111867
{
1186211868
HeapTuple copyTuple;
1186311869
Form_pg_constraint copy_con;
11864-
HeapTuple tgtuple;
11865-
ScanKeyData tgkey;
11866-
SysScanDesc tgscan;
1186711870

1186811871
copyTuple = heap_copytuple(contuple);
1186911872
copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
@@ -11884,53 +11887,8 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
1188411887
* Now we need to update the multiple entries in pg_trigger that
1188511888
* implement the constraint.
1188611889
*/
11887-
ScanKeyInit(&tgkey,
11888-
Anum_pg_trigger_tgconstraint,
11889-
BTEqualStrategyNumber, F_OIDEQ,
11890-
ObjectIdGetDatum(conoid));
11891-
tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
11892-
NULL, 1, &tgkey);
11893-
while (HeapTupleIsValid(tgtuple = systable_getnext(tgscan)))
11894-
{
11895-
Form_pg_trigger tgform = (Form_pg_trigger) GETSTRUCT(tgtuple);
11896-
Form_pg_trigger copy_tg;
11897-
HeapTuple tgCopyTuple;
11898-
11899-
/*
11900-
* Remember OIDs of other relation(s) involved in FK constraint.
11901-
* (Note: it's likely that we could skip forcing a relcache inval
11902-
* for other rels that don't have a trigger whose properties
11903-
* change, but let's be conservative.)
11904-
*/
11905-
if (tgform->tgrelid != RelationGetRelid(rel))
11906-
*otherrelids = list_append_unique_oid(*otherrelids,
11907-
tgform->tgrelid);
11908-
11909-
/*
11910-
* Update deferrability of RI_FKey_noaction_del,
11911-
* RI_FKey_noaction_upd, RI_FKey_check_ins and RI_FKey_check_upd
11912-
* triggers, but not others; see createForeignKeyActionTriggers
11913-
* and CreateFKCheckTrigger.
11914-
*/
11915-
if (tgform->tgfoid != F_RI_FKEY_NOACTION_DEL &&
11916-
tgform->tgfoid != F_RI_FKEY_NOACTION_UPD &&
11917-
tgform->tgfoid != F_RI_FKEY_CHECK_INS &&
11918-
tgform->tgfoid != F_RI_FKEY_CHECK_UPD)
11919-
continue;
11920-
11921-
tgCopyTuple = heap_copytuple(tgtuple);
11922-
copy_tg = (Form_pg_trigger) GETSTRUCT(tgCopyTuple);
11923-
11924-
copy_tg->tgdeferrable = cmdcon->deferrable;
11925-
copy_tg->tginitdeferred = cmdcon->initdeferred;
11926-
CatalogTupleUpdate(tgrel, &tgCopyTuple->t_self, tgCopyTuple);
11927-
11928-
InvokeObjectPostAlterHook(TriggerRelationId, tgform->oid, 0);
11929-
11930-
heap_freetuple(tgCopyTuple);
11931-
}
11932-
11933-
systable_endscan(tgscan);
11890+
AlterConstrTriggerDeferrability(conoid, tgrel, rel, cmdcon->deferrable,
11891+
cmdcon->initdeferred, otherrelids);
1193411892
}
1193511893

1193611894
/*
@@ -11943,34 +11901,118 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
1194311901
*/
1194411902
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
1194511903
get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE)
11904+
ATExecAlterChildConstr(cmdcon, conrel, tgrel, rel, contuple,
11905+
otherrelids, lockmode);
11906+
11907+
return changed;
11908+
}
11909+
11910+
/*
11911+
* A subroutine of ATExecAlterConstrRecurse that updated constraint trigger's
11912+
* deferrability.
11913+
*
11914+
* The arguments to this function have the same meaning as the arguments to
11915+
* ATExecAlterConstrRecurse.
11916+
*/
11917+
static void
11918+
AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
11919+
bool deferrable, bool initdeferred,
11920+
List **otherrelids)
11921+
{
11922+
HeapTuple tgtuple;
11923+
ScanKeyData tgkey;
11924+
SysScanDesc tgscan;
11925+
11926+
ScanKeyInit(&tgkey,
11927+
Anum_pg_trigger_tgconstraint,
11928+
BTEqualStrategyNumber, F_OIDEQ,
11929+
ObjectIdGetDatum(conoid));
11930+
tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
11931+
NULL, 1, &tgkey);
11932+
while (HeapTupleIsValid(tgtuple = systable_getnext(tgscan)))
1194611933
{
11947-
ScanKeyData pkey;
11948-
SysScanDesc pscan;
11949-
HeapTuple childtup;
11934+
Form_pg_trigger tgform = (Form_pg_trigger) GETSTRUCT(tgtuple);
11935+
Form_pg_trigger copy_tg;
11936+
HeapTuple tgCopyTuple;
1195011937

11951-
ScanKeyInit(&pkey,
11952-
Anum_pg_constraint_conparentid,
11953-
BTEqualStrategyNumber, F_OIDEQ,
11954-
ObjectIdGetDatum(conoid));
11938+
/*
11939+
* Remember OIDs of other relation(s) involved in FK constraint.
11940+
* (Note: it's likely that we could skip forcing a relcache inval for
11941+
* other rels that don't have a trigger whose properties change, but
11942+
* let's be conservative.)
11943+
*/
11944+
if (tgform->tgrelid != RelationGetRelid(rel))
11945+
*otherrelids = list_append_unique_oid(*otherrelids,
11946+
tgform->tgrelid);
1195511947

11956-
pscan = systable_beginscan(conrel, ConstraintParentIndexId,
11957-
true, NULL, 1, &pkey);
11948+
/*
11949+
* Update enable status and deferrability of RI_FKey_noaction_del,
11950+
* RI_FKey_noaction_upd, RI_FKey_check_ins and RI_FKey_check_upd
11951+
* triggers, but not others; see createForeignKeyActionTriggers and
11952+
* CreateFKCheckTrigger.
11953+
*/
11954+
if (tgform->tgfoid != F_RI_FKEY_NOACTION_DEL &&
11955+
tgform->tgfoid != F_RI_FKEY_NOACTION_UPD &&
11956+
tgform->tgfoid != F_RI_FKEY_CHECK_INS &&
11957+
tgform->tgfoid != F_RI_FKEY_CHECK_UPD)
11958+
continue;
1195811959

11959-
while (HeapTupleIsValid(childtup = systable_getnext(pscan)))
11960-
{
11961-
Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup);
11962-
Relation childrel;
11960+
tgCopyTuple = heap_copytuple(tgtuple);
11961+
copy_tg = (Form_pg_trigger) GETSTRUCT(tgCopyTuple);
1196311962

11964-
childrel = table_open(childcon->conrelid, lockmode);
11965-
ATExecAlterConstrRecurse(cmdcon, conrel, tgrel, childrel, childtup,
11966-
otherrelids, lockmode);
11967-
table_close(childrel, NoLock);
11968-
}
11963+
copy_tg->tgdeferrable = deferrable;
11964+
copy_tg->tginitdeferred = initdeferred;
11965+
CatalogTupleUpdate(tgrel, &tgCopyTuple->t_self, tgCopyTuple);
11966+
11967+
InvokeObjectPostAlterHook(TriggerRelationId, tgform->oid, 0);
1196911968

11970-
systable_endscan(pscan);
11969+
heap_freetuple(tgCopyTuple);
1197111970
}
1197211971

11973-
return changed;
11972+
systable_endscan(tgscan);
11973+
}
11974+
11975+
/*
11976+
* Invokes ATExecAlterConstrRecurse for each constraint that is a child of the
11977+
* specified constraint.
11978+
*
11979+
* The arguments to this function have the same meaning as the arguments to
11980+
* ATExecAlterConstrRecurse.
11981+
*/
11982+
static void
11983+
ATExecAlterChildConstr(Constraint *cmdcon, Relation conrel, Relation tgrel,
11984+
Relation rel, HeapTuple contuple, List **otherrelids,
11985+
LOCKMODE lockmode)
11986+
{
11987+
Form_pg_constraint currcon;
11988+
Oid conoid;
11989+
ScanKeyData pkey;
11990+
SysScanDesc pscan;
11991+
HeapTuple childtup;
11992+
11993+
currcon = (Form_pg_constraint) GETSTRUCT(contuple);
11994+
conoid = currcon->oid;
11995+
11996+
ScanKeyInit(&pkey,
11997+
Anum_pg_constraint_conparentid,
11998+
BTEqualStrategyNumber, F_OIDEQ,
11999+
ObjectIdGetDatum(conoid));
12000+
12001+
pscan = systable_beginscan(conrel, ConstraintParentIndexId,
12002+
true, NULL, 1, &pkey);
12003+
12004+
while (HeapTupleIsValid(childtup = systable_getnext(pscan)))
12005+
{
12006+
Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup);
12007+
Relation childrel;
12008+
12009+
childrel = table_open(childcon->conrelid, lockmode);
12010+
ATExecAlterConstrRecurse(cmdcon, conrel, tgrel, childrel, childtup,
12011+
otherrelids, lockmode);
12012+
table_close(childrel, NoLock);
12013+
}
12014+
12015+
systable_endscan(pscan);
1197412016
}
1197512017

1197612018
/*

0 commit comments

Comments
 (0)