From ba5095036f4b8988784af3bab71a30b1f31544af Mon Sep 17 00:00:00 2001 From: l30039603 Date: Wed, 23 Nov 2022 17:49:17 +0800 Subject: [PATCH] fix subpartition tablespace pg_global --- .../optimizer/commands/tablecmds.cpp | 51 ++++++++----- .../hw_subpartition_tablespace_global.out | 75 +++++++++++++++++++ src/test/regress/parallel_schedule0 | 2 +- .../sql/hw_subpartition_tablespace_global.sql | 67 +++++++++++++++++ 4 files changed, 177 insertions(+), 18 deletions(-) create mode 100755 src/test/regress/expected/hw_subpartition_tablespace_global.out create mode 100755 src/test/regress/sql/hw_subpartition_tablespace_global.sql diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index f3dc39cd0db..f47a4892853 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -1506,12 +1506,19 @@ static void validateDfsTableDef(CreateStmt* stmt, bool isDfsTbl) } } +static void check_sub_part_tbl_space(Oid ownerId, char* tablespacename, List* subPartitionDefState) +{ + ListCell* subspccell = NULL; + foreach(subspccell, subPartitionDefState) { + RangePartitionDefState* subpartitiondef = (RangePartitionDefState*)lfirst(subspccell); + char* subtablespacename = subpartitiondef->tablespacename; + CheckPartitionTablespace(subtablespacename, ownerId); + } +} + /* Check tablespace's permissions for partition */ static void check_part_tbl_space(CreateStmt* stmt, Oid ownerId, bool dfsTablespace) { - Oid partitionTablespaceId; - bool isPartitionTablespaceDfs = false; - RangePartitionDefState* partitiondef = NULL; ListCell* spccell = NULL; /* check value partition table is created at DFS table space */ if (stmt->partTableState->partitionStrategy == PART_STRATEGY_VALUE && !dfsTablespace) @@ -1520,21 +1527,31 @@ static void check_part_tbl_space(CreateStmt* stmt, Oid ownerId, bool dfsTablespa errmsg("Value partitioned table can only be created on DFS tablespace."))); foreach (spccell, stmt->partTableState->partitionList) { - partitiondef = (RangePartitionDefState*)lfirst(spccell); - - if (partitiondef->tablespacename) { - partitionTablespaceId = get_tablespace_oid(partitiondef->tablespacename, false); - isPartitionTablespaceDfs = IsSpecifiedTblspc(partitionTablespaceId, FILESYSTEM_HDFS); - if (isPartitionTablespaceDfs) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Partition can not be created on DFS tablespace.Only table-level tablespace can be " - "DFS.DFS table only support partition strategy '%s' feature.", - GetPartitionStrategyNameByType(PART_STRATEGY_VALUE)))); - } + if (nodeTag(lfirst(spccell)) == T_RangePartitionDefState) { + RangePartitionDefState* partitiondef = (RangePartitionDefState*)lfirst(spccell); + char* tablespacename = partitiondef->tablespacename; + List* subPartitionDefState = partitiondef->subPartitionDefState; + CheckPartitionTablespace(tablespacename, ownerId); + check_sub_part_tbl_space(ownerId, tablespacename, subPartitionDefState); + } else if (nodeTag(lfirst(spccell)) == T_HashPartitionDefState) { + HashPartitionDefState* partitiondef = (HashPartitionDefState*)lfirst(spccell); + char* tablespacename = partitiondef->tablespacename; + List* subPartitionDefState = partitiondef->subPartitionDefState; + CheckPartitionTablespace(tablespacename, ownerId); + check_sub_part_tbl_space(ownerId, tablespacename, subPartitionDefState); + } else if (nodeTag(lfirst(spccell)) == T_ListPartitionDefState) { + ListPartitionDefState* partitiondef = (ListPartitionDefState*)lfirst(spccell); + char* tablespacename = partitiondef->tablespacename; + List* subPartitionDefState = partitiondef->subPartitionDefState; + CheckPartitionTablespace(tablespacename, ownerId); + check_sub_part_tbl_space(ownerId, tablespacename, subPartitionDefState); + } else { + ereport(ERROR, (errmodule(MOD_COMMAND), errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Unknown PartitionDefState"), + errdetail("N/A"), errcause("The partition type is incorrect."), + erraction("Use the correct partition type."))); + break; } - - CheckPartitionTablespace(partitiondef->tablespacename, ownerId); } } diff --git a/src/test/regress/expected/hw_subpartition_tablespace_global.out b/src/test/regress/expected/hw_subpartition_tablespace_global.out new file mode 100755 index 00000000000..a63e8ef4a19 --- /dev/null +++ b/src/test/regress/expected/hw_subpartition_tablespace_global.out @@ -0,0 +1,75 @@ +DROP SCHEMA subpartition_tablespace CASCADE; +ERROR: schema "subpartition_tablespace" does not exist +CREATE SCHEMA subpartition_tablespace; +SET CURRENT_SCHEMA TO subpartition_tablespace; + +create table t1(id int) +partition by range(id)( +partition p1 values less than(100), +partition p2 values less than(200) tablespace pg_global); +ERROR: only shared relations can be placed in pg_global tablespace +drop table if exists t1; +NOTICE: table "t1" does not exist, skipping + +create table t1(id int) +partition by range(id)( +partition p1 values less than(100), +partition p2 values less than(200)); +alter table t1 add partition p3 values less than(300); +alter table t1 add partition p4 values less than(400) tablespace pg_global; +ERROR: only shared relations can be placed in pg_global tablespace +drop table if exists t1; + +create table b_range_hash_t01(c1 int primary key,c2 int,c3 text) +partition by range(c1) subpartition by hash(c2) +( +partition p1 values less than (100) +( +subpartition p1_1 tablespace pg_global, +subpartition p1_2 +), +partition p2 values less than (200) +( +subpartition p2_1, +subpartition p2_2 +), +partition p3 values less than (300) +( +subpartition p3_1, +subpartition p3_2 +) +); +ERROR: only shared relations can be placed in pg_global tablespace +drop table if exists b_range_hash_t01; +NOTICE: table "b_range_hash_t01" does not exist, skipping + +create table b_range_hash_t01(c1 int primary key,c2 int,c3 text) +partition by range(c1) subpartition by hash(c2) +( +partition p1 values less than (100) +( +subpartition p1_1, +subpartition p1_2 +), +partition p2 values less than (200) +( +subpartition p2_1, +subpartition p2_2 +) +); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "b_range_hash_t01_pkey" for table "b_range_hash_t01" +alter table b_range_hash_t01 add partition p3 values less than (300) +( + subpartition p3_1, + subpartition p3_2 +); +alter table b_range_hash_t01 add partition p4 values less than (400) +( + subpartition p4_1 tablespace pg_global, + subpartition p4_2 +); +ERROR: only shared relations can be placed in pg_global tablespace +drop table if exists b_range_hash_t01; + +DROP SCHEMA subpartition_tablespace CASCADE; +RESET CURRENT_SCHEMA; diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 96641c37a0a..775f3bb49e6 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -68,7 +68,7 @@ test: single_node_sha # test subpartition test: hw_subpartition_createtable hw_subpartition_scan hw_subpartition_select hw_subpartition_split hw_subpartition_truncate hw_subpartition_update hw_subpartition_gpi hw_subpartition_analyze_vacuum hw_subpartition_alter_table hw_subpartition_index hw_subpartition_add_drop_partition hw_subpartition_tablespace hw_subpartition_ddl_index hw_subpartition_size -test: hw_subpartition_vacuum_partition +test: hw_subpartition_vacuum_partition hw_subpartition_tablespace_global test: gs_dump_subpartition test: partition_dml_operations partition_minmax test: partition_param_path diff --git a/src/test/regress/sql/hw_subpartition_tablespace_global.sql b/src/test/regress/sql/hw_subpartition_tablespace_global.sql new file mode 100755 index 00000000000..c3b4562adff --- /dev/null +++ b/src/test/regress/sql/hw_subpartition_tablespace_global.sql @@ -0,0 +1,67 @@ +DROP SCHEMA subpartition_tablespace CASCADE; +CREATE SCHEMA subpartition_tablespace; +SET CURRENT_SCHEMA TO subpartition_tablespace; + +create table t1(id int) +partition by range(id)( +partition p1 values less than(100), +partition p2 values less than(200) tablespace pg_global); +drop table if exists t1; + +create table t1(id int) +partition by range(id)( +partition p1 values less than(100), +partition p2 values less than(200)); +alter table t1 add partition p3 values less than(300); +alter table t1 add partition p4 values less than(400) tablespace pg_global; +drop table if exists t1; + +create table b_range_hash_t01(c1 int primary key,c2 int,c3 text) +partition by range(c1) subpartition by hash(c2) +( +partition p1 values less than (100) +( +subpartition p1_1 tablespace pg_global, +subpartition p1_2 +), +partition p2 values less than (200) +( +subpartition p2_1, +subpartition p2_2 +), +partition p3 values less than (300) +( +subpartition p3_1, +subpartition p3_2 +) +); +drop table if exists b_range_hash_t01; + +create table b_range_hash_t01(c1 int primary key,c2 int,c3 text) +partition by range(c1) subpartition by hash(c2) +( +partition p1 values less than (100) +( +subpartition p1_1, +subpartition p1_2 +), +partition p2 values less than (200) +( +subpartition p2_1, +subpartition p2_2 +) +); +alter table b_range_hash_t01 add partition p3 values less than (300) +( + subpartition p3_1, + subpartition p3_2 +); +alter table b_range_hash_t01 add partition p4 values less than (400) +( + subpartition p4_1 tablespace pg_global, + subpartition p4_2 +); +drop table if exists b_range_hash_t01; + +DROP SCHEMA subpartition_tablespace CASCADE; +RESET CURRENT_SCHEMA; \ No newline at end of file -- Gitee