| From: | Paul A Jungwirth <pj(at)illuminatedcomputing(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Andres Freund <andres(at)anarazel(dot)de>, Peter Eisentraut <peter(at)eisentraut(dot)org> |
| Subject: | WITHOUT OVERLAPS foreign key allows referencing EXCLUDE constraint |
| Date: | 2026-09-30 21:41:21 |
| Message-ID: | CA+renyUy=+oZoOg0qN_wAHTL3MwVEnp4zdfX+Bu54foz6OXpQw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Hackers,
Andres reported that temporal foreign keys allow serialization
anomalies because their FOR KEY SHARE doesn't conflict with the
referenced key.[0] Actually if the reference is a WITHOUT OVERLAPS
primary key or uniqueness constraint, then the lock does conflict, and
there is no serialization anomaly. But we are erroneously allowing a
temporal foreign key to reference a plain EXCLUDE constraint, and in
that case there is no lock conflict.
The real bug here is permitting that reference in the first place. An
EXCLUDE constraint doesn't guarantee uniqueness (because of empty
ranges but also it could have any operator the user chooses). The
cause was checking indisexclusion but not indisunique. A WITHOUT
OVERLAPS constraint's index will have both. So this patch updates the
rules to forbid referencing an EXCLUDE constraint.
That fix is easy, but dealing with existing bad FKs from v18 is
trickier. They will cause failures when using pg_restore or
pg_upgrade. I think it is unlikely that anyone actually created
temporal foreign keys this way, but I included a new check in
pg_upgrade to detect them, just in case. I also log a warning when we
find such a foreign key. The release notes could include this SQL to
detect them, with a suggestion to replace them with references to real
WITHOUT OVERLAPS constraints:
SELECT c.conrelid::regclass AS table_name, c.conname AS constraint_name
FROM pg_constraint c JOIN pg_index i ON i.indexrelid = c.conindid
WHERE c.contype = 'f' AND c.conperiod AND NOT i.indisunique;
The warning only needs to be in v18, so I've broken it out into a
separate commit.
The first patch here applies cleanly against master, but has a
(routine) merge conflict in pg_upgrade/check.c to against
REL_{18,19}_STABLE. For 18 that hunk can actually be dropped, since
there is no need to check for this when upgrading from 17 to 18.
Getting this fix into 19 before release would reduce the chance
someone creates this bug, and it means we only have to carry the code
to print warnings in the 18 branch. Should I add it to the 19 Open
Items list?
Yours,
--
Paul ~{:-)
pj(at)illuminatedcomputing(dot)com
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Fix-temporal-FKs-referencing-invalid-constraints.patch | text/x-patch | 12.3 KB |
| v1-0002-Warn-about-temporal-FKs-that-reference-exclusion-.patch | text/x-patch | 16.7 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | David Rowley | 2026-09-30 22:04:07 | Re: [PATCH] intXshr, intXshl: return error on shift count out of range |
| Previous Message | Zsolt Parragi | 2026-09-30 21:22:17 | Re: Allow table AMs to define their own reloptions |