diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2025-03-11 08:40:42 +0100 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2025-03-11 08:43:35 +0100 |
commit | 64224a834ce4c899e878db27b14ea3412a6ddbed (patch) | |
tree | b60ab94c3342d6514957a28f3a680a735641b876 | |
parent | 76def4cdd7c2b32d19e950a160f834392ea51744 (diff) | |
download | postgresql-64224a834ce4c899e878db27b14ea3412a6ddbed.tar.gz postgresql-64224a834ce4c899e878db27b14ea3412a6ddbed.zip |
refactor: re-add ATExecAlterChildConstr()
ATExecAlterChildConstr() was removed in commit 80d7f990496, but it is
needed in some subsequent patches for the NOT ENFORCED feature, to
recurse over child constraints. This adds it back in slightly altered
form.
Author: Amul Sul <amul.sul@enterprisedb.com>
Reviewed-by: Alexandra Wang <alexandra.wang.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA%40mail.gmail.com
-rw-r--r-- | src/backend/commands/tablecmds.c | 84 |
1 files changed, 54 insertions, 30 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1f870982559..e9b95018199 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -398,6 +398,10 @@ static bool ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdc static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel, bool deferrable, bool initdeferred, List **otherrelids); +static void ATExecAlterChildConstr(List **wqueue, ATAlterConstraint *cmdcon, + Relation conrel, Relation tgrel, Relation rel, + HeapTuple contuple, bool recurse, List **otherrelids, + LOCKMODE lockmode); static ObjectAddress ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName, bool recurse, bool recursing, LOCKMODE lockmode); @@ -12031,41 +12035,13 @@ ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdcon, /* * If the table at either end of the constraint is partitioned, we need to * handle every constraint that is a child of this one. - * - * Note that this doesn't handle recursion the normal way, viz. by - * scanning the list of child relations and recursing; instead it uses the - * conparentid relationships. This may need to be reconsidered. */ if (recurse && changed && (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE || (OidIsValid(refrelid) && get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE))) - { - ScanKeyData pkey; - SysScanDesc pscan; - HeapTuple childtup; - - ScanKeyInit(&pkey, - Anum_pg_constraint_conparentid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(currcon->oid)); - - pscan = systable_beginscan(conrel, ConstraintParentIndexId, - true, NULL, 1, &pkey); - - while (HeapTupleIsValid(childtup = systable_getnext(pscan))) - { - Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup); - Relation childrel; - - childrel = table_open(childcon->conrelid, lockmode); - ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, childrel, - childtup, recurse, otherrelids, lockmode); - table_close(childrel, NoLock); - } - - systable_endscan(pscan); - } + ATExecAlterChildConstr(wqueue, cmdcon, conrel, tgrel, rel, contuple, + recurse, otherrelids, lockmode); /* * Update the catalog for inheritability. No work if the constraint is @@ -12204,6 +12180,54 @@ AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel, } /* + * Invokes ATExecAlterConstraintInternal for each constraint that is a child of + * the specified constraint. + * + * Note that this doesn't handle recursion the normal way, viz. by scanning the + * list of child relations and recursing; instead it uses the conparentid + * relationships. This may need to be reconsidered. + * + * The arguments to this function have the same meaning as the arguments to + * ATExecAlterConstraintInternal. + */ +static void +ATExecAlterChildConstr(List **wqueue, ATAlterConstraint *cmdcon, + Relation conrel, Relation tgrel, Relation rel, + HeapTuple contuple, bool recurse, 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, + ObjectIdGetDatum(conoid)); + + pscan = systable_beginscan(conrel, ConstraintParentIndexId, + true, NULL, 1, &pkey); + + while (HeapTupleIsValid(childtup = systable_getnext(pscan))) + { + Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup); + Relation childrel; + + childrel = table_open(childcon->conrelid, lockmode); + ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, childrel, + childtup, recurse, otherrelids, lockmode); + table_close(childrel, NoLock); + } + + systable_endscan(pscan); +} + +/* * ALTER TABLE VALIDATE CONSTRAINT * * XXX The reason we handle recursion here rather than at Phase 1 is because |