| 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 |
| 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 |