Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit33e6c34

Browse files
committed
Fix tablespace handling for partitioned indexes
When creating partitioned indexes, the tablespace was not being savedfor the parent index. This meant that subsequently created partitionswould not use the right tablespace for their indexes.ALTER INDEX SET TABLESPACE and ALTER INDEX ALL IN TABLESPACE raisederrors when tried; fix them too. This requires bespoke code forATExecCmd() that applies to the special case when the tablespace move isjust a catalog change.Discussion:https://postgr.es/m/20181102003138.uxpaca6qfxzskepi@alvherre.pgsql
1 parent0e88ba1 commit33e6c34

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

‎src/backend/catalog/heap.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ heap_create(const char *relname,
297297
caseRELKIND_COMPOSITE_TYPE:
298298
caseRELKIND_FOREIGN_TABLE:
299299
caseRELKIND_PARTITIONED_TABLE:
300-
caseRELKIND_PARTITIONED_INDEX:
301300
create_storage= false;
302301

303302
/*
@@ -306,6 +305,15 @@ heap_create(const char *relname,
306305
*/
307306
reltablespace=InvalidOid;
308307
break;
308+
309+
caseRELKIND_PARTITIONED_INDEX:
310+
/*
311+
* Preserve tablespace so that it's used as tablespace for indexes
312+
* on future partitions.
313+
*/
314+
create_storage= false;
315+
break;
316+
309317
caseRELKIND_SEQUENCE:
310318
create_storage= true;
311319

‎src/backend/commands/tablecmds.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ static bool ATPrepChangePersistence(Relation rel, bool toLogged);
446446
staticvoidATPrepSetTableSpace(AlteredTableInfo*tab,Relationrel,
447447
constchar*tablespacename,LOCKMODElockmode);
448448
staticvoidATExecSetTableSpace(OidtableOid,OidnewTableSpace,LOCKMODElockmode);
449+
staticvoidATExecPartedIdxSetTableSpace(Relationrel,OidnewTableSpace);
449450
staticvoidATExecSetRelOptions(Relationrel,List*defList,
450451
AlterTableTypeoperation,
451452
LOCKMODElockmode);
@@ -3845,7 +3846,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
38453846
pass=AT_PASS_DROP;
38463847
break;
38473848
caseAT_SetTableSpace:/* SET TABLESPACE */
3848-
ATSimplePermissions(rel,ATT_TABLE |ATT_MATVIEW |ATT_INDEX);
3849+
ATSimplePermissions(rel,ATT_TABLE |ATT_MATVIEW |ATT_INDEX |
3850+
ATT_PARTITIONED_INDEX);
38493851
/* This command never recurses */
38503852
ATPrepSetTableSpace(tab,rel,cmd->name,lockmode);
38513853
pass=AT_PASS_MISC;/* doesn't actually matter */
@@ -4181,10 +4183,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
41814183
*/
41824184
break;
41834185
caseAT_SetTableSpace:/* SET TABLESPACE */
4184-
41854186
/*
4186-
* Nothing to do here; Phase 3 does the work
4187+
* Only do this for partitioned indexes, for which this is just
4188+
* a catalog change. Other relation types are handled by Phase 3.
41874189
*/
4190+
if (rel->rd_rel->relkind==RELKIND_PARTITIONED_INDEX)
4191+
ATExecPartedIdxSetTableSpace(rel,tab->newTableSpace);
4192+
41884193
break;
41894194
caseAT_SetRelOptions:/* SET (...) */
41904195
caseAT_ResetRelOptions:/* RESET (...) */
@@ -11049,6 +11054,55 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
1104911054
list_free(reltoastidxids);
1105011055
}
1105111056

11057+
/*
11058+
* Special handling of ALTER TABLE SET TABLESPACE for partitioned indexes,
11059+
* which have no storage (so not handled in Phase 3 like other relation types)
11060+
*/
11061+
staticvoid
11062+
ATExecPartedIdxSetTableSpace(Relationrel,OidnewTableSpace)
11063+
{
11064+
HeapTupletuple;
11065+
OidoldTableSpace;
11066+
Relationpg_class;
11067+
Form_pg_classrd_rel;
11068+
OidindexOid=RelationGetRelid(rel);
11069+
11070+
Assert(rel->rd_rel->relkind==RELKIND_PARTITIONED_INDEX);
11071+
11072+
/*
11073+
* No work if no change in tablespace.
11074+
*/
11075+
oldTableSpace=rel->rd_rel->reltablespace;
11076+
if (newTableSpace==oldTableSpace||
11077+
(newTableSpace==MyDatabaseTableSpace&&oldTableSpace==0))
11078+
{
11079+
InvokeObjectPostAlterHook(RelationRelationId,
11080+
indexOid,0);
11081+
return;
11082+
}
11083+
11084+
/* Get a modifiable copy of the relation's pg_class row */
11085+
pg_class=heap_open(RelationRelationId,RowExclusiveLock);
11086+
11087+
tuple=SearchSysCacheCopy1(RELOID,ObjectIdGetDatum(indexOid));
11088+
if (!HeapTupleIsValid(tuple))
11089+
elog(ERROR,"cache lookup failed for relation %u",indexOid);
11090+
rd_rel= (Form_pg_class)GETSTRUCT(tuple);
11091+
11092+
/* update the pg_class row */
11093+
rd_rel->reltablespace= (newTableSpace==MyDatabaseTableSpace) ?InvalidOid :newTableSpace;
11094+
CatalogTupleUpdate(pg_class,&tuple->t_self,tuple);
11095+
11096+
InvokeObjectPostAlterHook(RelationRelationId,indexOid,0);
11097+
11098+
heap_freetuple(tuple);
11099+
11100+
heap_close(pg_class,RowExclusiveLock);
11101+
11102+
/* Make sure the reltablespace change is visible */
11103+
CommandCounterIncrement();
11104+
}
11105+
1105211106
/*
1105311107
* Alter Table ALL ... SET TABLESPACE
1105411108
*

‎src/test/regress/input/tablespace.source

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace;
4444
SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
4545
where c.reltablespace = t.oid AND c.relname = 'foo_idx';
4646

47+
-- partitioned index
48+
CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);
49+
CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1);
50+
CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace;
51+
CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2);
52+
SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
53+
where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx';
54+
4755
-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds
4856
CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace;
4957
INSERT INTO testschema.test_default_tab VALUES (1);
@@ -93,6 +101,8 @@ CREATE UNIQUE INDEX anindex ON testschema.atable(column1);
93101

94102
ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace;
95103
ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace;
104+
ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default;
105+
ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace;
96106

97107
INSERT INTO testschema.atable VALUES(3);-- ok
98108
INSERT INTO testschema.atable VALUES(1);-- fail (checks index)

‎src/test/regress/output/tablespace.source

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
6161
foo_idx | regress_tblspace
6262
(1 row)
6363

64+
-- partitioned index
65+
CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);
66+
CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1);
67+
CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace;
68+
CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2);
69+
SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
70+
where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx';
71+
relname | spcname
72+
-------------+------------------
73+
part1_a_idx | regress_tblspace
74+
part2_a_idx | regress_tblspace
75+
part_a_idx | regress_tblspace
76+
(3 rows)
77+
6478
-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds
6579
CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace;
6680
INSERT INTO testschema.test_default_tab VALUES (1);
@@ -200,6 +214,8 @@ CREATE TABLE testschema.atable AS VALUES (1), (2);
200214
CREATE UNIQUE INDEX anindex ON testschema.atable(column1);
201215
ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace;
202216
ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace;
217+
ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default;
218+
ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace;
203219
INSERT INTO testschema.atable VALUES(3);-- ok
204220
INSERT INTO testschema.atable VALUES(1);-- fail (checks index)
205221
ERROR: duplicate key value violates unique constraint "anindex"
@@ -241,10 +257,11 @@ NOTICE: no matching relations in tablespace "regress_tblspace_renamed" found
241257
-- Should succeed
242258
DROP TABLESPACE regress_tblspace_renamed;
243259
DROP SCHEMA testschema CASCADE;
244-
NOTICE: drop cascades to5 other objects
260+
NOTICE: drop cascades to6 other objects
245261
DETAIL: drop cascades to table testschema.foo
246262
drop cascades to table testschema.asselect
247263
drop cascades to table testschema.asexecute
264+
drop cascades to table testschema.part
248265
drop cascades to table testschema.atable
249266
drop cascades to table testschema.tablespace_acl
250267
DROP ROLE regress_tablespace_user1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp