#include "postgres.h"
#include "access/reloptions.h"
#include "utils/attoptcache.h"
#include "utils/catcache.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/syscache.h"
Go to the source code of this file.
Data Structures | |
struct | AttoptCacheKey |
struct | AttoptCacheEntry |
Functions | |
static void | InvalidateAttoptCacheCallback (Datum arg, int cacheid, uint32 hashvalue) |
static void | InitializeAttoptCache (void) |
AttributeOpts * | get_attribute_options (Oid attrelid, int attnum) |
Variables | |
static HTAB * | AttoptCacheHash = NULL |
AttributeOpts* get_attribute_options | ( | Oid | attrelid, | |
int | attnum | |||
) |
Definition at line 105 of file attoptcache.c.
References Anum_pg_attribute_attoptions, ATTNUM, AttoptCacheKey::attnum, AttoptCacheKey::attrelid, attribute_reloptions(), CacheMemoryContext, hash_search(), HeapTupleIsValid, InitializeAttoptCache(), Int16GetDatum, MemoryContextAlloc(), NULL, ObjectIdGetDatum, AttoptCacheEntry::opts, palloc(), ReleaseSysCache(), SearchSysCache2, SysCacheGetAttr(), and VARSIZE.
Referenced by compute_index_stats(), and do_analyze_rel().
{ AttoptCacheKey key; AttoptCacheEntry *attopt; AttributeOpts *result; HeapTuple tp; /* Find existing cache entry, if any. */ if (!AttoptCacheHash) InitializeAttoptCache(); memset(&key, 0, sizeof(key)); /* make sure any padding bits are * unset */ key.attrelid = attrelid; key.attnum = attnum; attopt = (AttoptCacheEntry *) hash_search(AttoptCacheHash, (void *) &key, HASH_FIND, NULL); /* Not found in Attopt cache. Construct new cache entry. */ if (!attopt) { AttributeOpts *opts; tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(attrelid), Int16GetDatum(attnum)); /* * If we don't find a valid HeapTuple, it must mean someone has * managed to request attribute details for a non-existent attribute. * We treat that case as if no options were specified. */ if (!HeapTupleIsValid(tp)) opts = NULL; else { Datum datum; bool isNull; datum = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attoptions, &isNull); if (isNull) opts = NULL; else { bytea *bytea_opts = attribute_reloptions(datum, false); opts = MemoryContextAlloc(CacheMemoryContext, VARSIZE(bytea_opts)); memcpy(opts, bytea_opts, VARSIZE(bytea_opts)); } ReleaseSysCache(tp); } /* * It's important to create the actual cache entry only after reading * pg_attribute, since the read could cause a cache flush. */ attopt = (AttoptCacheEntry *) hash_search(AttoptCacheHash, (void *) &key, HASH_ENTER, NULL); attopt->opts = opts; } /* Return results in caller's memory context. */ if (attopt->opts == NULL) return NULL; result = palloc(VARSIZE(attopt->opts)); memcpy(result, attopt->opts, VARSIZE(attopt->opts)); return result; }
static void InitializeAttoptCache | ( | void | ) | [static] |
Definition at line 77 of file attoptcache.c.
References ATTNUM, CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), HASHCTL::entrysize, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, InvalidateAttoptCacheCallback(), HASHCTL::keysize, and MemSet.
Referenced by get_attribute_options().
{ HASHCTL ctl; /* Initialize the hash table. */ MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(AttoptCacheKey); ctl.entrysize = sizeof(AttoptCacheEntry); ctl.hash = tag_hash; AttoptCacheHash = hash_create("Attopt cache", 256, &ctl, HASH_ELEM | HASH_FUNCTION); /* Make sure we've initialized CacheMemoryContext. */ if (!CacheMemoryContext) CreateCacheMemoryContext(); /* Watch for invalidation events. */ CacheRegisterSyscacheCallback(ATTNUM, InvalidateAttoptCacheCallback, (Datum) 0); }
Definition at line 54 of file attoptcache.c.
References elog, ERROR, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), AttoptCacheEntry::key, NULL, AttoptCacheEntry::opts, and pfree().
Referenced by InitializeAttoptCache().
{ HASH_SEQ_STATUS status; AttoptCacheEntry *attopt; hash_seq_init(&status, AttoptCacheHash); while ((attopt = (AttoptCacheEntry *) hash_seq_search(&status)) != NULL) { if (attopt->opts) pfree(attopt->opts); if (hash_search(AttoptCacheHash, (void *) &attopt->key, HASH_REMOVE, NULL) == NULL) elog(ERROR, "hash table corrupted"); } }
HTAB* AttoptCacheHash = NULL [static] |
Definition at line 28 of file attoptcache.c.