DEFERRABLE
означает, что ограничения проверяются в конце каждого оператора.DEFERRABLE INITIALLY DEFERRED
, означает, что ограничения проверяются в конце транзакции.
Это должно работать в вашем случае:
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL DEFERRABLE INITIALLY DEFERRED
);
...
BEGIN;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
Это, вероятно, тоже будет работать:
CREATE TABLE test.quuz (
foo int,
bar int,
baz int,
PRIMARY KEY ( foo, bar ),
FOREIGN KEY ( foo, bar ) REFERENCES test.quz MATCH FULL DEFERRABLE
);
...
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
UPDATE test.quz SET bar = 100 where bar = 2;
UPDATE test.quuz SET bar = 100 where bar = 2;
COMMIT;
Если я не ошибаюсь, проблема в ваших определениях заключается в том, что вы не помечаете свои ограничения как отложенные.Таким образом, Postgres рассматривает их как NOT DEFERRABLE INITIALLY IMMEDIATE
(т. Е. По умолчанию в Postgres, несмотря на стандарт SQL, разумно, что он самый быстрый) независимо от SET CONSTRAINTS
(который влияет только на отложенные ограничения).