Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

attoptcache.c File Reference

#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"
Include dependency graph for attoptcache.c:

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)
AttributeOptsget_attribute_options (Oid attrelid, int attnum)

Variables

static HTABAttoptCacheHash = NULL

Function Documentation

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);
}

static void InvalidateAttoptCacheCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
) [static]

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");
    }
}


Variable Documentation

HTAB* AttoptCacheHash = NULL [static]

Definition at line 28 of file attoptcache.c.