From 068900d2c41aa7383363b304636c1f11cd9c1f8b Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Mon, 29 Sep 2025 17:11:25 +0800 Subject: [PATCH v4 2/2] The other implementation. Author: Chao Li --- src/backend/commands/tablecmds.c | 47 ++++++++++++-------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4443b69c156..3791666834c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5296,20 +5296,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, AlterTableUtilityContext *context) { ListCell *ltab; - List *relids = NIL; - - /* - * Collect relation that both type and generation expression are changed. - */ - foreach(ltab, *wqueue) - { - AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab); - List *subcmds1 = tab->subcmds[AT_PASS_SET_EXPRESSION]; - List *subcmds2 = tab->subcmds[AT_PASS_ALTER_TYPE]; - - if (subcmds1 != NIL && subcmds2 != NIL) - relids = lappend_oid(relids, tab->relid); - } + AlteredTableInfo **tabsForAltTypeCleanup = palloc0(sizeof(AlteredTableInfo *) * list_length(*wqueue)); /* * We process all the tables "in parallel", one pass at a time. This is @@ -5320,6 +5307,8 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, */ for (AlterTablePass pass = 0; pass < AT_NUM_PASSES; pass++) { + int tabIdx = -1; + /* Go through each table that needs to be processed */ foreach(ltab, *wqueue) { @@ -5327,6 +5316,17 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, List *subcmds = tab->subcmds[pass]; ListCell *lcmd; + /* + * Cleanup work for ALTER TYPE or SET EXPRESSION. We must perform + * this cleanup after both ALTER TYPE and SET EXPRESSION are done. + */ + tabIdx += 1; + if (pass == AT_PASS_SET_EXPRESSION+1 && tabsForAltTypeCleanup[tabIdx] != NULL) + { + ATPostAlterTypeCleanup(wqueue, tabsForAltTypeCleanup[tabIdx], lockmode); + tabsForAltTypeCleanup[tabIdx] = NULL; + } + if (subcmds == NIL) continue; @@ -5342,22 +5342,8 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, 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 (list_member_oid(relids, tab->relid)) - { - /* - * If both type and generation expression being changed, do the - * cleanup at AT_PASS_SET_EXPRESSION - */ - if (pass == AT_PASS_SET_EXPRESSION) - ATPostAlterTypeCleanup(wqueue, tab, lockmode); - } - else if (pass == AT_PASS_ALTER_TYPE || pass == AT_PASS_SET_EXPRESSION) - ATPostAlterTypeCleanup(wqueue, tab, lockmode); + if (pass == AT_PASS_ALTER_TYPE || pass == AT_PASS_SET_EXPRESSION) + tabsForAltTypeCleanup[tabIdx] = tab; if (tab->rel) { @@ -5366,6 +5352,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, } } } + pfree(tabsForAltTypeCleanup); /* Check to see if a toast table must be added. */ foreach(ltab, *wqueue) -- 2.39.5 (Apple Git-154)