mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Propagate ALTER TABLE ... SET STORAGE to indexes
When creating a new index, the attstorage setting of the table column is copied to regular (non-expression) index columns. But a later ALTER TABLE ... SET STORAGE is not propagated to indexes, thus creating an inconsistent and undumpable state. Discussion: https://www.postgresql.org/message-id/flat/9765d72b-37c0-06f5-e349-2a580aafd989%402ndquadrant.com
This commit is contained in:
@ -7383,6 +7383,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
|
||||
Form_pg_attribute attrtuple;
|
||||
AttrNumber attnum;
|
||||
ObjectAddress address;
|
||||
ListCell *lc;
|
||||
|
||||
Assert(IsA(newValue, String));
|
||||
storagemode = strVal(newValue);
|
||||
@ -7442,6 +7443,52 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
|
||||
|
||||
heap_freetuple(tuple);
|
||||
|
||||
/*
|
||||
* Apply the change to indexes as well (only for simple index columns,
|
||||
* matching behavior of index.c ConstructTupleDescriptor()).
|
||||
*/
|
||||
foreach(lc, RelationGetIndexList(rel))
|
||||
{
|
||||
Oid indexoid = lfirst_oid(lc);
|
||||
Relation indrel;
|
||||
AttrNumber indattnum = 0;
|
||||
|
||||
indrel = index_open(indexoid, lockmode);
|
||||
|
||||
for (int i = 0; i < indrel->rd_index->indnatts; i++)
|
||||
{
|
||||
if (indrel->rd_index->indkey.values[i] == attnum)
|
||||
{
|
||||
indattnum = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (indattnum == 0)
|
||||
{
|
||||
index_close(indrel, lockmode);
|
||||
continue;
|
||||
}
|
||||
|
||||
tuple = SearchSysCacheCopyAttNum(RelationGetRelid(indrel), indattnum);
|
||||
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
|
||||
attrtuple->attstorage = newstorage;
|
||||
|
||||
CatalogTupleUpdate(attrelation, &tuple->t_self, tuple);
|
||||
|
||||
InvokeObjectPostAlterHook(RelationRelationId,
|
||||
RelationGetRelid(rel),
|
||||
attrtuple->attnum);
|
||||
|
||||
heap_freetuple(tuple);
|
||||
}
|
||||
|
||||
index_close(indrel, lockmode);
|
||||
}
|
||||
|
||||
table_close(attrelation, RowExclusiveLock);
|
||||
|
||||
ObjectAddressSubSet(address, RelationRelationId,
|
||||
|
Reference in New Issue
Block a user