| From: | Arseny Kositsin <a(dot)kositsyn(at)postgrespro(dot)ru> |
|---|---|
| To: | Álvaro Herrera <alvherre(at)kurilemu(dot)de> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: pg_upgrade fails when FK constraint with same name exists on partitioned table and its partition |
| Date: | 2026-07-23 13:47:00 |
| Message-ID: | d2358b70-67c5-4590-a498-c2a1a0afb355@postgrespro.ru |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
> So why not just drop the constraint in the partition? Seems rather
> useless. If there's a valid reason to have a constraint that's
> different from the one in the parent table, then you can rename it.
>
> I guess we could add a check to "pg_upgrade --check" to report this kind
> of thing ... I'm not really convinced of this though. Anyhow, I don't
> feel inclined to try to have pg_upgrade/pg_dump handle this case cleanly.
Thanks for the reply, and sorry for the long delay in responding.
You're right that the constraint on the partition can simply be dropped
or renamed. However, since the failure occurs during pg_upgrade and
the error message is not very obvious, I think it would be helpful to
detect this situation with "pg_upgrade --check" beforehand, as you
suggested.
Attached is a patch that implements this check. It detects NOT VALID
foreign keys on partitions that share a name with a foreign key on the
parent partitioned table and were not linked to it (conparentid = 0).
Such constraints may cause a name conflict during restore: pg_dump emits
them as separate ALTER TABLE ADD CONSTRAINT statements for both the
parent and the partition, and when the parent's constraint is restored
first, it is inherited by the partition, so the subsequent attempt to
create the same-named constraint on the partition errors out with
"constraint ... for relation ... already exists".
Whether the failure actually occurs depends on the order in which
pg_dump emits the constraints, which is determined by alphabetical
sorting of table names; the check flags both cases.
Only NOT VALID foreign keys are affected. VALID foreign keys on
partitions are matched and linked (conparentid is set) by
tryAttachPartitionForeignKey() during ATTACH PARTITION, so pg_dump
does not emit them separately. This matching logic excluded NOT VALID
constraints until PG 18, where it was fixed by commit b663b9436e7.
The check therefore applies to old clusters from PG 11 (when conparentid
was introduced) through PG 17.
Other constraint types are not affected: CHECK constraints can have
duplicate names on partitions, but pg_dump emits them inline in
CREATE TABLE; PRIMARY KEY, UNIQUE, and EXCLUDE constraints create
indexes, so duplicate names are prevented by an index name conflict;
NOT NULL constraints as named entries in pg_constraint exist only since
PG 18.
The patch is for the master branch. I did not add a separate test
because I did not find dedicated tests for other similar check
functions, but I am ready to add one if needed.
Best regards,
Arseny Kositsyn.
| Attachment | Content-Type | Size |
|---|---|---|
| v1-pg_upgrade-check-for-duplicate-FK-names-on-partition.patch | text/x-patch | 6.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Aleksander Alekseev | 2026-07-23 13:50:03 | Re: [PATCH] Cover get_json_table_plan() with tests |
| Previous Message | Tom Lane | 2026-07-23 13:34:44 | Re: Fix missing FORMAT when deparsing JSON_ARRAY(query) |