| From: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> |
|---|---|
| To: | Nitin Motiani <nitinmotiani(at)google(dot)com> |
| Cc: | pgsql-hackers(at)postgresql(dot)org |
| Subject: | Re: [PATCH v1] Fix for Bug#19724 - ALTER TYPE ... ALTER ATTRIBUTE triggers internal error for base type of domain with check |
| Date: | 2026-09-28 14:31:15 |
| Message-ID: | CAJTYsWUwEebLYkSD_+2L6tOp8nL9-TyaLkOYcb1q6viAH=ejNw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Mon, 28 Sept 2026 at 18:59, Nitin Motiani <nitinmotiani(at)google(dot)com>
wrote:
> The following bug was reported in [1]
>
> ```
> CREATE TYPE rt AS (i int);
> CREATE DOMAIN dt AS int CHECK ((ROW(value)::rt).i > 0);
> ALTER TYPE rt ALTER ATTRIBUTE i TYPE bigint;
>
>
>
> triggers an internal
> ERROR: XX000: could not identify relation associated with constraint
16390
> LOCATION: ATPostAlterTypeCleanup, tablecmds.c:16147
>
> Reproduced starting from af20e2d72.
>
> ```
>
> I am not sure how common this scenario is but I investigated the
> history of the commit af20e2d72. LLM pointed me to [2] from 2017.
>
> The thread mentions a similar case in the email but it isn't covered
> in the test cases.
>
> ```
> regression=# create type comptype as (r float8, i float8);
> CREATE TYPE
> regression=# create domain silly as float8 check
> ((row(value,0)::comptype).r > 0);
> CREATE DOMAIN
> regression=# alter type comptype alter attribute r type varchar;
> ERROR: cache lookup failed for relation 0
> ```
>
> Therefore I am attaching a patch file with a proposed fix. The issue
> stems from the fact that for a domain constraint, we currently look
> for the domain's base type and the corresponding relid. But if the
> domain is over a primitive type like int, there is no relid. And
> therefore it fails.
>
> My understanding of code is that this relid is only being used in
> ATPostAlterTypeParse to unqueue the entry corresponding to the type
> being altered.
>
> So in this patch instead of getting the relid from the domain, we use
> the relid of the type being altered.
>
> I tested changing int to bigint and text to ensure it passes in the
> first case and fails in the second.
>
> Please take a look and let me know what you think.
Thanks for working on this. Switching to tab->relid looks right to me,
since a domain constraint doesn't belong to any relation anyway.
I think there's still a problem when a table that uses the domain gets
rewritten by the same ALTER, though. The re-added constraint is
validated right away in phase 2, before phase 3 has rewritten those
tables, so their old rows are read with the new tuple descriptor. With
the patch this crashes for me:
create table dtab (i int);
create domain dtext as text check ((row(1)::dtab).i > 0 and md5(value) <>
'');
create table dtab_child (t dtext) inherits (dtab);
insert into dtab_child values (1, repeat('x', 200));
alter table dtab alter column i type bigint;
On master it just fails with the elog. (FWIW master, and 14 too as far
as I checked, can already crash like this with a domain over the
parent's rowtype stored in the child, so it's not entirely new.)
Maybe the constraint could be re-added as NOT VALID in phase 2, and then
validated once phase 3 is done, e.g. with AlterDomainValidateConstraint()
next to the FK checks at the end of ATRewriteTables()?
Also, I believe the test cases can be trimmed.
For the tests, all three cases take the same path and none of them
stores the domain in a table. One test for the reported case plus one
like the above might be enough.
Regards,
Ayush
[1]
https://www.postgresql.org/message-id/flat/19724-58468097b5b17d10%40postgresql.org
[2]
https://www.postgresql.org/message-id/flat/30656.1509128130%40sss.pgh.pa.us
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Ilia Evdokimov | 2026-09-28 15:06:29 | Re: Fold NOT IN / <> ALL expressions containing NULL to FALSE |
| Previous Message | Shashishekar Hullahally Anantharamu | 2026-09-28 14:05:38 | Re: [PATCH] Add memory/disk usage for Function Scan nodes in EXPLAIN |