diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/tablecmds.c | 47 | ||||
-rw-r--r-- | src/test/regress/expected/alter_table.out | 20 | ||||
-rw-r--r-- | src/test/regress/expected/vacuum.out | 4 | ||||
-rw-r--r-- | src/test/regress/sql/alter_table.sql | 6 | ||||
-rw-r--r-- | src/test/regress/sql/vacuum.sql | 4 |
5 files changed, 77 insertions, 4 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 5745cd648a6..2fba83504b6 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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, diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index f343f9b42ea..99ff6973bc8 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2172,6 +2172,26 @@ where oid = 'test_storage'::regclass; t (1 row) +-- test that SET STORAGE propagates to index correctly +create index test_storage_idx on test_storage (b, a); +alter table test_storage alter column a set storage external; +\d+ test_storage + Table "public.test_storage" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | text | | | | external | | + b | integer | | | 0 | plain | | +Indexes: + "test_storage_idx" btree (b, a) + +\d+ test_storage_idx + Index "public.test_storage_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+----------+-------------- + b | integer | yes | b | plain | + a | text | yes | a | external | +btree, for table "public.test_storage" + -- ALTER COLUMN TYPE with a check constraint and a child table (bug #13779) CREATE TABLE test_inh_check (a float check (a > 10.2), b float); CREATE TABLE test_inh_check_child() INHERITS(test_inh_check); diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index 736c2f60d20..3fccb183c0f 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -134,7 +134,7 @@ CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT); CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t); ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), - repeat('1234567890',300)); + repeat('1234567890',269)); -- index cleanup option is ignored if VACUUM FULL VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup; VACUUM (FULL TRUE) no_index_cleanup; @@ -148,7 +148,7 @@ ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true); VACUUM no_index_cleanup; -- Parameter is set for both the parent table and its toast relation. INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), - repeat('1234567890',300)); + repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; -- Only toast index is cleaned up. ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false, diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index fb5c9139d15..b45ba2a322b 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1472,6 +1472,12 @@ select reltoastrelid <> 0 as has_toast_table from pg_class where oid = 'test_storage'::regclass; +-- test that SET STORAGE propagates to index correctly +create index test_storage_idx on test_storage (b, a); +alter table test_storage alter column a set storage external; +\d+ test_storage +\d+ test_storage_idx + -- ALTER COLUMN TYPE with a check constraint and a child table (bug #13779) CREATE TABLE test_inh_check (a float check (a > 10.2), b float); CREATE TABLE test_inh_check_child() INHERITS(test_inh_check); diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 84dee8c8169..c7b5f96f6bd 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -115,7 +115,7 @@ CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT); CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t); ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL; INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), - repeat('1234567890',300)); + repeat('1234567890',269)); -- index cleanup option is ignored if VACUUM FULL VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup; VACUUM (FULL TRUE) no_index_cleanup; @@ -129,7 +129,7 @@ ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true); VACUUM no_index_cleanup; -- Parameter is set for both the parent table and its toast relation. INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), - repeat('1234567890',300)); + repeat('1234567890',269)); DELETE FROM no_index_cleanup WHERE i < 45; -- Only toast index is cleaned up. ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false, |