From: | David Rowley <dgrowleyml(at)gmail(dot)com> |
---|---|
To: | jian he <jian(dot)universality(at)gmail(dot)com>, amul sul <sulamul(at)gmail(dot)com>, Peter Eisentraut <peter(at)eisentraut(dot)org> |
Cc: | PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: bug, ALTER TABLE call ATPostAlterTypeCleanup twice for the same relation |
Date: | 2025-09-28 21:36:37 |
Message-ID: | CAApHDvp7NidshSiw0kqQMgtRupYw7=A5aCM0ubhxC7D0MzvTVg@mail.gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Sat, 27 Sept 2025 at 21:54, jian he <jian(dot)universality(at)gmail(dot)com> wrote:
> if (pass == AT_PASS_ALTER_TYPE || pass == AT_PASS_SET_EXPRESSION)
> - ATPostAlterTypeCleanup(wqueue, tab, lockmode);
> + {
> + if (!list_member_oid(relids, tab->relid))
> + {
> + ATPostAlterTypeCleanup(wqueue, tab, lockmode);
> + relids = lappend_oid(relids, tab->relid);
> + }
> + }
I've not studied this long enough to know what the correct fix should
be, but I have studied it long enough to know what you're proposing
isn't it.
You can't just forego the subsequent call to ATPostAlterTypeCleanup()
because you've done it during the AT_PASS_ALTER_TYPE pass as that
doesn't account for the fact that there might be more work to do (i.e
more constraints added since AT_PASS_ALTER_TYPE) in the
AT_PASS_SET_EXPRESSION pass.
With your patch applied, if I adapt your example case to alter the
type of an unrelated column so that the constraint related to that
column is adjusted first and the constraint related to the expression
column is only added to the changedConstraintOids list after the first
call to ATPostAlterTypeCleanup(), you'll see that "cc" isn't recreated
because your code thinks nothing further needs to be done:
drop table if exists gtest25;
CREATE TABLE gtest25 (a0 int, z int, a int, b int GENERATED ALWAYS AS
(a * 2 + a0) STORED);
alter table gtest25 add constraint check_z check (z > 0);
alter table gtest25 add constraint cc check (b > 0);
select oid, conname,conbin from pg_constraint where
conrelid='gtest25'::regclass;
alter table gtest25 alter column z set data type numeric, ALTER
COLUMN b SET EXPRESSION AS (z + 0);
select oid, conname,conbin from pg_constraint where
conrelid='gtest25'::regclass;
and that's certainly wrong as if I separate the ALTER TABLE into two
separate commands, then "cc" does get recreated.
I do wonder what the exact reason was that AT_PASS_ALTER_TYPE and
AT_PASS_SET_EXPRESSION are separate passes. I'd have expected that's
maybe so that it's possible to alter the type of a column used within
a generated column, but looking at the following error message makes
me think I might not be correct in that thinking:
create table test1 (a int, b int generated always as (a + 1) stored);
alter table test1 alter column a set data type bigint;
ERROR: cannot alter type of a column used by a generated column
DETAIL: Column "a" is used by generated column "b".
There's probably some good explanation for the separate pass, but I'm
not sure of it for now. I'm including in the author and committer of
the patch which added this code to see if we can figure this out.
David
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Smith | 2025-09-28 23:39:12 | Re: [WIP]Vertical Clustered Index (columnar store extension) - take2 |
Previous Message | Tristan Partin | 2025-09-28 21:16:52 | Re: Decouple C++ support in Meson's PGXS from LLVM enablement |