pg_dump: assert failure sorting casts/transforms

From: Alexander Kukushkin <cyberdemn(at)gmail(dot)com>
To: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: pg_dump: assert failure sorting casts/transforms
Date: 2026-08-20 10:20:00
Message-ID: CAFh8B=nb2KLugfF5pFgOLY2Q0db8KOqp=46kxvWNzgvTQeP8oQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

pg_dump's DOTypeNameCompare() can reach its Assert(false) fall-through
(pg_dump_sort.c) when a database contains two casts, or two transforms,
whose types share a typname across different schemas. On an
assertion-enabled build this aborts the dump:
pg_dump: pg_dump_sort.c:479: DOTypeNameCompare: Assertion `0' failed.

I hit this in the field with an extension that defines its own json type
alongside pg_catalog.json and casts to both, but it reproduces trivially
without any extension:
CREATE SCHEMA s;
CREATE TYPE public.tgt AS ENUM ('a');
CREATE TYPE s.tgt AS ENUM ('a');
CREATE TYPE public.src AS ENUM ('a');
CREATE CAST (public.src AS public.tgt) WITH INOUT;
CREATE CAST (public.src AS s.tgt) WITH INOUT;

$ pg_dump --schema-only ... # aborts on an --enable-cassert build

The cause: casts and transforms have no namespace of their own, and
getCasts() / getTransforms() build their sort name from the unqualified
type (and language) names. Two casts therefore tie on the full sort key
whenever their source/target type names match but the types live in
different schemas ("sourcetype tgt" in the example); transforms tie the same
way as "typname langname". Since DOTypeNameCompare() has no DO_CAST or
DO_TRANSFORM tiebreaker, such pairs fall through to the assert on master and
RL_19_STABLE branches.

The attached patch adds the missing tiebreakers, comparing the referenced
types by their full natural key via the existing pgTypeNameCompare()
(nspname, then typname) — the same helper already used for function
arguments and operator operands. For transforms, comparing trftype alone
is sufficient, since a name tie already implies the same unqualified typname
and language name. It also adds regression coverage to 002_pg_dump.pl (two
casts and two transforms sharing a typname across schemas), which aborts an
unpatched assert-enabled run and passes with the fix.

Regards,
--
Alexander Kukushkin

Attachment Content-Type Size
0001-pg_dump-sort-casts-and-transforms-independent-of-OID.patch text/x-patch 5.5 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andrey Borodin 2026-08-20 10:49:49 Re: SSI: ON CONFLICT DO SELECT takes no predicate lock on the returned row
Previous Message Andrey Borodin 2026-08-20 09:37:18 Re: GiST multirange index scans can fail to return rows