v57-0001-refactor-for-v57.no-cfbot

application/octet-stream

Filename: v57-0001-refactor-for-v57.no-cfbot
Type: application/octet-stream
Part: 0
Message: Re: Add SPLIT PARTITION/MERGE PARTITIONS commands
From 27bc6581d5a74ecb130c322baae90fd7c09f36c6 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
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