aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c62
1 files changed, 51 insertions, 11 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. */