29
29
#include "utils/lsyscache.h"
30
30
#include "utils/numeric.h"
31
31
#include "utils/ruleutils.h"
32
+ #include "utils/snapmgr.h"
32
33
#include "utils/syscache.h"
33
34
34
35
#if PG_VERSION_NUM >= 100000
@@ -72,10 +73,11 @@ static void modify_range_constraint(Oid partition_relid,
72
73
const Bound * lower ,
73
74
const Bound * upper );
74
75
static char * get_qualified_rel_name (Oid relid );
75
- static void drop_table_by_oid (Oid relid );
76
+ static void drop_table_by_oid (Oid relid , bool concurrent );
76
77
static bool interval_is_trivial (Oid atttype ,
77
78
Datum interval ,
78
79
Oid interval_type );
80
+ static void remove_inheritance (Oid parent_relid , Oid partition_relid );
79
81
80
82
81
83
/*
@@ -737,19 +739,25 @@ merge_range_partitions_internal(Oid parent_relid, Oid *parts, uint32 nparts)
737
739
prel -> ev_type ,
738
740
NULL ,
739
741
NULL );
742
+
743
+ /* should be invalidated */
744
+ //Assert(!prel->valid);
745
+
740
746
/* Make new relation visible */
741
747
CommandCounterIncrement ();
742
748
743
749
if (SPI_connect () != SPI_OK_CONNECT )
744
750
elog (ERROR , "could not connect using SPI" );
745
751
746
752
/* Copy the data from all partition to the first one */
747
- for (i = 1 ; i < nparts ; i ++ )
753
+ for (i = 0 ; i < nparts ; i ++ )
748
754
{
755
+ char * query ;
756
+
749
757
/* Prevent modification on relation */
750
758
LockRelationOid (parts [i ], ShareLock );
751
759
752
- char * query = psprintf ("INSERT INTO %s SELECT * FROM %s" ,
760
+ query = psprintf ("INSERT INTO %s SELECT * FROM %s" ,
753
761
get_qualified_rel_name (partition_relid ),
754
762
get_qualified_rel_name (parts [i ]));
755
763
@@ -759,11 +767,22 @@ merge_range_partitions_internal(Oid parent_relid, Oid *parts, uint32 nparts)
759
767
760
768
SPI_finish ();
761
769
762
- /* Drop partitions */
770
+ /*
771
+ * Now detach these partitions.
772
+ * this would get AccessExclusiveLock.
773
+ */
774
+ for (i = 0 ; i < nparts ; i ++ )
775
+ remove_inheritance (parent_relid , parts [i ]);
776
+
777
+ /* Now we can drop the partitions */
763
778
for (i = 0 ; i < nparts ; i ++ )
764
779
{
780
+ /*
781
+ * we should get AccessExclusiveLock anyway, because logic of
782
+ * ALTER TABLE .. NO INHERIT that we did before could change
783
+ */
765
784
LockRelationOid (parts [i ], AccessExclusiveLock );
766
- drop_table_by_oid (parts [i ]);
785
+ drop_table_by_oid (parts [i ], false );
767
786
}
768
787
}
769
788
@@ -825,7 +844,7 @@ drop_range_partition_expand_next(PG_FUNCTION_ARGS)
825
844
}
826
845
827
846
/* Finally drop this partition */
828
- drop_table_by_oid (relid );
847
+ drop_table_by_oid (relid , false );
829
848
830
849
PG_RETURN_VOID ();
831
850
}
@@ -1244,7 +1263,7 @@ get_qualified_rel_name(Oid relid)
1244
1263
* Drop table using it's Oid
1245
1264
*/
1246
1265
static void
1247
- drop_table_by_oid (Oid relid )
1266
+ drop_table_by_oid (Oid relid , bool concurrent )
1248
1267
{
1249
1268
DropStmt * n = makeNode (DropStmt );
1250
1269
const char * relname = get_qualified_rel_name (relid );
@@ -1256,7 +1275,30 @@ drop_table_by_oid(Oid relid)
1256
1275
n -> arguments = NIL ;
1257
1276
#endif
1258
1277
n -> behavior = DROP_RESTRICT ; /* default behavior */
1259
- n -> concurrent = false ;
1278
+ n -> concurrent = concurrent ;
1260
1279
1261
1280
RemoveRelations (n );
1262
1281
}
1282
+
1283
+ /* Remove inheritance for partition */
1284
+ static void
1285
+ remove_inheritance (Oid parent_relid , Oid partition_relid )
1286
+ {
1287
+ AlterTableStmt * stmt = makeNode (AlterTableStmt );
1288
+ AlterTableCmd * cmd = makeNode (AlterTableCmd );
1289
+ LOCKMODE lockmode ;
1290
+
1291
+ stmt -> relation = makeRangeVarFromNameList (
1292
+ stringToQualifiedNameList (get_qualified_rel_name (partition_relid )));
1293
+ stmt -> relkind = OBJECT_TABLE ;
1294
+ stmt -> cmds = list_make1 (cmd );
1295
+ stmt -> missing_ok = false;
1296
+
1297
+ cmd -> subtype = AT_DropInherit ;
1298
+ cmd -> def = (Node * ) makeRangeVarFromNameList (
1299
+ stringToQualifiedNameList (get_qualified_rel_name (parent_relid )));
1300
+
1301
+ lockmode = AlterTableGetLockLevel (stmt -> cmds );
1302
+ LockRelationOid (partition_relid , lockmode );
1303
+ AlterTable (partition_relid , lockmode , stmt );
1304
+ }
0 commit comments