From a36c84c3e4a9bee6baa740848f67a5db3fa279b0 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 7 Jun 2019 00:44:17 -0400 Subject: [PATCH] Fix default_tablespace usage for partitioned tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 87259588d0ab I (Álvaro) tried to rationalize the determination of tablespace to use for partitioned tables, but failed to handle the default_tablespace case. Repair and add proper tests. Author: Amit Langote, Rushabh Lathia Reported-by: Rushabh Lathia Reviewed-by: Amit Langote, Álvaro Herrera Discussion: https://postgr.es/m/CAGPqQf0cYjm1=rjxk_6gU0SjUS70=yFUAdCJLwWzh9bhNJnyVg@mail.gmail.com --- src/backend/commands/tablecmds.c | 8 +++- src/test/regress/input/tablespace.source | 34 +++++++++++++--- src/test/regress/output/tablespace.source | 48 ++++++++++++++++++----- 3 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e13b96d252..2a72c1b501 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -660,8 +660,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, } /* - * Select tablespace to use. If not specified, use default tablespace - * (which may in turn default to database's default). + * Select tablespace to use: an explicitly indicated one, or (in the case + * of a partitioned table) the parent's, if it has one. */ if (stmt->tablespacename) { @@ -682,6 +682,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, tablespaceId = get_rel_tablespace(linitial_oid(inheritOids)); } else + tablespaceId = InvalidOid; + + /* still nothing? use the default */ + if (!OidIsValid(tablespaceId)) tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence, partitioned); diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source index 78199eb6f5..8f012fcc33 100644 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/input/tablespace.source @@ -44,16 +44,38 @@ CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace; SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c where c.reltablespace = t.oid AND c.relname = 'foo_idx'; +-- -- partitioned table +-- CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); -CREATE TABLE testschema.part12 PARTITION OF testschema.part FOR VALUES IN(1,2) PARTITION BY LIST (a) TABLESPACE regress_tblspace; -CREATE TABLE testschema.part12_1 PARTITION OF testschema.part12 FOR VALUES IN (1); -ALTER TABLE testschema.part12 SET TABLESPACE pg_default; -CREATE TABLE testschema.part12_2 PARTITION OF testschema.part12 FOR VALUES IN (2); --- Ensure part12_1 defaulted to regress_tblspace and part12_2 defaulted to pg_default. +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +RESET default_tablespace; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +SET default_tablespace TO regress_tblspace; +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default; +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a); +ALTER TABLE testschema.part SET TABLESPACE pg_default; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace; +RESET default_tablespace; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); + SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid - where c.relname LIKE 'part%' order by relname; + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname; +RESET default_tablespace; DROP TABLE testschema.part; -- partitioned index diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source index 7625374d46..2ea68cabb0 100644 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/output/tablespace.source @@ -61,24 +61,52 @@ SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c foo_idx | regress_tblspace (1 row) +-- -- partitioned table +-- CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); -CREATE TABLE testschema.part12 PARTITION OF testschema.part FOR VALUES IN(1,2) PARTITION BY LIST (a) TABLESPACE regress_tblspace; -CREATE TABLE testschema.part12_1 PARTITION OF testschema.part12 FOR VALUES IN (1); -ALTER TABLE testschema.part12 SET TABLESPACE pg_default; -CREATE TABLE testschema.part12_2 PARTITION OF testschema.part12 FOR VALUES IN (2); --- Ensure part12_1 defaulted to regress_tblspace and part12_2 defaulted to pg_default. +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +ERROR: only shared relations can be placed in pg_global tablespace +RESET default_tablespace; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +SET default_tablespace TO regress_tblspace; +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +ERROR: only shared relations can be placed in pg_global tablespace +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default; +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a); +ALTER TABLE testschema.part SET TABLESPACE pg_default; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); +ERROR: only shared relations can be placed in pg_global tablespace +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace; +RESET default_tablespace; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid - where c.relname LIKE 'part%' order by relname; + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname; relname | spcname ----------+------------------ part | - part12 | - part12_1 | regress_tblspace - part12_2 | -(4 rows) + part_1 | + part_2 | regress_tblspace + part_3 | regress_tblspace + part_4 | + part_56 | regress_tblspace + part_78 | + part_910 | regress_tblspace +(8 rows) +RESET default_tablespace; DROP TABLE testschema.part; -- partitioned index CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);