[PATCH] Fix pg_dump --clean with inherited partition constraints

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

Responses

Browse pgsql-hackers by date

  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?