| From: | jian he <jian(dot)universality(at)gmail(dot)com> |
|---|---|
| To: | Alberto Piai <alberto(dot)piai(at)gmail(dot)com> |
| Cc: | PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: ALTER COLUMN SET EXPRESSION on partitions not work in case of constraint dependencies |
| Date: | 2026-08-26 04:47:57 |
| Message-ID: | CACJufxERxHfdx0QXJDxVvHnw+wfE+EVhFgBHK_ON490-9MVQWA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Tue, Aug 25, 2026 at 2:57 AM Alberto Piai <alberto(dot)piai(at)gmail(dot)com> wrote:
>
> What do you think?
>
> As a user, I would find it very surprising if ALTER TABLE ONLY ... SET
> EXPRESSION failed sometimes, depending on how dependencies are set up.
> It would be great if we'd manage to get this working.
>
The previous patch v3 is incorrect.
ATExecCmd->ATExecSetExpression.
In ATRewriteCatalogs, we have
```
foreach(lcmd, subcmds)
ATExecCmd(wqueue, tab,
lfirst_node(AlterTableCmd, lcmd),
lockmode, pass, context);
/*
* After the ALTER TYPE or SET EXPRESSION pass, do cleanup work
* (this is not done in ATExecAlterColumnType since it should be
* done only once if multiple columns of a table are altered).
*/
if (pass == AT_PASS_ALTER_TYPE || pass == AT_PASS_SET_EXPRESSION)
ATPostAlterTypeCleanup(wqueue, tab, lockmode);
`````
Consider ALTER TABLE on a partitioned table with SET EXPRESSION.
It will drop and recreate the dependent objects (such as indexes and
constraints) of the partitioned table first, and then process each partition.
If we call RememberAllDependentForRebuilding and
RememberWholeRowDependentForRebuilding only in Phase 1 (ATPrepCmd) for
each partition,
the dependent objects of the partitions may already have been dropped
as part of the cascading drop of the corresponding dependent objects
on the partitioned table in ATPostAlterTypeCleanup.
As a result, by the time we reach ATPostAlterTypeCleanup for the partition,
AlteredTableInfo->changedConstraintOids and AlteredTableInfo->changedIndexOids
may refer to dropped objects.
Therefore, RememberAllDependentForRebuilding and
RememberWholeRowDependentForRebuilding need to remain within
ATExecSetExpression.
But we want ALTER TABLE partitionX SET EXPRESSION to succeed when partitionX
itself does not have any index dependencies or other dependencies.
(partitionX is a partition, not a partitioned table).
So, during Phase 1 (ATPrepCmd), call RememberAllDependentForRebuilding
and RememberWholeRowDependentForRebuilding to detect unsupported dependencies
and report error if necessary. After the check, reset the corresponding lists
to NIL so that the dependencies are not actually queued for rebuilding.
In v4-0001-Fix-dependency-issue-when-directly-ALTER-TABLE-SET-EXPRESSION-o.nocfbot
We transform tab->changedConstraintOids to tab->constraints and delete
unncessary
tab->changedConstraintOids logic inside ATPostAlterTypeCleanup, seems
more intuitive IMHO.
In v4-0001-Disallow-directly-ALTER-TABLE-SET-EXPRESSION-on-child-table-if-de.patch
Disallow directly applying ALTER TABLE SET EXPRESSION on a child
table if dependencies exist;
Disallow ALTER TABLE ONLY SET EXPRESSION on a table if dependencies exist;
| Attachment | Content-Type | Size |
|---|---|---|
| v4-0001-Fix-dependency-issue-when-directly-ALTER-TABLE-SET-EXPRESSION-o.nocfbot | application/octet-stream | 28.5 KB |
| v4-0001-Disallow-directly-ALTER-TABLE-SET-EXPRESSION-on-child-table-if-de.patch | text/x-patch | 17.6 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Amit Kapila | 2026-08-26 04:53:18 | Re: Assertion failure in GetSubscriptionRelations() with concurrent DROP TABLE |
| Previous Message | vignesh C | 2026-08-26 04:18:33 | Re: Assertion failure in GetSubscriptionRelations() with concurrent DROP TABLE |