Hi, I added this to the open commitfest at https://commitfest.postgresql.org/patch/7169/
Also, please find attached v2, which addresses additional required test changes. Regards, Nikhil On Mon, Aug 17, 2026 at 12:33 PM Nikhil Sontakke <[email protected]> wrote: > Hi, > > A composite datum records the OID and typmod of its row type and nothing > about the shape it was built with, so every value is read back against > whatever the type looks like currently at read time. Nothing prevents > the below for example: > > CREATE TYPE ct AS (a int, b int); > CREATE TABLE t (v ct); > CREATE UNIQUE INDEX t_v ON t (v); > INSERT INTO t VALUES (ROW(1, 2)::ct), (ROW(1, 3)::ct); -- accepted > > ALTER TYPE ct DROP ATTRIBUTE b; -- accepted today! this violates UNIQUE > > SELECT count(DISTINCT v) FROM t; > 1 > > The rows are on disk and were committed before the ALTER; no cursor or > plan is involved, and the incorrect reading survives a restart. > > INSERT INTO t VALUES (ROW(1)::ct); > ERROR: duplicate key value violates unique constraint "t_v" > DETAIL: Key (v)=((1)) already exists. > > REINDEX INDEX t_v; > ERROR: could not create unique index "t_v" > DETAIL: Key (v)=((1)) is duplicated. > > Worse, a plain pg_dump of that database fails to restore for the > same reason. > > The check for this exists. On the same table, before the drop, retyping > the attribute is refused: > > ALTER TYPE ct ALTER ATTRIBUTE b TYPE bigint; > ERROR: cannot alter type "ct" because column "t.v" uses it > > but the call is gated on a rewrite being queued, > > if (tab->newvals != NIL || tab->rewrite > 0) > find_composite_type_dependencies(...); > > and a drop produces neither, so it walks past. > > The same applies to ALTER TABLE ... DROP COLUMN, since a table's row type > is a composite type too, and there too the retyping form is already > refused. > > The attached patch calls the existing function from the drop path, after > the column is checked for droppability and before recursion to > inheritance children, so both calls and every level are covered. > Regression, isolation and pg_upgrade suites pass. > > I added new tests and had to modify a couple of existing tests because of > this > behavior change. > > Regards, > Nikhil > --- > Nikhil Sontakke > PlanetScale Postgres Core Team >
v2-0001-Refuse-to-drop-a-column-whose-row-type-is-stored-.patch
Description: Binary data
