Somente
DEFERRABLE
restrições podem ser adiadas. Deixe-me sugerir alternativas superiores primeiro:
1. INSERT
em ordem
Inverta a sequência do
INSERT
declarações e nada precisa ser adiado. Mais simples e rápido - se possível. 2. Comando único
Faça isso em um comando único . Então ainda nada precisa ser adiado, pois as restrições não adiáveis são verificadas após cada comando e CTEs são considerados parte do comando único:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Enquanto estiver nisso, você pode reutilizar os valores para o primeiro
INSERT
; mais seguro / mais conveniente para certos casos ou pastilhas de várias linhas:WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Mas eu preciso de restrições adiadas! (Sério?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Em seguida, seu código original funciona (um pouco mais lento, pois as restrições adiadas aumentam o custo).
db<>fiddle aqui
Relacionado:
Minha resposta original citava o manual :
Mas isso foi enganoso, pois se aplica apenas a "ações referenciais", ou seja, o que acontece
ON UPDATE
ou ON DELETE
para linhas na tabela referenciada. O caso em questão não é um desses - como @zer0hedge apontado
.