summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane2015-05-03 15:30:24 +0000
committerTom Lane2015-05-03 15:30:24 +0000
commita4820434c1a62e0c5f4051a31ad8b4a11f0a6ad7 (patch)
tree91933f0ab93519019e7034c6e53b3abf47a9824e /src/backend/commands
parentf707b53449f3ab6998c615b746ad01f5775723a3 (diff)
Fix overlooked relcache invalidation in ALTER TABLE ... ALTER CONSTRAINT.
When altering the deferredness state of a foreign key constraint, we correctly updated the catalogs and then invalidated the relcache state for the target relation ... but that's not the only relation with relevant triggers. Must invalidate the other table as well, or the state change fails to take effect promptly for operations triggered on the other table. Per bug #13224 from Christian Ullrich. In passing, reorganize regression test case for this feature so that it isn't randomly injected into the middle of an unrelated test sequence. Oversight in commit f177cbfe676dc2c7ca2b206c54d6bf819feeea8b. Back-patch to 9.4 where the faulty code was added.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/tablecmds.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 5d842857523..299d8ccd81f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -6603,12 +6603,12 @@ static ObjectAddress
ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
bool recurse, bool recursing, LOCKMODE lockmode)
{
+ Constraint *cmdcon;
Relation conrel;
SysScanDesc scan;
ScanKeyData key;
HeapTuple contuple;
Form_pg_constraint currcon = NULL;
- Constraint *cmdcon = NULL;
bool found = false;
ObjectAddress address;
@@ -6655,10 +6655,11 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
HeapTuple copyTuple;
HeapTuple tgtuple;
Form_pg_constraint copy_con;
- Form_pg_trigger copy_tg;
+ List *otherrelids = NIL;
ScanKeyData tgkey;
SysScanDesc tgscan;
Relation tgrel;
+ ListCell *lc;
/*
* Now update the catalog, while we have the door open.
@@ -6691,8 +6692,16 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
while (HeapTupleIsValid(tgtuple = systable_getnext(tgscan)))
{
+ Form_pg_trigger copy_tg;
+
copyTuple = heap_copytuple(tgtuple);
copy_tg = (Form_pg_trigger) GETSTRUCT(copyTuple);
+
+ /* Remember OIDs of other relation(s) involved in FK constraint */
+ if (copy_tg->tgrelid != RelationGetRelid(rel))
+ otherrelids = list_append_unique_oid(otherrelids,
+ copy_tg->tgrelid);
+
copy_tg->tgdeferrable = cmdcon->deferrable;
copy_tg->tginitdeferred = cmdcon->initdeferred;
simple_heap_update(tgrel, &copyTuple->t_self, copyTuple);
@@ -6709,9 +6718,16 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
heap_close(tgrel, RowExclusiveLock);
/*
- * Invalidate relcache so that others see the new attributes.
+ * Invalidate relcache so that others see the new attributes. We must
+ * inval both the named rel and any others having relevant triggers.
+ * (At present there should always be exactly one other rel, but
+ * there's no need to hard-wire such an assumption here.)
*/
CacheInvalidateRelcache(rel);
+ foreach(lc, otherrelids)
+ {
+ CacheInvalidateRelcacheByRelid(lfirst_oid(lc));
+ }
ObjectAddressSet(address, ConstraintRelationId,
HeapTupleGetOid(contuple));