Re: Unexpected reindex when altering column types for partitioned tables

From: "Alberto Piai" <alberto(dot)piai(at)gmail(dot)com>
To: Álvaro Rodríguez <alvaro(at)datadoghq(dot)com>, <pgsql-hackers(at)postgresql(dot)org>
Cc: "Alvaro Herrera" <alvherre(at)kurilemu(dot)de>
Subject: Re: Unexpected reindex when altering column types for partitioned tables
Date: 2026-09-14 18:36:38
Message-ID: DLF99C6LBHYW.2P0416MELSPD9@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Álvaro,

I started reviewing/testing v2-0002. I think the approach is promising
(more on that later), but I found a problem when testing with multiple
levels of partitions:

create table p (a int, b int generated always as (1) stored)
partition by range (a);
create table m partition of p for values from (1) to (10)
partition by range (a);
create table l partition of m for values from (1) to (5);
create index on p(b);
alter table p alter column b set expression as (2);
ERROR: relation "m_b_idx" already exists

AFICS the problem is that recreating partition indexes in a separate
(later) pass is not enough: in this case both the index on p and the
index on m are partitioned indexes. They will both be enqueued at
AT_PASS_OLD_PARTITIONED_INDEX (each on the AlteredTableInfo
corresponding to its table), but then the tables themselves will be
processed in the wrong order within the AT_PASS_OLD_PARTITIONED_INDEX
pass. The command queue for p will be processed first, which will cause
the index on p(b) to be recreated, which will cause its descendant index
on m(b) to be recreated too. Then m will be processed, and will try to
recreate the same index again.

Maybe a good solution here would be to try and process the tables in the
opposite order when recreating object than the order in which we deleted
them? In which case we (possibly) wouldn't even need a new separate
pass. But I didn't look further into this. What do you think?

Besides this specific problem: there are currently multiple active
threads related to bugs with recursive alter table. I would suggest
specifically to read through [0], all of it because v19 is very
different than v1. The patch coming out of that thread partially
overlaps with this one. It tries to fix properties being lost in
recursive alter table operations that cause index rebuilds, both
properties which could be recreated with alter table commands and
properties which couldn't.

Your patch has potential to fix all properties being lost, which could
be recreated by alter table commands. I have verified for example that
the following is currently broken on master (reported in the other
thread), and your patch (v2) fixes it:

create table p (
a int not null,
b int not null generated always as (1) stored
) partition by range (a);
create table l partition of p for values from (1) to (5);
create unique index on p(a, b);
alter table p replica identity using index p_a_b_idx;
alter table l replica identity using index l_a_b_idx;
comment on index p_a_b_idx is 'comment on p_a_b_idx';
comment on index l_a_b_idx is 'comment on l_a_b_idx';
alter table p alter column b set expression as (2);
-- on master, l_a_b_idx has lost both the comment and the replica
-- identity marker, but not with patch v2 in this thread

I think it's worth exploring your approach too, and possibly joining
efforts with the other thread. The patch in the other thread has very
thorough tests. If your approach worked it could be simplified to do
less work saving all these properties on IndexStmt and restoring them
afterwards, because they would be recreated by enqueuing subcommands.

Kind regards,

Alberto Piai

[0] https://www.postgresql.org/message-id/flat/DB533C25-C6BA-4C0F-8046-96168E9CDD72%40gmail.com

--
Alberto Piai
Sensational AG
Zürich, Switzerland

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Andrey Borodin 2026-09-14 18:44:27 Re: Recovery does not honor io_combine_limit, causing IOPS saturation
Previous Message Alexandre Felipe 2026-09-14 18:34:33 Re: Restructured Shared Buffer Hash Table