PostgreSQL Source Code git master
Loading...
Searching...
No Matches
attoptcache.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * attoptcache.c
4 * Attribute options cache management.
5 *
6 * Attribute options are cached separately from the fixed-size portion of
7 * pg_attribute entries, which are handled by the relcache.
8 *
9 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
11 *
12 * IDENTIFICATION
13 * src/backend/utils/cache/attoptcache.c
14 *
15 *-------------------------------------------------------------------------
16 */
17#include "postgres.h"
18
19#include "access/reloptions.h"
20#include "utils/attoptcache.h"
21#include "utils/catcache.h"
22#include "utils/hsearch.h"
23#include "utils/inval.h"
24#include "utils/syscache.h"
25#include "varatt.h"
26
27
28/* Hash table for information about each attribute's options */
30
31/* attrelid and attnum form the lookup key, and must appear first */
32typedef struct
33{
35 int attnum;
37
38typedef struct
39{
40 AttoptCacheKey key; /* lookup key - must be first */
41 AttributeOpts *opts; /* options, or NULL if none */
43
44
45/*
46 * InvalidateAttoptCacheCallback
47 * Flush cache entry (or entries) when pg_attribute is updated.
48 *
49 * When pg_attribute is updated, we must flush the cache entry at least
50 * for that attribute.
51 */
52static void
54 uint32 hashvalue)
55{
56 HASH_SEQ_STATUS status;
58
59 /*
60 * By convention, zero hash value is passed to the callback as a sign that
61 * it's time to invalidate the whole cache. See sinval.c, inval.c and
62 * InvalidateSystemCachesExtended().
63 */
64 if (hashvalue == 0)
66 else
68
69 while ((attopt = (AttoptCacheEntry *) hash_seq_search(&status)) != NULL)
70 {
71 if (attopt->opts)
72 pfree(attopt->opts);
74 &attopt->key,
76 NULL) == NULL)
77 elog(ERROR, "hash table corrupted");
78 }
79}
80
81/*
82 * Hash function compatible with two-arg system cache hash function.
83 */
84static uint32
85relatt_cache_syshash(const void *key, Size keysize)
86{
87 const AttoptCacheKey *ckey = key;
88
89 Assert(keysize == sizeof(*ckey));
91}
92
93/*
94 * InitializeAttoptCache
95 * Initialize the attribute options cache.
96 */
97static void
99{
100 HASHCTL ctl;
101
102 /* Initialize the hash table. */
103 ctl.keysize = sizeof(AttoptCacheKey);
104 ctl.entrysize = sizeof(AttoptCacheEntry);
105
106 /*
107 * AttoptCacheEntry takes hash value from the system cache. For
108 * AttoptCacheHash we use the same hash in order to speedup search by hash
109 * value. This is used by hash_seq_init_with_hash_value().
110 */
112
114 hash_create("Attopt cache", 256, &ctl,
116
117 /* Make sure we've initialized CacheMemoryContext. */
120
121 /* Watch for invalidation events. */
124 (Datum) 0);
125}
126
127/*
128 * get_attribute_options
129 * Fetch attribute options for a specified table OID.
130 */
133{
134 AttoptCacheKey key;
136 AttributeOpts *result;
137 HeapTuple tp;
138
139 /* Find existing cache entry, if any. */
140 if (!AttoptCacheHash)
142 memset(&key, 0, sizeof(key)); /* make sure any padding bits are unset */
143 key.attrelid = attrelid;
144 key.attnum = attnum;
145 attopt =
147 &key,
148 HASH_FIND,
149 NULL);
150
151 /* Not found in Attopt cache. Construct new cache entry. */
152 if (!attopt)
153 {
155
157 ObjectIdGetDatum(attrelid),
159
160 /*
161 * If we don't find a valid HeapTuple, it must mean someone has
162 * managed to request attribute details for a non-existent attribute.
163 * We treat that case as if no options were specified.
164 */
165 if (!HeapTupleIsValid(tp))
166 opts = NULL;
167 else
168 {
169 Datum datum;
170 bool isNull;
171
172 datum = SysCacheGetAttr(ATTNUM,
173 tp,
175 &isNull);
176 if (isNull)
177 opts = NULL;
178 else
179 {
180 bytea *bytea_opts = attribute_reloptions(datum, false);
181
185 }
186 ReleaseSysCache(tp);
187 }
188
189 /*
190 * It's important to create the actual cache entry only after reading
191 * pg_attribute, since the read could cause a cache flush.
192 */
194 &key,
196 NULL);
197 attopt->opts = opts;
198 }
199
200 /* Return results in caller's memory context. */
201 if (attopt->opts == NULL)
202 return NULL;
203 result = palloc(VARSIZE(attopt->opts));
204 memcpy(result, attopt->opts, VARSIZE(attopt->opts));
205 return result;
206}
static uint32 relatt_cache_syshash(const void *key, Size keysize)
Definition attoptcache.c:85
AttributeOpts * get_attribute_options(Oid attrelid, int attnum)
static HTAB * AttoptCacheHash
Definition attoptcache.c:29
static void InvalidateAttoptCacheCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition attoptcache.c:53
static void InitializeAttoptCache(void)
Definition attoptcache.c:98
#define Assert(condition)
Definition c.h:885
uint32_t uint32
Definition c.h:558
size_t Size
Definition c.h:631
void CreateCacheMemoryContext(void)
Definition catcache.c:715
void hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status, HTAB *hashp, uint32 hashvalue)
Definition dynahash.c:1400
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:952
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
Definition dynahash.c:358
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition dynahash.c:1415
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition dynahash.c:1380
Datum arg
Definition elog.c:1322
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
@ HASH_FIND
Definition hsearch.h:113
@ HASH_REMOVE
Definition hsearch.h:115
@ HASH_ENTER
Definition hsearch.h:114
#define HASH_ELEM
Definition hsearch.h:95
#define HASH_FUNCTION
Definition hsearch.h:98
#define HeapTupleIsValid(tuple)
Definition htup.h:78
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CacheMemoryContext
Definition mcxt.c:169
static AmcheckOptions opts
Definition pg_amcheck.c:112
int16 attnum
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
unsigned int Oid
static int fb(int x)
tree ctl
Definition radixtree.h:1838
bytea * attribute_reloptions(Datum reloptions, bool validate)
AttributeOpts * opts
Definition attoptcache.c:41
AttoptCacheKey key
Definition attoptcache.c:40
Size keysize
Definition hsearch.h:75
Definition c.h:718
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
#define GetSysCacheHashValue2(cacheId, key1, key2)
Definition syscache.h:120
static Size VARSIZE(const void *PTR)
Definition varatt.h:298