From 27bc6581d5a74ecb130c322baae90fd7c09f36c6 Mon Sep 17 00:00:00 2001 From: jian he Date: Wed, 17 Sep 2025 15:31:55 +0800 Subject: [PATCH v57 1/1] refactor for v57 mainly refactoring these function check_two_partitions_bounds_range and check_partition_bounds_for_split_range. --- src/backend/commands/tablecmds.c | 5 +- src/backend/partitioning/partbounds.c | 147 +++++++++--------- src/test/regress/expected/partition_split.out | 12 +- 3 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d61b73e9dd1..9a52a36edba 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -23216,7 +23216,6 @@ ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, { Relation splitRel; Oid splitRelOid; - char relname[NAMEDATALEN]; ListCell *listptr, *listptr2; bool isSameName = false; @@ -23243,8 +23242,6 @@ ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, { Oid existingRelid; - strlcpy(relname, sps->name->relname, NAMEDATALEN); - /* Look up existing relation by new partition name. */ RangeVarGetAndCheckCreationNamespace(sps->name, NoLock, &existingRelid); @@ -23258,7 +23255,7 @@ ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, else if (OidIsValid(existingRelid)) ereport(ERROR, errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists", relname)); + errmsg("relation \"%s\" already exists", sps->name->relname)); } /* Detach split partition. */ diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index a72cd7f4282..9ac00d2ff44 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -5000,8 +5000,8 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) * second_name: name of second partition * second_bound: bound of second partition * defaultPart: true if one of new partitions is DEFAULT - * merge_or_split: true indicate the opration is "ALTER TABLE ... MERGE PARTITIONS" - * false indicate the opration is "ALTER TABLE ... SPLIT PARTITIONS". + * is_merge: true indicates the operation is MERGE PARTITIONS; + * false indicates the operation is SPLIT PARTITION. * pstate: pointer to ParseState struct for determining error position */ static void @@ -5011,7 +5011,7 @@ check_two_partitions_bounds_range(Relation parent, RangeVar *second_name, PartitionBoundSpec *second_bound, bool defaultPart, - bool merge_split, + bool is_merge, ParseState *pstate) { PartitionKey key = RelationGetPartitionKey(parent); @@ -5037,19 +5037,24 @@ check_two_partitions_bounds_range(Relation parent, { PartitionRangeDatum *datum = linitial(second_bound->lowerdatums); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - merge_split - ? errmsg("can not merge partition \"%s\" together with partition \"%s\"", - second_name->relname, first_name->relname) - : errmsg("can not split to partition \"%s\" together with partition \"%s\"", - second_name->relname, first_name->relname), - errdetail("lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"", - second_name->relname, first_name->relname), - merge_split - ? errhint("ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent.") - : errhint("ALTER TABLE ... SPLIT PARTITIONS requires the partition bounds to be adjacent."), - parser_errposition(pstate, datum->location)); + if (is_merge) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("can not merge partition \"%s\" together with partition \"%s\"", + second_name->relname, first_name->relname), + errdetail("lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"", + second_name->relname, first_name->relname), + errhint("ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent."), + parser_errposition(pstate, datum->location)); + else + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("can not split to partition \"%s\" together with partition \"%s\"", + second_name->relname, first_name->relname), + errdetail("lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"", + second_name->relname, first_name->relname), + errhint("ALTER TABLE ... SPLIT PARTITIONS requires the partition bounds to be adjacent."), + parser_errposition(pstate, datum->location)); } } @@ -5212,7 +5217,6 @@ check_partitions_not_overlap_list(Relation parent, ParseState *pstate) { PartitionKey key PG_USED_FOR_ASSERTS_ONLY = RelationGetPartitionKey(parent); - int overlap_location = -1; int i, j; SinglePartitionSpec *sps1, @@ -5238,12 +5242,11 @@ check_partitions_not_overlap_list(Relation parent, { Const *val = (Const *) lfirst(list_head(overlap)); - overlap_location = val->location; ereport(ERROR, errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("new partition \"%s\" would overlap with another new partition \"%s\"", sps1->name->relname, sps2->name->relname), - parser_errposition(pstate, overlap_location)); + parser_errposition(pstate, exprLocation((Node *) val))); } } } @@ -5315,7 +5318,7 @@ check_partition_bounds_for_split_range(Relation parent, errdetail("Specified lower bound %s is greater than or equal to upper bound %s.", get_range_partbound_string(spec->lowerdatums), get_range_partbound_string(spec->upperdatums)), - parser_errposition(pstate, datum->location)); + parser_errposition(pstate, exprLocation((Node *)datum))); } /* Need to check first and last partitions (from set of new partitions) */ @@ -5335,35 +5338,33 @@ check_partition_bounds_for_split_range(Relation parent, key->partcollation, lower->datums, lower->kind, true, split_lower); + if (cmpval != 0) + datum = list_nth(spec->lowerdatums, abs(cmpval) - 1); /* - * Lower bound of "spec" should be equal (or greater than or equal - * in case defaultPart=true) to lower bound of split partition. - */ - if (!defaultPart) - { - if (cmpval != 0) - { - datum = list_nth(spec->lowerdatums, abs(cmpval) - 1); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("lower bound of partition \"%s\" is not equal to lower bound of split partition", - relname), - parser_errposition(pstate, datum->location)); - } - } - else - { - if (cmpval < 0) - { - datum = list_nth(spec->lowerdatums, abs(cmpval) - 1); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("lower bound of partition \"%s\" is less than lower bound of split partition", - relname), - parser_errposition(pstate, datum->location)); - } - } + * The lower bound of "spec" must equal to the lower bound of the + * split partition. However, if one of the new partitions is + * DEFAULT, then it is ok for the new partition's lower bound to be + * greater than that of the split partition. + */ + if (!defaultPart && cmpval != 0) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"", + relname, + get_rel_name(splitPartOid)), + errhint("%s require combined bounds of new partitions must exactly match the bound of the split partition", + "ALTER TABLE ... MERGE PARTITIONS"), + parser_errposition(pstate, exprLocation((Node *)datum))); + else if (cmpval < 0) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"", + relname, + get_rel_name(splitPartOid)), + errhint("%s require combined bounds of new partitions must exactly match the bound of the split partition", + "ALTER TABLE ... MERGE PARTITIONS"), + parser_errposition(pstate, exprLocation((Node *)datum))); } else { @@ -5376,35 +5377,33 @@ check_partition_bounds_for_split_range(Relation parent, key->partcollation, upper->datums, upper->kind, false, split_upper); + if (cmpval != 0) + datum = list_nth(spec->upperdatums, abs(cmpval) - 1); /* - * Upper bound of "spec" should be equal (or less than or equal in - * case defaultPart=true) to upper bound of split partition. - */ - if (!defaultPart) - { - if (cmpval != 0) - { - datum = list_nth(spec->upperdatums, abs(cmpval) - 1); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("upper bound of partition \"%s\" is not equal to upper bound of split partition", - relname), - parser_errposition(pstate, datum->location)); - } - } - else - { - if (cmpval > 0) - { - datum = list_nth(spec->upperdatums, abs(cmpval) - 1); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("upper bound of partition \"%s\" is greater than upper bound of split partition", - relname), - parser_errposition(pstate, datum->location)); - } - } + * The upper bound of "spec" must equal to the upper bound of the + * split partition. However, if one of the new partitions is + * DEFAULT, then it is ok for the new partition's upper bound to be + * less than that of the split partition. + */ + if (!defaultPart && cmpval != 0) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"", + relname, + get_rel_name(splitPartOid)), + errhint("%s require combined bounds of new partitions must exactly match the bound of the split partition", + "ALTER TABLE ... MERGE PARTITIONS"), + parser_errposition(pstate, exprLocation((Node *)datum))); + else if (cmpval > 0) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"", + relname, + get_rel_name(splitPartOid)), + errhint("%s require combined bounds of new partitions must exactly match the bound of the split partition", + "ALTER TABLE ... MERGE PARTITIONS"), + parser_errposition(pstate, exprLocation((Node *)datum))); } } } diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out index 7bafd93e2f6..c933332facb 100644 --- a/src/test/regress/expected/partition_split.out +++ b/src/test/regress/expected/partition_split.out @@ -53,9 +53,10 @@ ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'), PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition +ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition "sales_feb_mar_apr2022" LINE 2: (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO... ^ +HINT: ALTER TABLE ... MERGE PARTITIONS require combined bounds of new partitions must exactly match the bound of the split partition -- ERROR: partition with name "sales_feb_mar_apr2022" is already used -- (We can create partition with the same name as split partition, but can't create two partitions with the same name) ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO @@ -94,9 +95,10 @@ ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); -ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition +ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition "sales_feb_mar_apr2022" LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0... ^ +HINT: ALTER TABLE ... MERGE PARTITIONS require combined bounds of new partitions must exactly match the bound of the split partition -- ERROR: can not split to partition "sales_mar2022" together with partition "sales_feb2022" ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), @@ -114,9 +116,10 @@ ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO ('2022-03-01'), PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition +ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition "sales_feb_mar_apr2022" LINE 2: (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO... ^ +HINT: ALTER TABLE ... MERGE PARTITIONS require combined bounds of new partitions must exactly match the bound of the split partition -- Check the source partition not in the search path SET search_path = partition_split_schema2, public; ALTER TABLE partition_split_schema.sales_range @@ -1511,9 +1514,10 @@ ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); -ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition +ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition "sales_feb_mar_apr2022" LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0... ^ +HINT: ALTER TABLE ... MERGE PARTITIONS require combined bounds of new partitions must exactly match the bound of the split partition DROP TABLE sales_range; -- Test for split partition properties: -- * STATISTICS is empty -- 2.34.1