Hi!

18.04.2024 19:00, Alexander Lakhin wrote:
leaves a strange constraint:
\d+ t*
                                           Table "public.tp_0"
...
Not-null constraints:
     "merge-16385-26BCB0-tmp_i_not_null" NOT NULL "i"

Thanks!
Attached fix (with test) for this case.
The patch should be applied after patches
v6-0001- ... .patch ... v6-0004- ... .patch

--
With best regards,
Dmitry Koval

Postgres Professional: http://postgrespro.com
From 58e4b7fb1d3b15cdf1c742c28690392dda34915d Mon Sep 17 00:00:00 2001
From: Koval Dmitry <d.ko...@postgrespro.ru>
Date: Fri, 19 Apr 2024 01:57:49 +0300
Subject: [PATCH v6] Fix

---
 src/backend/commands/tablecmds.c              | 49 ++++++-------------
 src/test/regress/expected/partition_merge.out | 13 ++++-
 src/test/regress/sql/partition_merge.sql      |  8 ++-
 3 files changed, 33 insertions(+), 37 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 72874295cb..8985747180 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -21508,9 +21508,6 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo 
*tab, Relation rel,
        ListCell   *listptr;
        List       *mergingPartitionsList = NIL;
        Oid                     defaultPartOid;
-       char            tmpRelName[NAMEDATALEN];
-       RangeVar   *mergePartName = cmd->name;
-       bool            isSameName = false;
 
        /*
         * Lock all merged partitions, check them and create list with 
partitions
@@ -21532,8 +21529,22 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo 
*tab, Relation rel,
                 * function transformPartitionCmdForMerge().
                 */
                if (equal(name, cmd->name))
+               {
                        /* One new partition can have the same name as merged 
partition. */
-                       isSameName = true;
+                       char            tmpRelName[NAMEDATALEN];
+
+                       /* Generate temporary name. */
+                       sprintf(tmpRelName, "merge-%u-%X-tmp", 
RelationGetRelid(rel), MyProcPid);
+
+                       /* Rename partition. */
+                       
RenameRelationInternal(RelationGetRelid(mergingPartition),
+                                                                  tmpRelName, 
false, false);
+                       /*
+                        * We must bump the command counter to make the new 
partition tuple
+                        * visible for rename.
+                        */
+                       CommandCounterIncrement();
+               }
 
                /* Store a next merging partition into the list. */
                mergingPartitionsList = lappend(mergingPartitionsList,
@@ -21553,16 +21564,8 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo 
*tab, Relation rel,
                DetachPartitionFinalize(rel, mergingPartition, false, 
defaultPartOid);
        }
 
-       /* Create table for new partition, use partitioned table as model. */
-       if (isSameName)
-       {
-               /* Create partition table with generated temporary name. */
-               sprintf(tmpRelName, "merge-%u-%X-tmp", RelationGetRelid(rel), 
MyProcPid);
-               mergePartName = makeRangeVar(cmd->name->schemaname, tmpRelName, 
-1);
-       }
-
        newPartRel = createPartitionTable(rel,
-                                                                         
mergePartName,
+                                                                         
cmd->name,
                                                                          
makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
                                                                                
                   RelationGetRelationName(rel), -1),
                                                                          
context);
@@ -21588,26 +21591,6 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo 
*tab, Relation rel,
        }
        list_free(mergingPartitionsList);
 
-       /* Rename new partition if it is needed. */
-       if (isSameName)
-       {
-               /*
-                * We must bump the command counter to make the new partition 
tuple
-                * visible for rename.
-                */
-               CommandCounterIncrement();
-
-               /* Rename partition. */
-               RenameRelationInternal(RelationGetRelid(newPartRel),
-                                                          cmd->name->relname, 
false, false);
-
-               /*
-                * Bump the command counter to make the tuple of renamed 
partition
-                * visible for attach partition operation.
-                */
-               CommandCounterIncrement();
-       }
-
        /*
         * Attach a new partition to the partitioned table. wqueue = NULL:
         * verification for each cloned constraint is not needed.
diff --git a/src/test/regress/expected/partition_merge.out 
b/src/test/regress/expected/partition_merge.out
index b5744ed498..2499a314fb 100644
--- a/src/test/regress/expected/partition_merge.out
+++ b/src/test/regress/expected/partition_merge.out
@@ -779,17 +779,26 @@ DROP TABLE t;
 -- Check the partition index name if the partition name is the same as one
 -- of the merged partitions.
 --
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
+CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
 CREATE INDEX tidx ON t(i);
 ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2;
--- Indexname value should be 'tp_1_2_i_idx'.
+-- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'.
 SELECT indexname FROM pg_indexes
 WHERE tablename = 'tp_1_2' AND schemaname = 'partitions_merge_schema';
   indexname   
 --------------
+ tp_1_2_pkey
  tp_1_2_i_idx
+(2 rows)
+
+-- Conname value should be 'tp_1_2_i_not_null'.
+SELECT conname FROM pg_constraint
+WHERE conrelid='tp_1_2'::regclass AND contype='n';
+      conname      
+-------------------
+ tp_1_2_i_not_null
 (1 row)
 
 DROP TABLE t;
diff --git a/src/test/regress/sql/partition_merge.sql 
b/src/test/regress/sql/partition_merge.sql
index df737e214e..6614512f69 100644
--- a/src/test/regress/sql/partition_merge.sql
+++ b/src/test/regress/sql/partition_merge.sql
@@ -470,7 +470,7 @@ DROP TABLE t;
 -- Check the partition index name if the partition name is the same as one
 -- of the merged partitions.
 --
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
+CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i);
 
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
@@ -478,10 +478,14 @@ CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO 
(2);
 CREATE INDEX tidx ON t(i);
 ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2;
 
--- Indexname value should be 'tp_1_2_i_idx'.
+-- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'.
 SELECT indexname FROM pg_indexes
 WHERE tablename = 'tp_1_2' AND schemaname = 'partitions_merge_schema';
 
+-- Conname value should be 'tp_1_2_i_not_null'.
+SELECT conname FROM pg_constraint
+WHERE conrelid='tp_1_2'::regclass AND contype='n';
+
 DROP TABLE t;
 
 --
-- 
2.40.1.windows.1

Reply via email to