0003-Allow-table-AM-to-store-complex-data-structures-i-v1.patch
application/octet-stream
Filename: 0003-Allow-table-AM-to-store-complex-data-structures-i-v1.patch
Type: application/octet-stream
Part: 2
Message:
Table AM Interface Enhancements
Patch
Format: format-patch
Series: patch v1-0003
Subject: Allow table AM to store complex data structures in rd_amcache
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam_handler.c | 1 | 0 |
| src/backend/utils/cache/relcache.c | 10 | 8 |
| src/include/access/tableam.h | 27 | 0 |
| src/include/utils/rel.h | 6 | 4 |
From e48a79f6d35b4bf797d372aba69e51b5b34513e9 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Wed, 7 Jun 2023 13:04:58 +0300
Subject: [PATCH 03/12] Allow table AM to store complex data structures in
rd_amcache
New table AM method free_rd_amcache is responsible for freeing the rd_amcache.
---
src/backend/access/heap/heapam_handler.c | 1 +
src/backend/utils/cache/relcache.c | 18 +++++++++-------
src/include/access/tableam.h | 27 ++++++++++++++++++++++++
src/include/utils/rel.h | 10 +++++----
4 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index f9bba734899..29cf023b274 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -2642,6 +2642,7 @@ static const TableAmRoutine heapam_methods = {
.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,
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index b3faccbefe5..c802f33ac59 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -319,6 +319,7 @@ static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
StrategyNumber numSupport);
static void RelationCacheInitFileRemoveInDir(const char *tblspcpath);
static void unlink_initfile(const char *initfilename, int elevel);
+static void release_rd_amcache(Relation rel);
/*
@@ -2263,9 +2264,7 @@ RelationReloadIndexInfo(Relation relation)
RelationCloseSmgr(relation);
/* Must free any AM cached data upon relcache flush */
- if (relation->rd_amcache)
- pfree(relation->rd_amcache);
- relation->rd_amcache = NULL;
+ release_rd_amcache(relation);
/*
* If it's a shared index, we might be called before backend startup has
@@ -2485,8 +2484,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);
+ release_rd_amcache(relation);
if (relation->rd_fdwroutine)
pfree(relation->rd_fdwroutine);
if (relation->rd_indexcxt)
@@ -2548,9 +2546,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;
+ release_rd_amcache(relation);
/*
* Treat nailed-in system relations separately, they always need to be
@@ -6873,3 +6869,9 @@ ResOwnerReleaseRelation(Datum res)
RelationCloseCleanup((Relation) res);
}
+
+static void
+release_rd_amcache(Relation rel)
+{
+ table_free_rd_amcache(rel);
+}
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 774e8b66d4c..d5972d7a580 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -715,6 +715,13 @@ typedef struct TableAmRoutine
* ------------------------------------------------------------------------
*/
+ /*
+ * This callback frees relation private cache data stored in rd_amcache.
+ * If this callback is not provided, rd_amcache is assumed to point to
+ * single memory chunk.
+ */
+ void (*free_rd_amcache) (Relation rel);
+
/*
* See table_relation_size().
*
@@ -1883,6 +1890,26 @@ table_index_validate_scan(Relation table_rel,
* ----------------------------------------------------------------------------
*/
+/*
+ * 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);
+ }
+ 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
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 0ad613c4b88..7ec7a9e2805 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -220,10 +220,12 @@ typedef struct RelationData
* 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 */
--
2.39.3 (Apple Git-145)