#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.
1.7.1