diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2020-04-09 14:10:01 +0200 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2020-05-08 09:30:57 +0200 |
commit | 03a8a5f2d4a1f9886ad1d62d3f70424dfcdf8048 (patch) | |
tree | 1d9ee332c7682647e2e965b22c7ce33a5cde015d /src/backend/commands | |
parent | f918b5d219b7200d204515b32346183b97d031ae (diff) | |
download | postgresql-03a8a5f2d4a1f9886ad1d62d3f70424dfcdf8048.tar.gz postgresql-03a8a5f2d4a1f9886ad1d62d3f70424dfcdf8048.zip |
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
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/tablecmds.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 49d7059d535..bc66d6c4f5f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -6734,6 +6734,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); @@ -6793,6 +6794,53 @@ 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; + int i; + AttrNumber indattnum = 0; + + indrel = index_open(indexoid, lockmode); + + for (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); + } + heap_close(attrelation, RowExclusiveLock); ObjectAddressSubSet(address, RelationRelationId, |