@@ -671,32 +671,34 @@ merge_range_partitions(PG_FUNCTION_ARGS)
671671}
672672
673673static void
674- merge_range_partitions_internal (Oid parent , Oid * parts , uint32 nparts )
674+ merge_range_partitions_internal (Oid parent_relid , Oid * parts , uint32 nparts )
675675{
676+ Oid partition_relid ;
676677 const PartRelationInfo * prel ;
677678 List * rentry_list = NIL ;
678679 RangeEntry * ranges ,
679680 * first ,
680681 * last ;
681682 FmgrInfo cmp_proc ;
682683 int i ;
684+ Bound min ,
685+ max ;
683686
684- prel = get_pathman_relation_info (parent );
685- shout_if_prel_is_invalid (parent , prel , PT_RANGE );
687+ prel = get_pathman_relation_info (parent_relid );
688+ shout_if_prel_is_invalid (parent_relid , prel , PT_RANGE );
686689
687690 /* Fetch ranges array */
688691 ranges = PrelGetRangesArray (prel );
689692
690693 /* Lock parent till transaction's end */
691- LockRelationOid (parent , ShareUpdateExclusiveLock );
694+ LockRelationOid (parent_relid , ShareUpdateExclusiveLock );
692695
693696 /* Process partitions */
694697 for (i = 0 ; i < nparts ; i ++ )
695698 {
696699 int j ;
697700
698- /* Prevent modification of partitions */
699- LockRelationOid (parts [0 ], AccessExclusiveLock );
701+ LockRelationOid (parts [i ], AccessShareLock );
700702
701703 /* Look for the specified partition */
702704 for (j = 0 ; j < PrelChildrenCount (prel ); j ++ )
@@ -724,38 +726,45 @@ merge_range_partitions_internal(Oid parent, Oid *parts, uint32 nparts)
724726 first = tmp ;
725727 }
726728
727- /* Drop old constraint and create a new one */
728- modify_range_constraint (parts [0 ],
729- prel -> expr_cstr ,
730- prel -> ev_type ,
731- & first -> min ,
732- & last -> max );
729+ /* We need to save bounds, they will be removed at invalidation */
730+ min = first -> min ;
731+ max = last -> max ;
733732
734- /* Make constraint visible */
733+ /* Create a new RANGE partition and return its Oid */
734+ partition_relid = create_single_range_partition_internal (parent_relid ,
735+ & min ,
736+ & max ,
737+ prel -> ev_type ,
738+ NULL ,
739+ NULL );
740+ /* Make new relation visible */
735741 CommandCounterIncrement ();
736742
737743 if (SPI_connect () != SPI_OK_CONNECT )
738744 elog (ERROR , "could not connect using SPI" );
739745
740- /* Migrate the data from all partition to the first one */
746+ /* Copy the data from all partition to the first one */
741747 for (i = 1 ; i < nparts ; i ++ )
742748 {
743- char * query = psprintf ( "WITH part_data AS ( "
744- "DELETE FROM %s RETURNING "
745- "*) "
746- "INSERT INTO %s SELECT * FROM part_data " ,
747- get_qualified_rel_name (parts [ i ] ),
748- get_qualified_rel_name (parts [0 ]));
749+ /* Prevent modification on relation */
750+ LockRelationOid ( parts [ i ], ShareLock );
751+
752+ char * query = psprintf ( "INSERT INTO %s SELECT * FROM %s " ,
753+ get_qualified_rel_name (partition_relid ),
754+ get_qualified_rel_name (parts [i ]));
749755
750756 SPI_exec (query , 0 );
751757 pfree (query );
752758 }
753759
754760 SPI_finish ();
755761
756- /* Drop obsolete partitions */
757- for (i = 1 ; i < nparts ; i ++ )
762+ /* Drop partitions */
763+ for (i = 0 ; i < nparts ; i ++ )
764+ {
765+ LockRelationOid (parts [i ], AccessExclusiveLock );
758766 drop_table_by_oid (parts [i ]);
767+ }
759768}
760769
761770
0 commit comments