aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/tablecmds.c62
-rw-r--r--src/test/regress/expected/partition_merge.out3
-rw-r--r--src/test/regress/expected/partition_split.out8
-rw-r--r--src/test/regress/sql/partition_merge.sql3
-rw-r--r--src/test/regress/sql/partition_split.sql9
5 files changed, 72 insertions, 13 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 313c782cae2..7a063ca8ae0 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -20409,6 +20409,7 @@ ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
* against concurrent drop, and mark stmt->relation as
* RELPERSISTENCE_TEMP if a temporary namespace is selected.
*/
+ sps->name->relpersistence = rel->rd_rel->relpersistence;
namespaceId =
RangeVarGetAndCheckCreationNamespace(sps->name, NoLock, NULL);
@@ -20601,6 +20602,8 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
ListCell *listptr;
List *mergingPartitionsList = NIL;
Oid defaultPartOid;
+ Oid namespaceId;
+ Oid existingRelid;
/*
* Lock all merged partitions, check them and create list with partitions
@@ -20617,13 +20620,48 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
*/
mergingPartition = table_openrv(name, AccessExclusiveLock);
- /*
- * Checking that two partitions have the same name was before, in
- * function transformPartitionCmdForMerge().
- */
- if (equal(name, cmd->name))
+ /* Store a next merging partition into the list. */
+ mergingPartitionsList = lappend(mergingPartitionsList,
+ mergingPartition);
+ }
+
+ /*
+ * Look up the namespace in which we are supposed to create the partition,
+ * check we have permission to create there, lock it against concurrent
+ * drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary
+ * namespace is selected.
+ */
+ cmd->name->relpersistence = rel->rd_rel->relpersistence;
+ namespaceId =
+ RangeVarGetAndCheckCreationNamespace(cmd->name, NoLock, NULL);
+
+ /*
+ * Check if this name is already taken. This helps us to detect the
+ * situation when one of the merging partitions has the same name as the
+ * new partition. Otherwise, this would fail later on anyway but catching
+ * this here allows us to emit a nicer error message.
+ */
+ existingRelid = get_relname_relid(cmd->name->relname, namespaceId);
+
+ if (OidIsValid(existingRelid))
+ {
+ Relation sameNamePartition = NULL;
+
+ foreach_ptr(RelationData, mergingPartition, mergingPartitionsList)
{
- /* One new partition can have the same name as merged partition. */
+ if (RelationGetRelid(mergingPartition) == existingRelid)
+ {
+ sameNamePartition = mergingPartition;
+ break;
+ }
+ }
+
+ if (sameNamePartition)
+ {
+ /*
+ * The new partition has the same name as one of merging
+ * partitions.
+ */
char tmpRelName[NAMEDATALEN];
/* Generate temporary name. */
@@ -20635,7 +20673,7 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
* in the future because we're going to eventually drop the
* existing partition anyway.
*/
- RenameRelationInternal(RelationGetRelid(mergingPartition),
+ RenameRelationInternal(RelationGetRelid(sameNamePartition),
tmpRelName, false, false);
/*
@@ -20644,10 +20682,12 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
*/
CommandCounterIncrement();
}
-
- /* Store a next merging partition into the list. */
- mergingPartitionsList = lappend(mergingPartitionsList,
- mergingPartition);
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_TABLE),
+ errmsg("relation \"%s\" already exists", cmd->name->relname)));
+ }
}
/* Detach all merged partitions. */
diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out
index 6361732d104..9c67a4a8b15 100644
--- a/src/test/regress/expected/partition_merge.out
+++ b/src/test/regress/expected/partition_merge.out
@@ -214,7 +214,8 @@ INSERT INTO sales_range VALUES (13, 'Gandi', 377, '2022-01-09');
INSERT INTO sales_range VALUES (14, 'Smith', 510, '2022-05-04');
-- Merge partitions (include DEFAULT partition) into partition with the same
-- name
-ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022, sales_others) INTO sales_others;
+ALTER TABLE sales_range MERGE PARTITIONS
+ (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others;
select * from sales_others;
salesperson_id | salesperson_name | sales_amount | sales_date
----------------+------------------+--------------+------------
diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out
index 14c4f97c9ff..d08eb4770ba 100644
--- a/src/test/regress/expected/partition_split.out
+++ b/src/test/regress/expected/partition_split.out
@@ -1547,6 +1547,14 @@ REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_alice;
REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob;
DROP ROLE regress_partition_split_alice;
DROP ROLE regress_partition_split_bob;
+-- Split partition of a temporary table when one of the partitions after
+-- split has the same name as the partition being split
+CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a);
+CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2);
+ALTER TABLE t SPLIT PARTITION tp_0 INTO
+ (PARTITION tp_0 FOR VALUES FROM (0) TO (1),
+ PARTITION tp_1 FOR VALUES FROM (1) TO (2));
+DROP TABLE t;
RESET search_path;
--
DROP SCHEMA partition_split_schema;
diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql
index 5a741efa09b..56249732002 100644
--- a/src/test/regress/sql/partition_merge.sql
+++ b/src/test/regress/sql/partition_merge.sql
@@ -140,7 +140,8 @@ INSERT INTO sales_range VALUES (14, 'Smith', 510, '2022-05-04');
-- Merge partitions (include DEFAULT partition) into partition with the same
-- name
-ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022, sales_others) INTO sales_others;
+ALTER TABLE sales_range MERGE PARTITIONS
+ (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others;
select * from sales_others;
diff --git a/src/test/regress/sql/partition_split.sql b/src/test/regress/sql/partition_split.sql
index 70d70499ec6..d9e2359cb76 100644
--- a/src/test/regress/sql/partition_split.sql
+++ b/src/test/regress/sql/partition_split.sql
@@ -931,6 +931,15 @@ REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob;
DROP ROLE regress_partition_split_alice;
DROP ROLE regress_partition_split_bob;
+-- Split partition of a temporary table when one of the partitions after
+-- split has the same name as the partition being split
+CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a);
+CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2);
+ALTER TABLE t SPLIT PARTITION tp_0 INTO
+ (PARTITION tp_0 FOR VALUES FROM (0) TO (1),
+ PARTITION tp_1 FOR VALUES FROM (1) TO (2));
+DROP TABLE t;
+
RESET search_path;
--