diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 5dcedc337a..ca514919d1 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -872,7 +872,7 @@ DefineIndex(Oid relationId, CreateComments(indexRelationId, RelationRelationId, 0, stmt->idxcomment); - if (partitioned) + if (partitioned && !is_alter_table) { /* * Unless caller specified to skip this step (via ONLY), process each diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 93f13a4778..fb10d640e5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -426,7 +426,9 @@ static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode); static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, List *options, LOCKMODE lockmode); -static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, +static void ATPostAlterTypeCleanup1(List **wqueue, AlteredTableInfo *tab, + LOCKMODE lockmode); +static void ATPostAlterTypeCleanup2(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode); static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, List **wqueue, LOCKMODE lockmode, @@ -4068,6 +4070,10 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode) if (subcmds == NIL) continue; + /* Drop the old indexes and constraints before creating*/ + if (pass == AT_PASS_OLD_INDEX || pass == AT_PASS_OLD_CONSTR) + ATPostAlterTypeCleanup2(wqueue, tab, lockmode); + /* * Appropriate lock was obtained by phase 1, needn't get it again */ @@ -4084,7 +4090,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode) * multiple columns of a table are altered). */ if (pass == AT_PASS_ALTER_TYPE) - ATPostAlterTypeCleanup(wqueue, tab, lockmode); + ATPostAlterTypeCleanup1(wqueue, tab, lockmode); relation_close(rel, NoLock); } @@ -7233,6 +7239,9 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, if (constr->is_no_inherit) return address; + if (is_readd) + return address; + /* * Propagate to children as appropriate. Unlike most other ALTER * routines, we have to do this one level of recursion at a time; we can't @@ -10307,21 +10316,12 @@ ATExecAlterColumnGenericOptions(Relation rel, * and constraints that depend on the altered columns. */ static void -ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) +ATPostAlterTypeCleanup1(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) { - ObjectAddress obj; - ObjectAddresses *objects; ListCell *def_item; ListCell *oid_item; /* - * Collect all the constraints and indexes to drop so we can process them - * in a single call. That way we don't have to worry about dependencies - * among them. - */ - objects = new_object_addresses(); - - /* * Re-parse the index and constraint definitions, and attach them to the * appropriate work queue entries. We do this before dropping because in * the case of a FOREIGN KEY constraint, we might not yet have exclusive @@ -10363,16 +10363,13 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) conislocal = con->conislocal; ReleaseSysCache(tup); - ObjectAddressSet(obj, ConstraintRelationId, oldId); - add_exact_object_address(&obj, objects); - /* * If the constraint is inherited (only), we don't want to inject a * new definition here; it'll get recreated when ATAddCheckConstraint * recurses from adding the parent table's constraint. But we had to * carry the info this far so that we can drop the constraint below. */ - if (!conislocal) + if (!conislocal && contype == CONSTR_CHECK) continue; /* @@ -10398,6 +10395,46 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) ATPostAlterTypeParse(oldId, relid, InvalidOid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); + } +} + +/* + * Cleanup after we've finished all the ALTER TYPE operations for a + * particular relation. We have to drop and recreate all the indexes + * and constraints that depend on the altered columns. + */ +static void +ATPostAlterTypeCleanup2(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) +{ + ObjectAddress obj; + ObjectAddresses *objects; + ListCell *def_item; + ListCell *oid_item; + + /* + * Collect all the constraints and indexes to drop so we can process them + * in a single call. That way we don't have to worry about dependencies + * among them. + */ + objects = new_object_addresses(); + forboth(oid_item, tab->changedConstraintOids, + def_item, tab->changedConstraintDefs) + { + Oid oldId = lfirst_oid(oid_item); + + if (!SearchSysCacheExists1(CONSTROID, oldId)) + continue; + + ObjectAddressSet(obj, ConstraintRelationId, oldId); + add_exact_object_address(&obj, objects); + } + forboth(oid_item, tab->changedIndexOids, + def_item, tab->changedIndexDefs) + { + Oid oldId = lfirst_oid(oid_item); + + if (!SearchSysCacheExists1(RELOID, oldId)) + continue; ObjectAddressSet(obj, RelationRelationId, oldId); add_exact_object_address(&obj, objects); @@ -10411,6 +10448,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) free_object_addresses(objects); + CommandCounterIncrement(); /* * The objects will get recreated during subsequent passes over the work * queue.