Skip to content
Advertisement

SET CONSTRAINTS ALL DEFERRED not working as expected

In a PostgreSQL 9.3 database, if I define tables a and b as follows:

And then do the following:

It produces the error below. Why is SET CONSTRAINTS not having the desired effect?

Advertisement

Answer

Only DEFERRABLE constraints can be deferred.

Let me suggest superior alternatives first:

1. INSERT in order

Reverse the sequence of the INSERT statements and nothing needs to be deferred. Simplest and fastest – if at all possible.

2. Single command

Do it in a single command. Then still nothing needs to be deferred, as non-deferrable constraints are checked after each command and CTEs are considered to be part of single command:

While being at it, you can reuse the values for the first INSERT: safer / more convenient for certain cases or multi-row inserts:

But I need deferred constraints! (Really?)

Then your original code works (a bit slower, as deferred constraints add cost).

db<>fiddle here

Related:


My original answer quoted the manual:

Referential actions other than the NO ACTION check cannot be deferred, even if the constraint is declared deferrable.

But that was misleading as it only applies to “referential actions”, i.e. what happens ON UPDATE or ON DELETE to rows in the referenced table. The case at hand is not one of those – as @zer0hedge pointed out.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement