mirror of
https://github.com/postgres/postgres.git
synced 2025-06-18 00:02:37 -04:00
Fix several oversights in previous commit - attribute options patch.
I failed to 'cvs add' the new files and also neglected to bump catversion.
This commit is contained in:
parent
76a47c0e74
commit
d779199175
181
src/backend/utils/cache/attoptcache.c
vendored
Normal file
181
src/backend/utils/cache/attoptcache.c
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* attoptcache.c
|
||||
* Attribute options cache management.
|
||||
*
|
||||
* Attribute options are cached separately from the fixed-size portion of
|
||||
* pg_attribute entries, which are handled by the relcache.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/attoptcache.c,v 1.1 2010/01/22 16:42:31 rhaas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/reloptions.h"
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "utils/attoptcache.h"
|
||||
#include "utils/catcache.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/* Hash table for informations about each attribute's options */
|
||||
static HTAB *AttoptCacheHash = NULL;
|
||||
|
||||
/* attrelid and attnum form the lookup key, and must appear first */
|
||||
typedef struct
|
||||
{
|
||||
Oid attrelid;
|
||||
int attnum;
|
||||
} AttoptCacheKey;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AttoptCacheKey key; /* lookup key - must be first */
|
||||
AttributeOpts *opts; /* options, or NULL if none */
|
||||
} AttoptCacheEntry;
|
||||
|
||||
|
||||
/*
|
||||
* InvalidateAttoptCacheCallback
|
||||
* Flush all cache entries when pg_attribute is updated.
|
||||
*
|
||||
* When pg_attribute is updated, we must flush the cache entry at least
|
||||
* for that attribute. Currently, we just flush them all. Since attribute
|
||||
* options are not currently used in performance-critical paths (such as
|
||||
* query execution), this seems OK.
|
||||
*/
|
||||
static void
|
||||
InvalidateAttoptCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* InitializeAttoptCache
|
||||
* Initialize the tablespace cache.
|
||||
*/
|
||||
static void
|
||||
InitializeAttoptCache(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_attribute_options
|
||||
* Fetch attribute options for a specified table OID.
|
||||
*/
|
||||
AttributeOpts *
|
||||
get_attribute_options(Oid attrelid, int attnum)
|
||||
{
|
||||
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 = SearchSysCache(ATTNUM,
|
||||
ObjectIdGetDatum(attrelid),
|
||||
Int16GetDatum(attnum),
|
||||
0, 0);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.577 2010/01/22 15:45:15 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.578 2010/01/22 16:42:31 rhaas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 201001221
|
||||
#define CATALOG_VERSION_NO 201001222
|
||||
|
||||
#endif
|
||||
|
28
src/include/utils/attoptcache.h
Normal file
28
src/include/utils/attoptcache.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* attoptcache.h
|
||||
* Attribute options cache.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/attoptcache.h,v 1.1 2010/01/22 16:42:31 rhaas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SPCCACHE_H
|
||||
#define SPCCACHE_H
|
||||
|
||||
/*
|
||||
* Attribute options.
|
||||
*/
|
||||
typedef struct AttributeOpts
|
||||
{
|
||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||
float8 n_distinct;
|
||||
float8 n_distinct_inherited;
|
||||
} AttributeOpts;
|
||||
|
||||
AttributeOpts *get_attribute_options(Oid spcid, int attnum);
|
||||
|
||||
#endif /* SPCCACHE_H */
|
Loading…
x
Reference in New Issue
Block a user