index 680a50bf8b161bb37576efad4b962631a6d73f0e..4dd1341f606cb371ee6687f5098459017b9d08f5 100644 (file)
.index_build_range_scan = heapam_index_build_range_scan,
.index_validate_scan = heapam_index_validate_scan,
+ .free_rd_amcache = NULL,
.relation_size = table_block_relation_size,
.relation_needs_toast_table = heapam_relation_needs_toast_table,
.relation_toast_am = heapam_relation_toast_am,
index 2cd19d603fba7ce941e41f15d2fe231f62eca879..dcd18e462686c1581dcec4bb80ad9430420e502d 100644 (file)
RelationCloseSmgr(relation);
/* Must free any AM cached data upon relcache flush */
- if (relation->rd_amcache)
- pfree(relation->rd_amcache);
- relation->rd_amcache = NULL;
+ table_free_rd_amcache(relation);
/*
* If it's a shared index, we might be called before backend startup has
@@ -2484,8 +2482,7 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc)
pfree(relation->rd_options);
if (relation->rd_indextuple)
pfree(relation->rd_indextuple);
- if (relation->rd_amcache)
- pfree(relation->rd_amcache);
+ table_free_rd_amcache(relation);
if (relation->rd_fdwroutine)
pfree(relation->rd_fdwroutine);
if (relation->rd_indexcxt)
@@ -2547,9 +2544,7 @@ RelationClearRelation(Relation relation, bool rebuild)
RelationCloseSmgr(relation);
/* Free AM cached data, if any */
- if (relation->rd_amcache)
- pfree(relation->rd_amcache);
- relation->rd_amcache = NULL;
+ table_free_rd_amcache(relation);
/*
* Treat nailed-in system relations separately, they always need to be
index 8249b37bbf16266a4918a8787005395ce63beb2e..fd474b74883c6dcbc43daf0a4ef45af0176f0fe3 100644 (file)
* ------------------------------------------------------------------------
*/
+ /*
+ * This callback frees relation private cache data stored in rd_amcache.
+ * After the call all memory related to rd_amcache must be freed,
+ * rd_amcache must be set to NULL. If this callback is not provided,
+ * rd_amcache is assumed to point to a single memory chunk.
+ */
+ void (*free_rd_amcache) (Relation rel);
+
/*
* See table_relation_size().
*
* ----------------------------------------------------------------------------
*/
+/*
+ * Frees relation private cache data stored in rd_amcache. Uses
+ * free_rd_amcache method if provided. Assumes rd_amcache to point to single
+ * memory chunk otherwise.
+ */
+static inline void
+table_free_rd_amcache(Relation rel)
+{
+ if (rel->rd_tableam && rel->rd_tableam->free_rd_amcache)
+ {
+ rel->rd_tableam->free_rd_amcache(rel);
+
+ /*
+ * We are assuming free_rd_amcache() did clear the cache and left NULL
+ * in rd_amcache.
+ */
+ Assert(rel->rd_amcache == NULL);
+ }
+ else
+ {
+ if (rel->rd_amcache)
+ pfree(rel->rd_amcache);
+ rel->rd_amcache = NULL;
+ }
+}
+
/*
* Return the current size of `rel` in bytes. If `forkNumber` is
* InvalidForkNumber, return the relation's overall size, otherwise the size
index 87002049538a8990aa64a9814a4e3a88dd350eea..f25f769af2b2a0a7352dc957692d4a07874d59ba 100644 (file)
* rd_amcache is available for index and table AMs to cache private data
* about the relation. This must be just a cache since it may get reset
* at any time (in particular, it will get reset by a relcache inval
- * message for the relation). If used, it must point to a single memory
- * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index
- * relation. A relcache reset will include freeing that chunk and setting
- * rd_amcache = NULL.
+ * message for the relation). If used for table AM it must point to a
+ * single memory chunk palloc'd in CacheMemoryContext, or more complex
+ * data structure in that memory context to be freed by free_rd_amcache
+ * method. If used for index AM it must point to a single memory chunk
+ * palloc'd in rd_indexcxt memory context. A relcache reset will include
+ * freeing that chunk and setting rd_amcache = NULL.
*/
void *rd_amcache; /* available for use by index/table AM */