I have the following test case:
DROP SCHEMA IF EXISTS test CASCADE;
CREATE SCHEMA test;
CREATE TABLE test.quz (
foo int,
bar int,
PRIMARY KEY ( foo, bar )
);
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL
);
INSERT INTO test.quz VALUES ( 1, 2 );
INSERT INTO test.quuz VALUES ( 1, 2, 3 );
However, even when deferred this doesn’t seem to work.
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
END;
Is there any reason? Can this task be done without the terseness of manually deleteing and re-inserting rows?
DEFERRABLEmeans that constraints are checked at the end of each statement.DEFERRABLE INITIALLY DEFERRED, means that constraints are checked at the end of the transaction.This should work in your case:
This will probably work too:
Unless I am mistaking, the issue in your definitions is that you don’t mark your constraints as deferrable. So Postgres treats them as
NOT DEFERRABLE INITIALLY IMMEDIATE(i.e. the default in Postgres in spite of the SQL standard, the rational being that it is fastest) irrespective ofSET CONSTRAINTS(which only affects deferrable constraints).