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

Commitdfa6081

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 parentceadcbe commitdfa6081

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
@@ -353,7 +353,6 @@ heap_create(const char *relname,
353353
caseRELKIND_COMPOSITE_TYPE:
354354
caseRELKIND_FOREIGN_TABLE:
355355
caseRELKIND_PARTITIONED_TABLE:
356-
caseRELKIND_PARTITIONED_INDEX:
357356
create_storage= false;
358357

359358
/*
@@ -362,6 +361,15 @@ heap_create(const char *relname,
362361
*/
363362
reltablespace=InvalidOid;
364363
break;
364+
365+
caseRELKIND_PARTITIONED_INDEX:
366+
/*
367+
* Preserve tablespace so that it's used as tablespace for indexes
368+
* on future partitions.
369+
*/
370+
create_storage= false;
371+
break;
372+
365373
caseRELKIND_SEQUENCE:
366374
create_storage= true;
367375

‎src/backend/commands/tablecmds.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ static bool ATPrepChangePersistence(Relation rel, bool toLogged);
449449
staticvoidATPrepSetTableSpace(AlteredTableInfo*tab,Relationrel,
450450
constchar*tablespacename,LOCKMODElockmode);
451451
staticvoidATExecSetTableSpace(OidtableOid,OidnewTableSpace,LOCKMODElockmode);
452+
staticvoidATExecPartedIdxSetTableSpace(Relationrel,OidnewTableSpace);
452453
staticvoidATExecSetRelOptions(Relationrel,List*defList,
453454
AlterTableTypeoperation,
454455
LOCKMODElockmode);
@@ -3875,7 +3876,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
38753876
pass=AT_PASS_DROP;
38763877
break;
38773878
caseAT_SetTableSpace:/* SET TABLESPACE */
3878-
ATSimplePermissions(rel,ATT_TABLE |ATT_MATVIEW |ATT_INDEX);
3879+
ATSimplePermissions(rel,ATT_TABLE |ATT_MATVIEW |ATT_INDEX |
3880+
ATT_PARTITIONED_INDEX);
38793881
/* This command never recurses */
38803882
ATPrepSetTableSpace(tab,rel,cmd->name,lockmode);
38813883
pass=AT_PASS_MISC;/* doesn't actually matter */
@@ -4211,10 +4213,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
42114213
*/
42124214
break;
42134215
caseAT_SetTableSpace:/* SET TABLESPACE */
4214-
42154216
/*
4216-
* Nothing to do here; Phase 3 does the work
4217+
* Only do this for partitioned indexes, for which this is just
4218+
* a catalog change. Other relation types are handled by Phase 3.
42174219
*/
4220+
if (rel->rd_rel->relkind==RELKIND_PARTITIONED_INDEX)
4221+
ATExecPartedIdxSetTableSpace(rel,tab->newTableSpace);
4222+
42184223
break;
42194224
caseAT_SetRelOptions:/* SET (...) */
42204225
caseAT_ResetRelOptions:/* RESET (...) */
@@ -11080,6 +11085,55 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
1108011085
list_free(reltoastidxids);
1108111086
}
1108211087

11088+
/*
11089+
* Special handling of ALTER TABLE SET TABLESPACE for partitioned indexes,
11090+
* which have no storage (so not handled in Phase 3 like other relation types)
11091+
*/
11092+
staticvoid
11093+
ATExecPartedIdxSetTableSpace(Relationrel,OidnewTableSpace)
11094+
{
11095+
HeapTupletuple;
11096+
OidoldTableSpace;
11097+
Relationpg_class;
11098+
Form_pg_classrd_rel;
11099+
OidindexOid=RelationGetRelid(rel);
11100+
11101+
Assert(rel->rd_rel->relkind==RELKIND_PARTITIONED_INDEX);
11102+
11103+
/*
11104+
* No work if no change in tablespace.
11105+
*/
11106+
oldTableSpace=rel->rd_rel->reltablespace;
11107+
if (newTableSpace==oldTableSpace||
11108+
(newTableSpace==MyDatabaseTableSpace&&oldTableSpace==0))
11109+
{
11110+
InvokeObjectPostAlterHook(RelationRelationId,
11111+
indexOid,0);
11112+
return;
11113+
}
11114+
11115+
/* Get a modifiable copy of the relation's pg_class row */
11116+
pg_class=heap_open(RelationRelationId,RowExclusiveLock);
11117+
11118+
tuple=SearchSysCacheCopy1(RELOID,ObjectIdGetDatum(indexOid));
11119+
if (!HeapTupleIsValid(tuple))
11120+
elog(ERROR,"cache lookup failed for relation %u",indexOid);
11121+
rd_rel= (Form_pg_class)GETSTRUCT(tuple);
11122+
11123+
/* update the pg_class row */
11124+
rd_rel->reltablespace= (newTableSpace==MyDatabaseTableSpace) ?InvalidOid :newTableSpace;
11125+
CatalogTupleUpdate(pg_class,&tuple->t_self,tuple);
11126+
11127+
InvokeObjectPostAlterHook(RelationRelationId,indexOid,0);
11128+
11129+
heap_freetuple(tuple);
11130+
11131+
heap_close(pg_class,RowExclusiveLock);
11132+
11133+
/* Make sure the reltablespace change is visible */
11134+
CommandCounterIncrement();
11135+
}
11136+
1108311137
/*
1108411138
* Alter Table ALL ... SET TABLESPACE
1108511139
*

‎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