]> granicus.if.org Git - postgresql/commitdiff
Fix default_tablespace usage for partitioned tables
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 7 Jun 2019 04:44:17 +0000 (00:44 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 7 Jun 2019 04:44:17 +0000 (00:44 -0400)
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
src/test/regress/input/tablespace.source
src/test/regress/output/tablespace.source

index e13b96d252260fcee652fdcfd17b7105b8fcdebe..2a72c1b501d678f27cdb096bd6782c9cf2176f5b 100644 (file)
@@ -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);
 
index 78199eb6f5d2c8ee9271f552778723ae66da2170..8f012fcc339b3c1fda59d6fd47bfbf5a6095dea8 100644 (file)
@@ -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
index 7625374d466c1b6da9bf06462a3a73b27f3289e0..2ea68cabb0a3bc1a13d1cba64f32c2d5030bea5b 100644 (file)
@@ -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);