| From: | lin teletele <teletele(dot)lin(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | jian he <jian(dot)universality(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
| Subject: | [PATCH] Fix pg_dump --clean with inherited partition constraints |
| Date: | 2026-10-10 02:20:04 |
| Message-ID: | CAP--GgNDzPmC8w-c69=Ptnno8veM0_zqYC4QQ_zXfd5d1c=k0g@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
I found that pg_restore --clean still reports errors when restoring a
partitioned table with a PRIMARY KEY or UNIQUE constraint.
This appears to be the constraint-backed counterpart of the partitioned
index issue fixed by commit 1fc3403626d4:
Fix pg_dump --clean with partitioned indexes.
That commit suppresses the DROP statement in dumpIndex() when the index
is attached to a parent partitioned index. However, constraint-backed
indexes are handled through dumpConstraint(), which still generates DROP
CONSTRAINT unconditionally.
Here is a minimal reproducer:
createdb clean_src
psql -X -v ON_ERROR_STOP=1 clean_src <<'SQL'
CREATE TABLE p
(
id integer NOT NULL,
k integer NOT NULL,
payload text,
PRIMARY KEY (id, k)
) PARTITION BY LIST (k);
CREATE TABLE p1 PARTITION OF p FOR VALUES IN (1);
CREATE TABLE p2 PARTITION OF p FOR VALUES IN (2);
INSERT INTO p VALUES
(1, 1, 'one'),
(2, 2, 'two');
SQL
pg_dump -Fc -f partition.dump clean_src
createdb clean_dst
pg_restore -d clean_dst partition.dump
pg_restore --clean --if-exists --exit-on-error \
-d clean_dst partition.dump
The second restore fails with:
ERROR: cannot drop inherited constraint "p2_pkey" of relation "p2"
The failing command is:
ALTER TABLE IF EXISTS ONLY public.p2
DROP CONSTRAINT IF EXISTS p2_pkey;
Without --exit-on-error, the restore normally continues and rebuilds the
objects, but reports errors and exits nonzero. With --single-transaction
or --transaction-size, both of which imply --exit-on-error, the restore
is aborted.
The proposed fix applies the existing dumpIndex() rule to the
index-related constraint path in dumpConstraint():
if (indxinfo->parentidx == 0)
{
appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
fmtQualifiedDumpable(tbinfo));
appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
fmtId(coninfo->dobj.name));
}
An inherited partition constraint cannot be dropped independently. It
will disappear when the parent constraint or the partition's table is
dropped, so its separate DROP command is unnecessary.
Checking parentidx, rather than tbinfo->ispartition, preserves DROP
statements for local constraints on partitions whose backing indexes are
not attached to a parent index. Constraint creation and index attachment
remain unchanged.
Earlier discussions of these cleanup failures include:
https://postgr.es/m/3170626.1594842723@sss.pgh.pa.us
https://postgr.es/m/1228964.1610480929@sss.pgh.pa.us
https://postgr.es/m/16928-54e2ea7edca104c1@postgresql.org
The discussion leading to the partitioned index fix is here:
https://postgr.es/m/CACJufxF0QSdkjFKF4di-JGWN6CSdQYEAhGPmQJJCdkSZtd=oLg@mail.gmail.com
While testing this change, I also found a related failure involving a
local constraint whose backing index is attached to a partitioned index
without a corresponding parent constraint. In that case, dropping the
parent index fails because of the child constraint's dependency. This
failure also occurs without the proposed patch.
I plan to report that case in a separate thread, where we can discuss
its cleanup behavior and a follow-up fix.
Comments welcome.
--
Best Regards,
Teletele
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Fix-pg_dump-clean-with-inherited-partition-constr.patch | application/octet-stream | 7.3 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Tender Wang | 2026-10-10 02:37:44 | Re: "failed to build any N-way joins" from a five-relation query |
| Previous Message | Chao Li | 2026-10-10 02:06:02 | Re: Reset unlogged relations before syncing the data directory? |