4343#define CHILD_FACTOR 500
4444
4545
46+ /* Various memory contexts for caches */
47+ MemoryContext TopPathmanContext = NULL ;
48+ MemoryContext PathmanRelationCacheContext = NULL ;
49+ MemoryContext PathmanParentCacheContext = NULL ;
50+ MemoryContext PathmanCostraintCacheContext = NULL ;
51+
4652/* Storage for PartRelationInfos */
47- HTAB * partitioned_rels = NULL ;
53+ HTAB * partitioned_rels = NULL ;
4854
4955/* Storage for PartParentInfos */
50- HTAB * parent_cache = NULL ;
56+ HTAB * parent_cache = NULL ;
5157
5258/* Storage for partition constraints */
53- HTAB * constraint_cache = NULL ;
59+ HTAB * constraint_cache = NULL ;
5460
5561/* pg_pathman's init status */
5662PathmanInitState pg_pathman_init_state ;
@@ -210,7 +216,7 @@ load_config(void)
210216/* Validate pg_pathman's Pl/PgSQL facade (might be outdated) */
211217validate_sql_facade_version (get_sql_facade_version ());
212218
213- init_local_cache ();/* create'partitioned_rels' hashtable */
219+ init_local_cache ();/* createvarious hashtables (caches) */
214220read_pathman_config ();/* read PATHMAN_CONFIG table & fill cache */
215221
216222/* Register pathman_relcache_hook(), currently we can't unregister it */
@@ -307,18 +313,60 @@ init_local_cache(void)
307313hash_destroy (parent_cache );
308314hash_destroy (constraint_cache );
309315
316+ /* Reset pg_pathman's memory contexts */
317+ if (TopPathmanContext )
318+ {
319+ /* Check that child contexts exist */
320+ Assert (MemoryContextIsValid (PathmanRelationCacheContext ));
321+ Assert (MemoryContextIsValid (PathmanParentCacheContext ));
322+ Assert (MemoryContextIsValid (PathmanCostraintCacheContext ));
323+
324+ /* Clear children */
325+ MemoryContextResetChildren (TopPathmanContext );
326+ }
327+ /* Initialize pg_pathman's memory contexts */
328+ else
329+ {
330+ Assert (PathmanRelationCacheContext == NULL );
331+ Assert (PathmanParentCacheContext == NULL );
332+ Assert (PathmanCostraintCacheContext == NULL );
333+
334+ TopPathmanContext =
335+ AllocSetContextCreate (TopMemoryContext ,
336+ CppAsString (TopPathmanContext ),
337+ ALLOCSET_DEFAULT_SIZES );
338+
339+ /* For PartRelationInfo */
340+ PathmanRelationCacheContext =
341+ AllocSetContextCreate (TopPathmanContext ,
342+ CppAsString (PathmanRelationCacheContext ),
343+ ALLOCSET_DEFAULT_SIZES );
344+
345+ /* For PartParentInfo */
346+ PathmanParentCacheContext =
347+ AllocSetContextCreate (TopPathmanContext ,
348+ CppAsString (PathmanParentCacheContext ),
349+ ALLOCSET_DEFAULT_SIZES );
350+
351+ /* For PartConstraintInfo */
352+ PathmanCostraintCacheContext =
353+ AllocSetContextCreate (TopPathmanContext ,
354+ CppAsString (PathmanCostraintCacheContext ),
355+ ALLOCSET_DEFAULT_SIZES );
356+ }
357+
310358memset (& ctl ,0 ,sizeof (ctl ));
311359ctl .keysize = sizeof (Oid );
312360ctl .entrysize = sizeof (PartRelationInfo );
313- ctl .hcxt = TopMemoryContext ; /* place data to persistent mcxt */
361+ ctl .hcxt = PathmanRelationCacheContext ;
314362
315363partitioned_rels = hash_create ("pg_pathman's partitioned relations cache" ,
316364PART_RELS_SIZE ,& ctl ,HASH_ELEM |HASH_BLOBS );
317365
318366memset (& ctl ,0 ,sizeof (ctl ));
319367ctl .keysize = sizeof (Oid );
320368ctl .entrysize = sizeof (PartParentInfo );
321- ctl .hcxt = TopMemoryContext ; /* place data to persistent mcxt */
369+ ctl .hcxt = PathmanParentCacheContext ;
322370
323371parent_cache = hash_create ("pg_pathman's partition parents cache" ,
324372PART_RELS_SIZE * CHILD_FACTOR ,
@@ -327,7 +375,7 @@ init_local_cache(void)
327375memset (& ctl ,0 ,sizeof (ctl ));
328376ctl .keysize = sizeof (Oid );
329377ctl .entrysize = sizeof (PartConstraintInfo );
330- ctl .hcxt = TopMemoryContext ; /* place data to persistent mcxt */
378+ ctl .hcxt = PathmanCostraintCacheContext ;
331379
332380constraint_cache = hash_create ("pg_pathman's partition constraints cache" ,
333381PART_RELS_SIZE * CHILD_FACTOR ,
@@ -340,24 +388,17 @@ init_local_cache(void)
340388static void
341389fini_local_cache (void )
342390{
343- HASH_SEQ_STATUS status ;
344- PartRelationInfo * prel ;
345-
346- hash_seq_init (& status ,partitioned_rels );
347- while ((prel = (PartRelationInfo * )hash_seq_search (& status ))!= NULL )
348- {
349- if (PrelIsValid (prel ))
350- {
351- FreeChildrenArray (prel );
352- FreeRangesArray (prel );
353- }
354- }
355-
356- /* Now we can safely destroy hash tables */
391+ /* First, destroy hash tables */
357392hash_destroy (partitioned_rels );
358393hash_destroy (parent_cache );
359- partitioned_rels = NULL ;
360- parent_cache = NULL ;
394+ hash_destroy (constraint_cache );
395+
396+ partitioned_rels = NULL ;
397+ parent_cache = NULL ;
398+ constraint_cache = NULL ;
399+
400+ /* Now we can clear allocations */
401+ MemoryContextResetChildren (TopPathmanContext );
361402}
362403
363404/*
@@ -371,7 +412,7 @@ fill_prel_with_partitions(const Oid *partitions,
371412{
372413uint32 i ;
373414Expr * con_expr ;
374- MemoryContext mcxt = TopMemoryContext ;
415+ MemoryContext mcxt = PathmanRelationCacheContext ;
375416
376417/* Allocate memory for 'prel->children' & 'prel->ranges' (if needed) */
377418prel -> children = MemoryContextAllocZero (mcxt ,parts_count * sizeof (Oid ));
@@ -474,7 +515,7 @@ fill_prel_with_partitions(const Oid *partitions,
474515prel -> children [i ]= prel -> ranges [i ].child_oid ;
475516
476517/* Copy all min & max Datums to the persistent mcxt */
477- old_mcxt = MemoryContextSwitchTo (TopMemoryContext );
518+ old_mcxt = MemoryContextSwitchTo (PathmanRelationCacheContext );
478519for (i = 0 ;i < PrelChildrenCount (prel );i ++ )
479520{
480521prel -> ranges [i ].min = CopyBound (& prel -> ranges [i ].min ,