Hi hackers,
The following sequence of statements:
CREATE SCHEMA testschema;
CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);
SET default_tablespace TO pg_global;
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);
Produce error
ERROR: only shared relations can be placed in pg_global tablespace
when been executed in database with default tablespace, but produce no
error in database with assigned tablespace.
create tablespace my_tblspc location '/tmp/tblspc';
create databse test;
alter database test set tablespace my_tblspc;
There is the following code in tablecmds.c:
else if (stmt->partbound)
{
/*
* For partitions, when no other tablespace is specified, we
default
* the tablespace to the parent partitioned table's.
*/
Assert(list_length(inheritOids) == 1);
tablespaceId = get_rel_tablespace(linitial_oid(inheritOids));
}
In first case get_rel_tablespace returns 0 (because parent table has no
explicit tablespace)
and in the second: pg_default
Also I am confused that the following statement is rejected:
SET default_tablespace TO pg_default;
CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);
ERROR: cannot specify default tablespace for partitioned relations
but still it is possible to set tablespace of parent table to pg_default
using alter tablespace command:
RESET default_tablespace;
CREATE TABLE testschema.part (a int) PARTITION BY LIST (a);
ALTER TABLE testschema.part SET TABLESPACE pg_default;
But ... it has no effect: testschema.part is till assumed to belong to
default tablespace.
Because of the following code in tablecmds.c:
/*
* No work if no change in tablespace.
*/
oldTableSpace = rel->rd_rel->reltablespace;
if (newTableSpace == oldTableSpace ||
(newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
{
InvokeObjectPostAlterHook(RelationRelationId,
RelationGetRelid(rel), 0);
relation_close(rel, NoLock);
return;
}
I found the thread discussing the similar problem:
https://www.postgresql.org/message-id/flat/BY5PR18MB3170E372542F34694E630B12F10C0%40BY5PR18MB3170.namprd18.prod.outlook.com
and looks like the decision was to change nothing and leave everything
as it is.
From my point of view the source of the problem is that pg_default
(oid=1663) is treated as database default tablespace.
pg_default stands for concrete tablespace and it is not clear why it is
treated in different way comparing with any other tablepsace.
--
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company