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



Reply via email to