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 <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
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy