aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index a7722052faa..fafd85db348 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8207,6 +8207,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
SysScanDesc scan;
HeapTuple depTup;
ObjectAddress address;
+ ListCell *lc;
+ ListCell *prev;
+ ListCell *next;
attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
@@ -8320,14 +8323,20 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
if (relKind == RELKIND_INDEX)
{
+ /*
+ * Indexes that are directly dependent on the table
+ * might be regular indexes or constraint indexes.
+ * Constraint indexes typically have only indirect
+ * dependencies; but there are exceptions, notably
+ * partial exclusion constraints. Hence we must check
+ * whether the index depends on any constraint that's
+ * due to be rebuilt, which we'll do below after we've
+ * found all such constraints.
+ */
Assert(foundObject.objectSubId == 0);
- if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
- {
- tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
- foundObject.objectId);
- tab->changedIndexDefs = lappend(tab->changedIndexDefs,
- pg_get_indexdef_string(foundObject.objectId));
- }
+ tab->changedIndexOids =
+ list_append_unique_oid(tab->changedIndexOids,
+ foundObject.objectId);
}
else if (relKind == RELKIND_SEQUENCE)
{
@@ -8482,6 +8491,41 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
systable_endscan(scan);
/*
+ * Check the collected index OIDs to see which ones belong to the
+ * constraint(s) of the table, and drop those from the list of indexes
+ * that we need to process; rebuilding the constraints will handle them.
+ */
+ prev = NULL;
+ for (lc = list_head(tab->changedIndexOids); lc; lc = next)
+ {
+ Oid indexoid = lfirst_oid(lc);
+ Oid conoid;
+
+ next = lnext(lc);
+
+ conoid = get_index_constraint(indexoid);
+ if (OidIsValid(conoid) &&
+ list_member_oid(tab->changedConstraintOids, conoid))
+ tab->changedIndexOids = list_delete_cell(tab->changedIndexOids,
+ lc, prev);
+ else
+ prev = lc;
+ }
+
+ /*
+ * Now collect the definitions of the indexes that must be rebuilt. (We
+ * could merge this into the previous loop, but it'd be more complicated
+ * for little gain.)
+ */
+ foreach(lc, tab->changedIndexOids)
+ {
+ Oid indexoid = lfirst_oid(lc);
+
+ tab->changedIndexDefs = lappend(tab->changedIndexDefs,
+ pg_get_indexdef_string(indexoid));
+ }
+
+ /*
* Now scan for dependencies of this column on other things. The only
* thing we should find is the dependency on the column datatype, which we
* want to remove, and possibly a collation dependency.