35 #include "utils/fmgroids.h"
50 #define HASH_INDEX(h, sz) ((Index) ((h) & ((sz) - 1)))
58 #define CACHE_elog(...) elog(__VA_ARGS__)
60 #define CACHE_elog(...)
83 const Datum *cachekeys,
84 const Datum *searchkeys);
87 static void CatCachePrintStats(
int code,
Datum arg);
237 case REGPROCEDUREOID:
242 case REGCOLLATIONOID:
244 case REGDICTIONARYOID:
246 case REGNAMESPACEOID:
254 *eqfunc = F_OIDVECTOREQ;
257 elog(
FATAL,
"type %u not supported as catcache key", keytype);
284 oneHash = (cc_hashfunc[3]) (v4);
288 oneHash = (cc_hashfunc[2]) (v3);
292 oneHash = (cc_hashfunc[1]) (v2);
296 oneHash = (cc_hashfunc[0]) (v1);
297 hashValue ^= oneHash;
300 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
355 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
369 const Datum *cachekeys,
370 const Datum *searchkeys)
375 for (
i = 0;
i < nkeys;
i++)
377 if (!(cc_fastequal[
i]) (cachekeys[
i], searchkeys[
i]))
384 #ifdef CATCACHE_STATS
387 CatCachePrintStats(
int code,
Datum arg)
390 long cc_searches = 0;
392 long cc_neg_hits = 0;
393 long cc_newloads = 0;
395 long cc_lsearches = 0;
402 if (cache->
cc_ntup == 0 && cache->cc_searches == 0)
404 elog(
DEBUG2,
"catcache %s/%u: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lsrch, %ld lhits",
411 cache->cc_hits + cache->cc_neg_hits,
413 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits - cache->cc_newloads,
414 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits,
418 cc_searches += cache->cc_searches;
419 cc_hits += cache->cc_hits;
420 cc_neg_hits += cache->cc_neg_hits;
421 cc_newloads += cache->cc_newloads;
422 cc_invals += cache->cc_invals;
423 cc_lsearches += cache->cc_lsearches;
424 cc_lhits += cache->cc_lhits;
426 elog(
DEBUG2,
"catcache totals: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lsrch, %ld lhits",
431 cc_hits + cc_neg_hits,
433 cc_searches - cc_hits - cc_neg_hits - cc_newloads,
434 cc_searches - cc_hits - cc_neg_hits,
509 #ifndef CATCACHE_FORCE_RELEASE
592 #ifdef CATCACHE_STATS
622 "CacheMemoryContext",
670 #ifdef CATCACHE_STATS
746 #define InitCatCache_DEBUG2 \
748 elog(DEBUG2, "InitCatCache: rel=%u ind=%u id=%d nkeys=%d size=%d", \
749 cp->cc_reloid, cp->cc_indexoid, cp->id, \
750 cp->cc_nkeys, cp->cc_nbuckets); \
753 #define InitCatCache_DEBUG2
779 Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
798 #ifdef CATCACHE_STATS
827 for (
i = 0;
i < nkeys; ++
i)
859 elog(
DEBUG1,
"rehashing catalog cache id %d for %s; %d tups, %d buckets",
895 #define CatalogCacheInitializeCache_DEBUG1 \
896 elog(DEBUG2, "CatalogCacheInitializeCache: cache @%p rel=%u", cache, \
899 #define CatalogCacheInitializeCache_DEBUG2 \
901 if (cache->cc_keyno[i] > 0) { \
902 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d, %u", \
903 i+1, cache->cc_nkeys, cache->cc_keyno[i], \
904 TupleDescAttr(tupdesc, cache->cc_keyno[i] - 1)->atttypid); \
906 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d", \
907 i+1, cache->cc_nkeys, cache->cc_keyno[i]); \
911 #define CatalogCacheInitializeCache_DEBUG1
912 #define CatalogCacheInitializeCache_DEBUG2
972 keytype = attr->atttypid;
979 elog(
FATAL,
"sys attributes are not supported in caches");
1218 #ifdef CATCACHE_STATS
1219 cache->cc_searches++;
1275 #ifdef CATCACHE_STATS
1286 #ifdef CATCACHE_STATS
1287 cache->cc_neg_hits++;
1366 hashValue, hashIndex,
1395 hashValue, hashIndex,
1416 #ifdef CATCACHE_STATS
1417 cache->cc_newloads++;
1448 #ifndef CATCACHE_FORCE_RELEASE
1513 List *
volatile ctlist;
1527 Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1529 #ifdef CATCACHE_STATS
1530 cache->cc_lsearches++;
1565 if (cl->
nkeys != nkeys)
1588 #ifdef CATCACHE_STATS
1635 ordered = (scandesc->
irel != NULL);
1680 hashValue, hashIndex,
1715 foreach(ctlist_item, ctlist)
1722 #ifndef CATCACHE_FORCE_RELEASE
1744 foreach(ctlist_item, ctlist)
1785 #ifndef CATCACHE_FORCE_RELEASE
1788 list->refcount == 0)
1830 MAXIMUM_ALIGNOF + dtp->
t_len);
1838 (
const char *) dtp->
t_data,
1909 for (
i = 0;
i < nkeys;
i++)
1940 for (
i = 0;
i < nkeys;
i++)
1953 if (att->atttypid == NAMEOID)
2044 (*function) (ccp->
id, hashvalue, dbid);
2052 if (newhashvalue != hashvalue)
2053 (*function) (ccp->
id, newhashvalue, dbid);
2072 elog(
WARNING,
"cache reference leak: cache %s (%d), tuple %u/%u has count %d",
2082 elog(
WARNING,
"cache reference leak: cache %s (%d), list %p has count %d",
2083 list->my_cache->cc_relname,
list->my_cache->id,
#define PointerIsValid(pointer)
static bool chareqfast(Datum a, Datum b)
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
static bool int4eqfast(Datum a, Datum b)
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
void ReleaseCatCacheList(CatCList *list)
static void CatalogCacheInitializeCache(CatCache *cache)
void PrintCatCacheLeakWarning(HeapTuple tuple)
static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
static bool int2eqfast(Datum a, Datum b)
static uint32 int4hashfast(Datum datum)
void PrintCatCacheListLeakWarning(CatCList *list)
void InitCatCachePhase2(CatCache *cache, bool touch_index)
void ResetCatalogCaches(void)
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
static void RehashCatCache(CatCache *cp)
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments, uint32 hashValue, Index hashIndex, bool negative)
#define CatalogCacheInitializeCache_DEBUG1
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *srckeys, Datum *dstkeys)
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
static CatCacheHeader * CacheHdr
static uint32 namehashfast(Datum datum)
void CreateCacheMemoryContext(void)
static void ResetCatalogCache(CatCache *cache)
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
static void GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
static bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
static bool nameeqfast(Datum a, Datum b)
static uint32 charhashfast(Datum datum)
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
#define InitCatCache_DEBUG2
static uint32 oidvectorhashfast(Datum datum)
static bool texteqfast(Datum a, Datum b)
static bool oidvectoreqfast(Datum a, Datum b)
void CatalogCacheFlushCatalog(Oid catId)
static uint32 int2hashfast(Datum datum)
#define CatalogCacheInitializeCache_DEBUG2
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
#define HASH_INDEX(h, sz)
static bool IndexScanOK(CatCache *cache, ScanKey cur_skey)
static uint32 texthashfast(Datum datum)
void ReleaseCatCache(HeapTuple tuple)
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
uint32(* CCHashFN)(Datum datum)
bool(* CCFastEqualFN)(Datum a, Datum b)
Datum datumCopy(Datum value, bool typByVal, int typLen)
elog(ERROR, "%s: %s", p2, msg)
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
#define DirectFunctionCall2(func, arg1, arg2)
#define DirectFunctionCall1(func, arg1)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
static uint32 murmurhash32(uint32 data)
static Datum hash_any(const unsigned char *k, int keylen)
Datum hashoidvector(PG_FUNCTION_ARGS)
Datum hashtext(PG_FUNCTION_ARGS)
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
void heap_freetuple(HeapTuple htup)
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define HeapTupleHasExternal(tuple)
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define dlist_foreach(iter, lhead)
static void dlist_delete(dlist_node *node)
static void slist_init(slist_head *head)
static void dlist_push_head(dlist_head *head, dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static void slist_push_head(slist_head *head, slist_node *node)
#define slist_container(type, membername, ptr)
static void dlist_move_head(dlist_head *head, dlist_node *node)
#define slist_foreach(iter, lhead)
#define dlist_container(type, membername, ptr)
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
void on_proc_exit(pg_on_exit_callback function, Datum arg)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void * palloc_aligned(Size size, Size alignto, int flags)
MemoryContext CacheMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define IsBootstrapProcessingMode()
void namestrcpy(Name name, const char *str)
Datum oidvectoreq(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
static uint32 pg_rotate_left32(uint32 word, int n)
#define PG_CACHE_LINE_SIZE
static int list_length(const List *l)
static bool DatumGetBool(Datum X)
static Name DatumGetName(Datum X)
static char * DatumGetCString(Datum X)
static Datum NameGetDatum(const NameData *X)
static Pointer DatumGetPointer(Datum X)
static char DatumGetChar(Datum X)
static int16 DatumGetInt16(Datum X)
static int32 DatumGetInt32(Datum X)
#define RelationGetForm(relation)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationIsValid(relation)
bool criticalRelcachesBuilt
bool criticalSharedRelcachesBuilt
void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
ResourceOwner CurrentResourceOwner
void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner)
void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner)
void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
#define BTEqualStrategyNumber
StrategyNumber sk_strategy
CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]
int cc_keyno[CATCACHE_MAXKEYS]
CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Datum keys[CATCACHE_MAXKEYS]
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Datum keys[CATCACHE_MAXKEYS]
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
struct TupleDescData * TupleDesc
#define TupleDescAttr(tupdesc, i)
Datum texteq(PG_FUNCTION_ARGS)
bool IsTransactionState(void)