Unexpected reindex when altering column types for partitioned tables

From: Álvaro Rodríguez <alvaro(at)datadoghq(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Unexpected reindex when altering column types for partitioned tables
Date: 2026-06-08 13:50:40
Message-ID: CA+C_kKUS0QtMT1sHW067z=CAEDLOysAy6PiwvTx9QPBifHmR5w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

When running the ALTER TABLE ALTER COLUMN TYPE operation, certain type
changes are supposed to not require a reindex. For example, text to
varchar or varchar(n) to varchar(m) when m > n. However, this turns
out to not be the case for indexes (including pk / unique constraints)
on partitioned tables. Patch 0001 (attached) demonstrates this
behavior with a new regression test. In this case, the table rewrite
is avoided but the indexes are rebuilt.

During an alter column type for a partitioned table with an index, the
current deletion behavior:
1. Processes the parent table in ATRewriteCatalogs before
processing any of its child tables. This runs ATPostAlterTypeCleanup
for the table, which drops the partitioned index at the end. That drop
cascades to the child indexes.
2. Processes the child tables in ATRewriteCatalogs. However, the
child indexes were already dropped, so we never remember them in
RememberAllDependentForRebuilding.
3. When indexes are eventually recreated, they always need to be reindexed.

Patch 0002 batches the deletions in ATRewriteCatalogs so that they
happen at the end of a processing step and not in each call to
ATPostAlterTypeCleanup (which is called for each processed table).
This ensures that child indexes are tracked when ATExecAlterColumnType
calls RememberAllDependentForRebuilding for each child table.

After the change, child indexes are now recreated twice: once when the
parent index is created, and once by themselves. We need for the child
indexes to be created first. That way, they use the remembered
information to decide whether a reindex is needed. When the parent
index is created, it will automatically use existing child indexes. To
enforce this behavior, we add a new AT_PASS_OLD_PARTITIONED_INDEX that
recreates the parent indexes.

Finally, patch 0003 does very similar changes to index-backed
constraints. We make sure that the child constraints are properly
remembered. We also make sure that when the indexes for the child
constraints are rebuilt, the do so in the new
AT_PASS_OLD_PARTITIONED_INDEX step.

Thoughts?

Regards,
Álvaro Rodríguez

Attachment Content-Type Size
v1-0001-Add-regression-test-to-highlight-unexpected-behav.patch application/octet-stream 4.2 KB
v1-0002-Skip-index-rewriting-when-possible-on-ALTER-TABLE.patch application/octet-stream 10.1 KB
v1-0003-Skip-index-rewriting-for-PK-associated-indexes-wh.patch application/octet-stream 5.8 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Bruce Momjian 2026-06-08 14:13:33 Re: First draft of PG 19 release notes
Previous Message Andrei Lepikhov 2026-06-08 13:32:14 Re: Subquery pull-up increases jointree search space