mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Check for pending trigger events on far end when dropping an FK constraint.
When dropping a foreign key constraint with ALTER TABLE DROP CONSTRAINT, we refuse the drop if there are any pending trigger events on the named table; this ensures that we won't remove the pg_trigger row that will be consulted by those events. But we should make the same check for the referenced relation, else we might remove a due-to-be-referenced pg_trigger row for that relation too, resulting in "could not find trigger NNN" or "relation NNN has no triggers" errors at commit. Per bug #14431 from Benjie Gillam. Back-patch to all supported branches. Report: <20161124114911.6530.31200@wrigleys.postgresql.org>
This commit is contained in:
parent
8afb811088
commit
4e026b32d4
@ -7722,6 +7722,24 @@ ATExecDropConstraint(Relation rel, const char *constrName,
|
||||
|
||||
is_no_inherit_constraint = con->connoinherit;
|
||||
|
||||
/*
|
||||
* If it's a foreign-key constraint, we'd better lock the referenced
|
||||
* table and check that that's not in use, just as we've already done
|
||||
* for the constrained table (else we might, eg, be dropping a trigger
|
||||
* that has unfired events). But we can/must skip that in the
|
||||
* self-referential case.
|
||||
*/
|
||||
if (con->contype == CONSTRAINT_FOREIGN &&
|
||||
con->confrelid != RelationGetRelid(rel))
|
||||
{
|
||||
Relation frel;
|
||||
|
||||
/* Must match lock taken by RemoveTriggerById: */
|
||||
frel = heap_open(con->confrelid, AccessExclusiveLock);
|
||||
CheckTableNotInUse(frel, "ALTER TABLE");
|
||||
heap_close(frel, NoLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the actual constraint deletion
|
||||
*/
|
||||
|
@ -1401,4 +1401,17 @@ rollback to x;
|
||||
commit; -- fail
|
||||
ERROR: insert or update on table "fktable2" violates foreign key constraint "fktable2_f1_fkey"
|
||||
DETAIL: Key (f1)=(2) is not present in table "pktable2".
|
||||
--
|
||||
-- Test that we prevent dropping FK constraint with pending trigger events
|
||||
--
|
||||
begin;
|
||||
insert into fktable2 values(2);
|
||||
alter table fktable2 drop constraint fktable2_f1_fkey;
|
||||
ERROR: cannot ALTER TABLE "fktable2" because it has pending trigger events
|
||||
commit;
|
||||
begin;
|
||||
delete from pktable2 where f1 = 1;
|
||||
alter table fktable2 drop constraint fktable2_f1_fkey;
|
||||
ERROR: cannot ALTER TABLE "pktable2" because it has pending trigger events
|
||||
commit;
|
||||
drop table pktable2, fktable2;
|
||||
|
@ -1041,4 +1041,17 @@ delete from fktable2;
|
||||
rollback to x;
|
||||
commit; -- fail
|
||||
|
||||
--
|
||||
-- Test that we prevent dropping FK constraint with pending trigger events
|
||||
--
|
||||
begin;
|
||||
insert into fktable2 values(2);
|
||||
alter table fktable2 drop constraint fktable2_f1_fkey;
|
||||
commit;
|
||||
|
||||
begin;
|
||||
delete from pktable2 where f1 = 1;
|
||||
alter table fktable2 drop constraint fktable2_f1_fkey;
|
||||
commit;
|
||||
|
||||
drop table pktable2, fktable2;
|
||||
|
Loading…
Reference in New Issue
Block a user