PostgreSQL Source Code  git master
catcache.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heaptoast.h"
#include "access/relscan.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "common/hashfn.h"
#include "common/pg_prng.h"
#include "miscadmin.h"
#include "port/pg_bitutils.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
Include dependency graph for catcache.c:

Go to the source code of this file.

Macros

#define HASH_INDEX(h, sz)   ((Index) ((h) & ((sz) - 1)))
 
#define CACHE_elog(...)
 
#define InitCatCache_DEBUG2
 
#define CatalogCacheInitializeCache_DEBUG1
 
#define CatalogCacheInitializeCache_DEBUG2
 

Functions

static HeapTuple SearchCatCacheInternal (CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
 
static pg_noinline HeapTuple SearchCatCacheMiss (CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
 
static uint32 CatalogCacheComputeHashValue (CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
 
static uint32 CatalogCacheComputeTupleHashValue (CatCache *cache, int nkeys, HeapTuple tuple)
 
static bool CatalogCacheCompareTuple (const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
 
static void CatCacheRemoveCTup (CatCache *cache, CatCTup *ct)
 
static void CatCacheRemoveCList (CatCache *cache, CatCList *cl)
 
static void CatalogCacheInitializeCache (CatCache *cache)
 
static CatCTupCatalogCacheCreateEntry (CatCache *cache, HeapTuple ntp, SysScanDesc scandesc, Datum *arguments, uint32 hashValue, Index hashIndex)
 
static void ReleaseCatCacheWithOwner (HeapTuple tuple, ResourceOwner resowner)
 
static void ReleaseCatCacheListWithOwner (CatCList *list, ResourceOwner resowner)
 
static void CatCacheFreeKeys (TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
 
static void CatCacheCopyKeys (TupleDesc tupdesc, int nkeys, int *attnos, Datum *srckeys, Datum *dstkeys)
 
static void ResOwnerReleaseCatCache (Datum res)
 
static char * ResOwnerPrintCatCache (Datum res)
 
static void ResOwnerReleaseCatCacheList (Datum res)
 
static char * ResOwnerPrintCatCacheList (Datum res)
 
static void ResourceOwnerRememberCatCacheRef (ResourceOwner owner, HeapTuple tuple)
 
static void ResourceOwnerForgetCatCacheRef (ResourceOwner owner, HeapTuple tuple)
 
static void ResourceOwnerRememberCatCacheListRef (ResourceOwner owner, CatCList *list)
 
static void ResourceOwnerForgetCatCacheListRef (ResourceOwner owner, CatCList *list)
 
static bool chareqfast (Datum a, Datum b)
 
static uint32 charhashfast (Datum datum)
 
static bool nameeqfast (Datum a, Datum b)
 
static uint32 namehashfast (Datum datum)
 
static bool int2eqfast (Datum a, Datum b)
 
static uint32 int2hashfast (Datum datum)
 
static bool int4eqfast (Datum a, Datum b)
 
static uint32 int4hashfast (Datum datum)
 
static bool texteqfast (Datum a, Datum b)
 
static uint32 texthashfast (Datum datum)
 
static bool oidvectoreqfast (Datum a, Datum b)
 
static uint32 oidvectorhashfast (Datum datum)
 
static void GetCCHashEqFuncs (Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
 
void CatCacheInvalidate (CatCache *cache, uint32 hashValue)
 
void CreateCacheMemoryContext (void)
 
static void ResetCatalogCache (CatCache *cache)
 
void ResetCatalogCaches (void)
 
void CatalogCacheFlushCatalog (Oid catId)
 
CatCacheInitCatCache (int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
 
static void RehashCatCache (CatCache *cp)
 
void InitCatCachePhase2 (CatCache *cache, bool touch_index)
 
static bool IndexScanOK (CatCache *cache, ScanKey cur_skey)
 
HeapTuple SearchCatCache (CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
 
HeapTuple SearchCatCache1 (CatCache *cache, Datum v1)
 
HeapTuple SearchCatCache2 (CatCache *cache, Datum v1, Datum v2)
 
HeapTuple SearchCatCache3 (CatCache *cache, Datum v1, Datum v2, Datum v3)
 
HeapTuple SearchCatCache4 (CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
 
void ReleaseCatCache (HeapTuple tuple)
 
uint32 GetCatCacheHashValue (CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
 
CatCListSearchCatCacheList (CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
 
void ReleaseCatCacheList (CatCList *list)
 
void PrepareToInvalidateCacheTuple (Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
 

Variables

static CatCacheHeaderCacheHdr = NULL
 
static const ResourceOwnerDesc catcache_resowner_desc
 
static const ResourceOwnerDesc catlistref_resowner_desc
 

Macro Definition Documentation

◆ CACHE_elog

#define CACHE_elog (   ...)

Definition at line 62 of file catcache.c.

◆ CatalogCacheInitializeCache_DEBUG1

#define CatalogCacheInitializeCache_DEBUG1

Definition at line 968 of file catcache.c.

◆ CatalogCacheInitializeCache_DEBUG2

#define CatalogCacheInitializeCache_DEBUG2

Definition at line 969 of file catcache.c.

◆ HASH_INDEX

#define HASH_INDEX (   h,
  sz 
)    ((Index) ((h) & ((sz) - 1)))

Definition at line 52 of file catcache.c.

◆ InitCatCache_DEBUG2

#define InitCatCache_DEBUG2

Definition at line 807 of file catcache.c.

Function Documentation

◆ CatalogCacheCompareTuple()

static bool CatalogCacheCompareTuple ( const CatCache cache,
int  nkeys,
const Datum cachekeys,
const Datum searchkeys 
)
inlinestatic

Definition at line 422 of file catcache.c.

425 {
426  const CCFastEqualFN *cc_fastequal = cache->cc_fastequal;
427  int i;
428 
429  for (i = 0; i < nkeys; i++)
430  {
431  if (!(cc_fastequal[i]) (cachekeys[i], searchkeys[i]))
432  return false;
433  }
434  return true;
435 }
bool(* CCFastEqualFN)(Datum a, Datum b)
Definition: catcache.h:42
int i
Definition: isn.c:73
CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]
Definition: catcache.h:51

References catcache::cc_fastequal, and i.

Referenced by SearchCatCacheInternal(), and SearchCatCacheList().

◆ CatalogCacheComputeHashValue()

static uint32 CatalogCacheComputeHashValue ( CatCache cache,
int  nkeys,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)
static

Definition at line 325 of file catcache.c.

327 {
328  uint32 hashValue = 0;
329  uint32 oneHash;
330  CCHashFN *cc_hashfunc = cache->cc_hashfunc;
331 
332  CACHE_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p",
333  cache->cc_relname, nkeys, cache);
334 
335  switch (nkeys)
336  {
337  case 4:
338  oneHash = (cc_hashfunc[3]) (v4);
339  hashValue ^= pg_rotate_left32(oneHash, 24);
340  /* FALLTHROUGH */
341  case 3:
342  oneHash = (cc_hashfunc[2]) (v3);
343  hashValue ^= pg_rotate_left32(oneHash, 16);
344  /* FALLTHROUGH */
345  case 2:
346  oneHash = (cc_hashfunc[1]) (v2);
347  hashValue ^= pg_rotate_left32(oneHash, 8);
348  /* FALLTHROUGH */
349  case 1:
350  oneHash = (cc_hashfunc[0]) (v1);
351  hashValue ^= oneHash;
352  break;
353  default:
354  elog(FATAL, "wrong number of hash keys: %d", nkeys);
355  break;
356  }
357 
358  return hashValue;
359 }
unsigned int uint32
Definition: c.h:495
#define CACHE_elog(...)
Definition: catcache.c:62
uint32(* CCHashFN)(Datum datum)
Definition: catcache.h:39
#define FATAL
Definition: elog.h:41
#define DEBUG2
Definition: elog.h:29
static uint32 pg_rotate_left32(uint32 word, int n)
Definition: pg_bitutils.h:326
const char * cc_relname
Definition: catcache.h:57
CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]
Definition: catcache.h:50

References CACHE_elog, catcache::cc_hashfunc, catcache::cc_relname, DEBUG2, elog(), FATAL, and pg_rotate_left32().

Referenced by CatalogCacheComputeTupleHashValue(), GetCatCacheHashValue(), SearchCatCacheInternal(), and SearchCatCacheList().

◆ CatalogCacheComputeTupleHashValue()

static uint32 CatalogCacheComputeTupleHashValue ( CatCache cache,
int  nkeys,
HeapTuple  tuple 
)
static

Definition at line 367 of file catcache.c.

368 {
369  Datum v1 = 0,
370  v2 = 0,
371  v3 = 0,
372  v4 = 0;
373  bool isNull = false;
374  int *cc_keyno = cache->cc_keyno;
375  TupleDesc cc_tupdesc = cache->cc_tupdesc;
376 
377  /* Now extract key fields from tuple, insert into scankey */
378  switch (nkeys)
379  {
380  case 4:
381  v4 = fastgetattr(tuple,
382  cc_keyno[3],
383  cc_tupdesc,
384  &isNull);
385  Assert(!isNull);
386  /* FALLTHROUGH */
387  case 3:
388  v3 = fastgetattr(tuple,
389  cc_keyno[2],
390  cc_tupdesc,
391  &isNull);
392  Assert(!isNull);
393  /* FALLTHROUGH */
394  case 2:
395  v2 = fastgetattr(tuple,
396  cc_keyno[1],
397  cc_tupdesc,
398  &isNull);
399  Assert(!isNull);
400  /* FALLTHROUGH */
401  case 1:
402  v1 = fastgetattr(tuple,
403  cc_keyno[0],
404  cc_tupdesc,
405  &isNull);
406  Assert(!isNull);
407  break;
408  default:
409  elog(FATAL, "wrong number of hash keys: %d", nkeys);
410  break;
411  }
412 
413  return CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
414 }
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:325
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:749
Assert(fmt[strlen(fmt) - 1] !='\n')
uintptr_t Datum
Definition: postgres.h:64
int cc_keyno[CATCACHE_MAXKEYS]
Definition: catcache.h:53
TupleDesc cc_tupdesc
Definition: catcache.h:48

References Assert(), CatalogCacheComputeHashValue(), catcache::cc_keyno, catcache::cc_tupdesc, elog(), fastgetattr(), and FATAL.

Referenced by PrepareToInvalidateCacheTuple(), and SearchCatCacheList().

◆ CatalogCacheCreateEntry()

static CatCTup * CatalogCacheCreateEntry ( CatCache cache,
HeapTuple  ntp,
SysScanDesc  scandesc,
Datum arguments,
uint32  hashValue,
Index  hashIndex 
)
static

Definition at line 1931 of file catcache.c.

1934 {
1935  CatCTup *ct;
1936  HeapTuple dtp;
1937  MemoryContext oldcxt;
1938 
1939  if (ntp)
1940  {
1941  int i;
1942 
1943  /*
1944  * The visibility recheck below essentially never fails during our
1945  * regression tests, and there's no easy way to force it to fail for
1946  * testing purposes. To ensure we have test coverage for the retry
1947  * paths in our callers, make debug builds randomly fail about 0.1% of
1948  * the times through this code path, even when there's no toasted
1949  * fields.
1950  */
1951 #ifdef USE_ASSERT_CHECKING
1953  return NULL;
1954 #endif
1955 
1956  /*
1957  * If there are any out-of-line toasted fields in the tuple, expand
1958  * them in-line. This saves cycles during later use of the catcache
1959  * entry, and also protects us against the possibility of the toast
1960  * tuples being freed before we attempt to fetch them, in case of
1961  * something using a slightly stale catcache entry.
1962  */
1963  if (HeapTupleHasExternal(ntp))
1964  {
1965  dtp = toast_flatten_tuple(ntp, cache->cc_tupdesc);
1966 
1967  /*
1968  * The tuple could become stale while we are doing toast table
1969  * access (since AcceptInvalidationMessages can run then), so we
1970  * must recheck its visibility afterwards.
1971  */
1972  if (!systable_recheck_tuple(scandesc, ntp))
1973  {
1974  heap_freetuple(dtp);
1975  return NULL;
1976  }
1977  }
1978  else
1979  dtp = ntp;
1980 
1981  /* Allocate memory for CatCTup and the cached tuple in one go */
1983 
1984  ct = (CatCTup *) palloc(sizeof(CatCTup) +
1985  MAXIMUM_ALIGNOF + dtp->t_len);
1986  ct->tuple.t_len = dtp->t_len;
1987  ct->tuple.t_self = dtp->t_self;
1988  ct->tuple.t_tableOid = dtp->t_tableOid;
1989  ct->tuple.t_data = (HeapTupleHeader)
1990  MAXALIGN(((char *) ct) + sizeof(CatCTup));
1991  /* copy tuple contents */
1992  memcpy((char *) ct->tuple.t_data,
1993  (const char *) dtp->t_data,
1994  dtp->t_len);
1995  MemoryContextSwitchTo(oldcxt);
1996 
1997  if (dtp != ntp)
1998  heap_freetuple(dtp);
1999 
2000  /* extract keys - they'll point into the tuple if not by-value */
2001  for (i = 0; i < cache->cc_nkeys; i++)
2002  {
2003  Datum atp;
2004  bool isnull;
2005 
2006  atp = heap_getattr(&ct->tuple,
2007  cache->cc_keyno[i],
2008  cache->cc_tupdesc,
2009  &isnull);
2010  Assert(!isnull);
2011  ct->keys[i] = atp;
2012  }
2013  }
2014  else
2015  {
2016  /* Set up keys for a negative cache entry */
2018  ct = (CatCTup *) palloc(sizeof(CatCTup));
2019 
2020  /*
2021  * Store keys - they'll point into separately allocated memory if not
2022  * by-value.
2023  */
2024  CatCacheCopyKeys(cache->cc_tupdesc, cache->cc_nkeys, cache->cc_keyno,
2025  arguments, ct->keys);
2026  MemoryContextSwitchTo(oldcxt);
2027  }
2028 
2029  /*
2030  * Finish initializing the CatCTup header, and add it to the cache's
2031  * linked list and counts.
2032  */
2033  ct->ct_magic = CT_MAGIC;
2034  ct->my_cache = cache;
2035  ct->c_list = NULL;
2036  ct->refcount = 0; /* for the moment */
2037  ct->dead = false;
2038  ct->negative = (ntp == NULL);
2039  ct->hash_value = hashValue;
2040 
2041  dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem);
2042 
2043  cache->cc_ntup++;
2044  CacheHdr->ch_ntup++;
2045 
2046  /*
2047  * If the hash table has become too full, enlarge the buckets array. Quite
2048  * arbitrarily, we enlarge when fill factor > 2.
2049  */
2050  if (cache->cc_ntup > cache->cc_nbuckets * 2)
2051  RehashCatCache(cache);
2052 
2053  return ct;
2054 }
#define MAXALIGN(LEN)
Definition: c.h:800
#define PG_UINT32_MAX
Definition: c.h:579
static void RehashCatCache(CatCache *cp)
Definition: catcache.c:910
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *srckeys, Datum *dstkeys)
Definition: catcache.c:2085
static CatCacheHeader * CacheHdr
Definition: catcache.c:66
#define CT_MAGIC
Definition: catcache.h:89
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Definition: genam.c:565
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
Definition: heaptoast.c:350
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHasExternal(tuple)
Definition: htup_details.h:671
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
MemoryContext CacheMemoryContext
Definition: mcxt.c:144
void * palloc(Size size)
Definition: mcxt.c:1201
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
uint32 pg_prng_uint32(pg_prng_state *state)
Definition: pg_prng.c:191
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
dlist_head * cc_bucket
Definition: catcache.h:49
int cc_nkeys
Definition: catcache.h:56
int cc_nbuckets
Definition: catcache.h:47
int cc_ntup
Definition: catcache.h:55
int ct_magic
Definition: catcache.h:88
int refcount
Definition: catcache.h:118
bool negative
Definition: catcache.h:120
dlist_node cache_elem
Definition: catcache.h:104
HeapTupleData tuple
Definition: catcache.h:121
CatCache * my_cache
Definition: catcache.h:132
struct catclist * c_list
Definition: catcache.h:130
Datum keys[CATCACHE_MAXKEYS]
Definition: catcache.h:97
bool dead
Definition: catcache.h:119
uint32 hash_value
Definition: catcache.h:91

References Assert(), catctup::c_list, catctup::cache_elem, CacheHdr, CacheMemoryContext, CatCacheCopyKeys(), catcache::cc_bucket, catcache::cc_keyno, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_tupdesc, catcacheheader::ch_ntup, catctup::ct_magic, CT_MAGIC, catctup::dead, dlist_push_head(), catctup::hash_value, heap_freetuple(), heap_getattr(), HeapTupleHasExternal, i, catctup::keys, MAXALIGN, MemoryContextSwitchTo(), catctup::my_cache, catctup::negative, palloc(), pg_global_prng_state, pg_prng_uint32(), PG_UINT32_MAX, catctup::refcount, RehashCatCache(), systable_recheck_tuple(), HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, toast_flatten_tuple(), and catctup::tuple.

Referenced by SearchCatCacheList(), and SearchCatCacheMiss().

◆ CatalogCacheFlushCatalog()

void CatalogCacheFlushCatalog ( Oid  catId)

Definition at line 767 of file catcache.c.

768 {
769  slist_iter iter;
770 
771  CACHE_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
772 
774  {
775  CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
776 
777  /* Does this cache store tuples of the target catalog? */
778  if (cache->cc_reloid == catId)
779  {
780  /* Yes, so flush all its contents */
781  ResetCatalogCache(cache);
782 
783  /* Tell inval.c to call syscache callbacks for this cache */
784  CallSyscacheCallbacks(cache->id, 0);
785  }
786  }
787 
788  CACHE_elog(DEBUG2, "end of CatalogCacheFlushCatalog call");
789 }
static void ResetCatalogCache(CatCache *cache)
Definition: catcache.c:690
#define slist_container(type, membername, ptr)
Definition: ilist.h:1106
#define slist_foreach(iter, lhead)
Definition: ilist.h:1132
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1578
Oid cc_reloid
Definition: catcache.h:58
int id
Definition: catcache.h:46
slist_head ch_caches
Definition: catcache.h:184
slist_node * cur
Definition: ilist.h:259

References CACHE_elog, CacheHdr, CallSyscacheCallbacks(), catcache::cc_reloid, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, catcache::id, ResetCatalogCache(), slist_container, and slist_foreach.

Referenced by LocalExecuteInvalidationMessage().

◆ CatalogCacheInitializeCache()

static void CatalogCacheInitializeCache ( CatCache cache)
static

Definition at line 973 of file catcache.c.

974 {
975  Relation relation;
976  MemoryContext oldcxt;
977  TupleDesc tupdesc;
978  int i;
979 
981 
982  relation = table_open(cache->cc_reloid, AccessShareLock);
983 
984  /*
985  * switch to the cache context so our allocations do not vanish at the end
986  * of a transaction
987  */
988  Assert(CacheMemoryContext != NULL);
989 
991 
992  /*
993  * copy the relcache's tuple descriptor to permanent cache storage
994  */
995  tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
996 
997  /*
998  * save the relation's name and relisshared flag, too (cc_relname is used
999  * only for debugging purposes)
1000  */
1001  cache->cc_relname = pstrdup(RelationGetRelationName(relation));
1002  cache->cc_relisshared = RelationGetForm(relation)->relisshared;
1003 
1004  /*
1005  * return to the caller's memory context and close the rel
1006  */
1007  MemoryContextSwitchTo(oldcxt);
1008 
1009  table_close(relation, AccessShareLock);
1010 
1011  CACHE_elog(DEBUG2, "CatalogCacheInitializeCache: %s, %d keys",
1012  cache->cc_relname, cache->cc_nkeys);
1013 
1014  /*
1015  * initialize cache's key information
1016  */
1017  for (i = 0; i < cache->cc_nkeys; ++i)
1018  {
1019  Oid keytype;
1020  RegProcedure eqfunc;
1021 
1023 
1024  if (cache->cc_keyno[i] > 0)
1025  {
1026  Form_pg_attribute attr = TupleDescAttr(tupdesc,
1027  cache->cc_keyno[i] - 1);
1028 
1029  keytype = attr->atttypid;
1030  /* cache key columns should always be NOT NULL */
1031  Assert(attr->attnotnull);
1032  }
1033  else
1034  {
1035  if (cache->cc_keyno[i] < 0)
1036  elog(FATAL, "sys attributes are not supported in caches");
1037  keytype = OIDOID;
1038  }
1039 
1040  GetCCHashEqFuncs(keytype,
1041  &cache->cc_hashfunc[i],
1042  &eqfunc,
1043  &cache->cc_fastequal[i]);
1044 
1045  /*
1046  * Do equality-function lookup (we assume this won't need a catalog
1047  * lookup for any supported type)
1048  */
1049  fmgr_info_cxt(eqfunc,
1050  &cache->cc_skey[i].sk_func,
1052 
1053  /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
1054  cache->cc_skey[i].sk_attno = cache->cc_keyno[i];
1055 
1056  /* Fill in sk_strategy as well --- always standard equality */
1058  cache->cc_skey[i].sk_subtype = InvalidOid;
1059  /* If a catcache key requires a collation, it must be C collation */
1060  cache->cc_skey[i].sk_collation = C_COLLATION_OID;
1061 
1062  CACHE_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p",
1063  cache->cc_relname, i, cache);
1064  }
1065 
1066  /*
1067  * mark this cache fully initialized
1068  */
1069  cache->cc_tupdesc = tupdesc;
1070 }
regproc RegProcedure
Definition: c.h:639
#define CatalogCacheInitializeCache_DEBUG1
Definition: catcache.c:968
static void GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
Definition: catcache.c:255
#define CatalogCacheInitializeCache_DEBUG2
Definition: catcache.c:969
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
#define AccessShareLock
Definition: lockdefs.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1619
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetForm(relation)
Definition: rel.h:498
#define RelationGetDescr(relation)
Definition: rel.h:530
#define RelationGetRelationName(relation)
Definition: rel.h:538
#define BTEqualStrategyNumber
Definition: stratnum.h:31
FmgrInfo sk_func
Definition: skey.h:71
Oid sk_subtype
Definition: skey.h:69
Oid sk_collation
Definition: skey.h:70
StrategyNumber sk_strategy
Definition: skey.h:68
AttrNumber sk_attno
Definition: skey.h:67
bool cc_relisshared
Definition: catcache.h:60
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Definition: catcache.h:62
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
Definition: tupdesc.c:173
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

References AccessShareLock, Assert(), BTEqualStrategyNumber, CACHE_elog, CacheMemoryContext, CatalogCacheInitializeCache_DEBUG1, CatalogCacheInitializeCache_DEBUG2, catcache::cc_fastequal, catcache::cc_hashfunc, catcache::cc_keyno, catcache::cc_nkeys, catcache::cc_relisshared, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcache::cc_tupdesc, CreateTupleDescCopyConstr(), DEBUG2, elog(), FATAL, fmgr_info_cxt(), GetCCHashEqFuncs(), i, InvalidOid, MemoryContextSwitchTo(), pstrdup(), RelationGetDescr, RelationGetForm, RelationGetRelationName, ScanKeyData::sk_attno, ScanKeyData::sk_collation, ScanKeyData::sk_func, ScanKeyData::sk_strategy, ScanKeyData::sk_subtype, table_close(), table_open(), and TupleDescAttr.

Referenced by GetCatCacheHashValue(), InitCatCachePhase2(), PrepareToInvalidateCacheTuple(), SearchCatCacheInternal(), and SearchCatCacheList().

◆ CatCacheCopyKeys()

static void CatCacheCopyKeys ( TupleDesc  tupdesc,
int  nkeys,
int *  attnos,
Datum srckeys,
Datum dstkeys 
)
static

Definition at line 2085 of file catcache.c.

2087 {
2088  int i;
2089 
2090  /*
2091  * XXX: memory and lookup performance could possibly be improved by
2092  * storing all keys in one allocation.
2093  */
2094 
2095  for (i = 0; i < nkeys; i++)
2096  {
2097  int attnum = attnos[i];
2098  Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
2099  Datum src = srckeys[i];
2100  NameData srcname;
2101 
2102  /*
2103  * Must be careful in case the caller passed a C string where a NAME
2104  * is wanted: convert the given argument to a correctly padded NAME.
2105  * Otherwise the memcpy() done by datumCopy() could fall off the end
2106  * of memory.
2107  */
2108  if (att->atttypid == NAMEOID)
2109  {
2110  namestrcpy(&srcname, DatumGetCString(src));
2111  src = NameGetDatum(&srcname);
2112  }
2113 
2114  dstkeys[i] = datumCopy(src,
2115  att->attbyval,
2116  att->attlen);
2117  }
2118 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
void namestrcpy(Name name, const char *str)
Definition: name.c:233
int16 attnum
Definition: pg_attribute.h:74
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
Definition: c.h:730

References attnum, datumCopy(), DatumGetCString(), i, NameGetDatum(), namestrcpy(), and TupleDescAttr.

Referenced by CatalogCacheCreateEntry(), and SearchCatCacheList().

◆ CatCacheFreeKeys()

static void CatCacheFreeKeys ( TupleDesc  tupdesc,
int  nkeys,
int *  attnos,
Datum keys 
)
static

Definition at line 2060 of file catcache.c.

2061 {
2062  int i;
2063 
2064  for (i = 0; i < nkeys; i++)
2065  {
2066  int attnum = attnos[i];
2067  Form_pg_attribute att;
2068 
2069  /* system attribute are not supported in caches */
2070  Assert(attnum > 0);
2071 
2072  att = TupleDescAttr(tupdesc, attnum - 1);
2073 
2074  if (!att->attbyval)
2075  pfree(DatumGetPointer(keys[i]));
2076  }
2077 }
void pfree(void *pointer)
Definition: mcxt.c:1431
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312

References Assert(), attnum, DatumGetPointer(), i, pfree(), and TupleDescAttr.

Referenced by CatCacheRemoveCList(), and CatCacheRemoveCTup().

◆ CatCacheInvalidate()

void CatCacheInvalidate ( CatCache cache,
uint32  hashValue 
)

Definition at line 600 of file catcache.c.

601 {
602  Index hashIndex;
603  dlist_mutable_iter iter;
604 
605  CACHE_elog(DEBUG2, "CatCacheInvalidate: called");
606 
607  /*
608  * We don't bother to check whether the cache has finished initialization
609  * yet; if not, there will be no entries in it so no problem.
610  */
611 
612  /*
613  * Invalidate *all* CatCLists in this cache; it's too hard to tell which
614  * searches might still be correct, so just zap 'em all.
615  */
616  dlist_foreach_modify(iter, &cache->cc_lists)
617  {
618  CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
619 
620  if (cl->refcount > 0)
621  cl->dead = true;
622  else
623  CatCacheRemoveCList(cache, cl);
624  }
625 
626  /*
627  * inspect the proper hash bucket for tuple matches
628  */
629  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
630  dlist_foreach_modify(iter, &cache->cc_bucket[hashIndex])
631  {
632  CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
633 
634  if (hashValue == ct->hash_value)
635  {
636  if (ct->refcount > 0 ||
637  (ct->c_list && ct->c_list->refcount > 0))
638  {
639  ct->dead = true;
640  /* list, if any, was marked dead above */
641  Assert(ct->c_list == NULL || ct->c_list->dead);
642  }
643  else
644  CatCacheRemoveCTup(cache, ct);
645  CACHE_elog(DEBUG2, "CatCacheInvalidate: invalidated");
646 #ifdef CATCACHE_STATS
647  cache->cc_invals++;
648 #endif
649  /* could be multiple matches, so keep looking! */
650  }
651  }
652 }
unsigned int Index
Definition: c.h:603
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition: catcache.c:505
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Definition: catcache.c:547
#define HASH_INDEX(h, sz)
Definition: catcache.c:52
#define dlist_foreach_modify(iter, lhead)
Definition: ilist.h:640
#define dlist_container(type, membername, ptr)
Definition: ilist.h:593
dlist_head cc_lists
Definition: catcache.h:54
int refcount
Definition: catcache.h:172
bool dead
Definition: catcache.h:173
dlist_node * cur
Definition: ilist.h:200

References Assert(), catctup::c_list, CACHE_elog, CatCacheRemoveCList(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_lists, catcache::cc_nbuckets, dlist_mutable_iter::cur, catctup::dead, catclist::dead, DEBUG2, dlist_container, dlist_foreach_modify, HASH_INDEX, catctup::hash_value, catctup::refcount, and catclist::refcount.

Referenced by SysCacheInvalidate().

◆ CatCacheRemoveCList()

static void CatCacheRemoveCList ( CatCache cache,
CatCList cl 
)
static

Definition at line 547 of file catcache.c.

548 {
549  int i;
550 
551  Assert(cl->refcount == 0);
552  Assert(cl->my_cache == cache);
553 
554  /* delink from member tuples */
555  for (i = cl->n_members; --i >= 0;)
556  {
557  CatCTup *ct = cl->members[i];
558 
559  Assert(ct->c_list == cl);
560  ct->c_list = NULL;
561  /* if the member is dead and now has no references, remove it */
562  if (
563 #ifndef CATCACHE_FORCE_RELEASE
564  ct->dead &&
565 #endif
566  ct->refcount == 0)
567  CatCacheRemoveCTup(cache, ct);
568  }
569 
570  /* delink from linked list */
571  dlist_delete(&cl->cache_elem);
572 
573  /* free associated column data */
574  CatCacheFreeKeys(cache->cc_tupdesc, cl->nkeys,
575  cache->cc_keyno, cl->keys);
576 
577  pfree(cl);
578 }
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
Definition: catcache.c:2060
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
dlist_node cache_elem
Definition: catcache.h:164
CatCache * my_cache
Definition: catcache.h:177
short nkeys
Definition: catcache.h:175
Datum keys[CATCACHE_MAXKEYS]
Definition: catcache.h:170
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
int n_members
Definition: catcache.h:176

References Assert(), catctup::c_list, catclist::cache_elem, CatCacheFreeKeys(), CatCacheRemoveCTup(), catcache::cc_keyno, catcache::cc_tupdesc, catctup::dead, dlist_delete(), i, catclist::keys, catclist::members, catclist::my_cache, catclist::n_members, catclist::nkeys, pfree(), catctup::refcount, and catclist::refcount.

Referenced by CatCacheInvalidate(), CatCacheRemoveCTup(), ReleaseCatCacheListWithOwner(), and ResetCatalogCache().

◆ CatCacheRemoveCTup()

static void CatCacheRemoveCTup ( CatCache cache,
CatCTup ct 
)
static

Definition at line 505 of file catcache.c.

506 {
507  Assert(ct->refcount == 0);
508  Assert(ct->my_cache == cache);
509 
510  if (ct->c_list)
511  {
512  /*
513  * The cleanest way to handle this is to call CatCacheRemoveCList,
514  * which will recurse back to me, and the recursive call will do the
515  * work. Set the "dead" flag to make sure it does recurse.
516  */
517  ct->dead = true;
518  CatCacheRemoveCList(cache, ct->c_list);
519  return; /* nothing left to do */
520  }
521 
522  /* delink from linked list */
523  dlist_delete(&ct->cache_elem);
524 
525  /*
526  * Free keys when we're dealing with a negative entry, normal entries just
527  * point into tuple, allocated together with the CatCTup.
528  */
529  if (ct->negative)
530  CatCacheFreeKeys(cache->cc_tupdesc, cache->cc_nkeys,
531  cache->cc_keyno, ct->keys);
532 
533  pfree(ct);
534 
535  --cache->cc_ntup;
536  --CacheHdr->ch_ntup;
537 }

References Assert(), catctup::c_list, catctup::cache_elem, CacheHdr, CatCacheFreeKeys(), CatCacheRemoveCList(), catcache::cc_keyno, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_tupdesc, catcacheheader::ch_ntup, catctup::dead, dlist_delete(), catctup::keys, catctup::my_cache, catctup::negative, pfree(), and catctup::refcount.

Referenced by CatCacheInvalidate(), CatCacheRemoveCList(), ReleaseCatCacheWithOwner(), ResetCatalogCache(), and SearchCatCacheList().

◆ chareqfast()

static bool chareqfast ( Datum  a,
Datum  b 
)
static

Definition at line 172 of file catcache.c.

173 {
174  return DatumGetChar(a) == DatumGetChar(b);
175 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69
static char DatumGetChar(Datum X)
Definition: postgres.h:112

References a, b, and DatumGetChar().

Referenced by GetCCHashEqFuncs().

◆ charhashfast()

static uint32 charhashfast ( Datum  datum)
static

Definition at line 178 of file catcache.c.

179 {
180  return murmurhash32((int32) DatumGetChar(datum));
181 }
signed int int32
Definition: c.h:483
static uint32 murmurhash32(uint32 data)
Definition: hashfn.h:92

References DatumGetChar(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ CreateCacheMemoryContext()

void CreateCacheMemoryContext ( void  )

Definition at line 668 of file catcache.c.

669 {
670  /*
671  * Purely for paranoia, check that context doesn't exist; caller probably
672  * did so already.
673  */
674  if (!CacheMemoryContext)
676  "CacheMemoryContext",
678 }
MemoryContext TopMemoryContext
Definition: mcxt.c:141
#define AllocSetContextCreate
Definition: memutils.h:128
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:152

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CacheMemoryContext, and TopMemoryContext.

Referenced by assign_record_type_typmod(), BuildEventTriggerCache(), init_ts_config_cache(), InitCatCache(), InitializeAttoptCache(), InitializeRelfilenumberMap(), InitializeTableSpaceCache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), LookupOpclassInfo(), RelationBuildLocalRelation(), and RelationCacheInitialize().

◆ GetCatCacheHashValue()

uint32 GetCatCacheHashValue ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1550 of file catcache.c.

1555 {
1556  /*
1557  * one-time startup overhead for each cache
1558  */
1559  if (cache->cc_tupdesc == NULL)
1561 
1562  /*
1563  * calculate the hash value
1564  */
1565  return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, v1, v2, v3, v4);
1566 }
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:973

References CatalogCacheComputeHashValue(), CatalogCacheInitializeCache(), catcache::cc_nkeys, and catcache::cc_tupdesc.

Referenced by GetSysCacheHashValue().

◆ GetCCHashEqFuncs()

static void GetCCHashEqFuncs ( Oid  keytype,
CCHashFN hashfunc,
RegProcedure eqfunc,
CCFastEqualFN fasteqfunc 
)
static

Definition at line 255 of file catcache.c.

256 {
257  switch (keytype)
258  {
259  case BOOLOID:
260  *hashfunc = charhashfast;
261  *fasteqfunc = chareqfast;
262  *eqfunc = F_BOOLEQ;
263  break;
264  case CHAROID:
265  *hashfunc = charhashfast;
266  *fasteqfunc = chareqfast;
267  *eqfunc = F_CHAREQ;
268  break;
269  case NAMEOID:
270  *hashfunc = namehashfast;
271  *fasteqfunc = nameeqfast;
272  *eqfunc = F_NAMEEQ;
273  break;
274  case INT2OID:
275  *hashfunc = int2hashfast;
276  *fasteqfunc = int2eqfast;
277  *eqfunc = F_INT2EQ;
278  break;
279  case INT4OID:
280  *hashfunc = int4hashfast;
281  *fasteqfunc = int4eqfast;
282  *eqfunc = F_INT4EQ;
283  break;
284  case TEXTOID:
285  *hashfunc = texthashfast;
286  *fasteqfunc = texteqfast;
287  *eqfunc = F_TEXTEQ;
288  break;
289  case OIDOID:
290  case REGPROCOID:
291  case REGPROCEDUREOID:
292  case REGOPEROID:
293  case REGOPERATOROID:
294  case REGCLASSOID:
295  case REGTYPEOID:
296  case REGCOLLATIONOID:
297  case REGCONFIGOID:
298  case REGDICTIONARYOID:
299  case REGROLEOID:
300  case REGNAMESPACEOID:
301  *hashfunc = int4hashfast;
302  *fasteqfunc = int4eqfast;
303  *eqfunc = F_OIDEQ;
304  break;
305  case OIDVECTOROID:
306  *hashfunc = oidvectorhashfast;
307  *fasteqfunc = oidvectoreqfast;
308  *eqfunc = F_OIDVECTOREQ;
309  break;
310  default:
311  elog(FATAL, "type %u not supported as catcache key", keytype);
312  *hashfunc = NULL; /* keep compiler quiet */
313 
314  *eqfunc = InvalidOid;
315  break;
316  }
317 }
static bool chareqfast(Datum a, Datum b)
Definition: catcache.c:172
static bool int4eqfast(Datum a, Datum b)
Definition: catcache.c:213
static bool int2eqfast(Datum a, Datum b)
Definition: catcache.c:201
static uint32 int4hashfast(Datum datum)
Definition: catcache.c:219
static uint32 namehashfast(Datum datum)
Definition: catcache.c:193
static bool nameeqfast(Datum a, Datum b)
Definition: catcache.c:184
static uint32 charhashfast(Datum datum)
Definition: catcache.c:178
static uint32 oidvectorhashfast(Datum datum)
Definition: catcache.c:248
static bool texteqfast(Datum a, Datum b)
Definition: catcache.c:225
static bool oidvectoreqfast(Datum a, Datum b)
Definition: catcache.c:242
static uint32 int2hashfast(Datum datum)
Definition: catcache.c:207
static uint32 texthashfast(Datum datum)
Definition: catcache.c:235

References chareqfast(), charhashfast(), elog(), FATAL, int2eqfast(), int2hashfast(), int4eqfast(), int4hashfast(), InvalidOid, nameeqfast(), namehashfast(), oidvectoreqfast(), oidvectorhashfast(), texteqfast(), and texthashfast().

Referenced by CatalogCacheInitializeCache().

◆ IndexScanOK()

static bool IndexScanOK ( CatCache cache,
ScanKey  cur_skey 
)
static

Definition at line 1134 of file catcache.c.

1135 {
1136  switch (cache->id)
1137  {
1138  case INDEXRELID:
1139 
1140  /*
1141  * Rather than tracking exactly which indexes have to be loaded
1142  * before we can use indexscans (which changes from time to time),
1143  * just force all pg_index searches to be heap scans until we've
1144  * built the critical relcaches.
1145  */
1147  return false;
1148  break;
1149 
1150  case AMOID:
1151  case AMNAME:
1152 
1153  /*
1154  * Always do heap scans in pg_am, because it's so small there's
1155  * not much point in an indexscan anyway. We *must* do this when
1156  * initially building critical relcache entries, but we might as
1157  * well just always do it.
1158  */
1159  return false;
1160 
1161  case AUTHNAME:
1162  case AUTHOID:
1163  case AUTHMEMMEMROLE:
1164  case DATABASEOID:
1165 
1166  /*
1167  * Protect authentication lookups occurring before relcache has
1168  * collected entries for shared indexes.
1169  */
1171  return false;
1172  break;
1173 
1174  default:
1175  break;
1176  }
1177 
1178  /* Normal case, allow index scan */
1179  return true;
1180 }
bool criticalRelcachesBuilt
Definition: relcache.c:142
bool criticalSharedRelcachesBuilt
Definition: relcache.c:148

References criticalRelcachesBuilt, criticalSharedRelcachesBuilt, and catcache::id.

Referenced by SearchCatCacheList(), and SearchCatCacheMiss().

◆ InitCatCache()

CatCache* InitCatCache ( int  id,
Oid  reloid,
Oid  indexoid,
int  nkeys,
const int *  key,
int  nbuckets 
)

Definition at line 811 of file catcache.c.

817 {
818  CatCache *cp;
819  MemoryContext oldcxt;
820  int i;
821 
822  /*
823  * nbuckets is the initial number of hash buckets to use in this catcache.
824  * It will be enlarged later if it becomes too full.
825  *
826  * nbuckets must be a power of two. We check this via Assert rather than
827  * a full runtime check because the values will be coming from constant
828  * tables.
829  *
830  * If you're confused by the power-of-two check, see comments in
831  * bitmapset.c for an explanation.
832  */
833  Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
834 
835  /*
836  * first switch to the cache context so our allocations do not vanish at
837  * the end of a transaction
838  */
839  if (!CacheMemoryContext)
841 
843 
844  /*
845  * if first time through, initialize the cache group header
846  */
847  if (CacheHdr == NULL)
848  {
851  CacheHdr->ch_ntup = 0;
852 #ifdef CATCACHE_STATS
853  /* set up to dump stats at backend exit */
854  on_proc_exit(CatCachePrintStats, 0);
855 #endif
856  }
857 
858  /*
859  * Allocate a new cache structure, aligning to a cacheline boundary
860  *
861  * Note: we rely on zeroing to initialize all the dlist headers correctly
862  */
865  cp->cc_bucket = palloc0(nbuckets * sizeof(dlist_head));
866 
867  /*
868  * initialize the cache's relation information for the relation
869  * corresponding to this cache, and initialize some of the new cache's
870  * other internal fields. But don't open the relation yet.
871  */
872  cp->id = id;
873  cp->cc_relname = "(not known yet)";
874  cp->cc_reloid = reloid;
875  cp->cc_indexoid = indexoid;
876  cp->cc_relisshared = false; /* temporary */
877  cp->cc_tupdesc = (TupleDesc) NULL;
878  cp->cc_ntup = 0;
879  cp->cc_nbuckets = nbuckets;
880  cp->cc_nkeys = nkeys;
881  for (i = 0; i < nkeys; ++i)
882  {
884  cp->cc_keyno[i] = key[i];
885  }
886 
887  /*
888  * new cache is initialized as far as we can go for now. print some
889  * debugging information, if appropriate.
890  */
892 
893  /*
894  * add completed cache to top of group header's list
895  */
897 
898  /*
899  * back to the old context before we return...
900  */
901  MemoryContextSwitchTo(oldcxt);
902 
903  return cp;
904 }
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void CreateCacheMemoryContext(void)
Definition: catcache.c:668
#define InitCatCache_DEBUG2
Definition: catcache.c:807
#define MCXT_ALLOC_ZERO
Definition: fe_memutils.h:18
static void slist_init(slist_head *head)
Definition: ilist.h:986
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:1006
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:309
void * palloc0(Size size)
Definition: mcxt.c:1232
void * palloc_aligned(Size size, Size alignto, int flags)
Definition: mcxt.c:1421
#define PG_CACHE_LINE_SIZE
slist_node cc_next
Definition: catcache.h:61
Oid cc_indexoid
Definition: catcache.h:59
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89

References Assert(), AttributeNumberIsValid, CacheHdr, CacheMemoryContext, catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_keyno, catcache::cc_nbuckets, catcache::cc_next, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_relisshared, catcache::cc_relname, catcache::cc_reloid, catcache::cc_tupdesc, catcacheheader::ch_caches, catcacheheader::ch_ntup, CreateCacheMemoryContext(), i, catcache::id, InitCatCache_DEBUG2, sort-test::key, MCXT_ALLOC_ZERO, MemoryContextSwitchTo(), on_proc_exit(), palloc(), palloc0(), palloc_aligned(), PG_CACHE_LINE_SIZE, slist_init(), and slist_push_head().

Referenced by InitCatalogCache().

◆ InitCatCachePhase2()

void InitCatCachePhase2 ( CatCache cache,
bool  touch_index 
)

Definition at line 1082 of file catcache.c.

1083 {
1084  if (cache->cc_tupdesc == NULL)
1086 
1087  if (touch_index &&
1088  cache->id != AMOID &&
1089  cache->id != AMNAME)
1090  {
1091  Relation idesc;
1092 
1093  /*
1094  * We must lock the underlying catalog before opening the index to
1095  * avoid deadlock, since index_open could possibly result in reading
1096  * this same catalog, and if anyone else is exclusive-locking this
1097  * catalog and index they'll be doing it in that order.
1098  */
1100  idesc = index_open(cache->cc_indexoid, AccessShareLock);
1101 
1102  /*
1103  * While we've got the index open, let's check that it's unique (and
1104  * not just deferrable-unique, thank you very much). This is just to
1105  * catch thinkos in definitions of new catcaches, so we don't worry
1106  * about the pg_am indexes not getting tested.
1107  */
1108  Assert(idesc->rd_index->indisunique &&
1109  idesc->rd_index->indimmediate);
1110 
1111  index_close(idesc, AccessShareLock);
1113  }
1114 }
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:182
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:138
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:228
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:109
Form_pg_index rd_index
Definition: rel.h:191

References AccessShareLock, Assert(), CatalogCacheInitializeCache(), catcache::cc_indexoid, catcache::cc_reloid, catcache::cc_tupdesc, catcache::id, index_close(), index_open(), LockRelationOid(), RelationData::rd_index, and UnlockRelationOid().

Referenced by InitCatalogCachePhase2(), and SysCacheGetAttr().

◆ int2eqfast()

static bool int2eqfast ( Datum  a,
Datum  b 
)
static

Definition at line 201 of file catcache.c.

202 {
203  return DatumGetInt16(a) == DatumGetInt16(b);
204 }
static int16 DatumGetInt16(Datum X)
Definition: postgres.h:162

References a, b, and DatumGetInt16().

Referenced by GetCCHashEqFuncs().

◆ int2hashfast()

static uint32 int2hashfast ( Datum  datum)
static

Definition at line 207 of file catcache.c.

208 {
209  return murmurhash32((int32) DatumGetInt16(datum));
210 }

References DatumGetInt16(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ int4eqfast()

static bool int4eqfast ( Datum  a,
Datum  b 
)
static

Definition at line 213 of file catcache.c.

214 {
215  return DatumGetInt32(a) == DatumGetInt32(b);
216 }
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202

References a, b, and DatumGetInt32().

Referenced by GetCCHashEqFuncs().

◆ int4hashfast()

static uint32 int4hashfast ( Datum  datum)
static

Definition at line 219 of file catcache.c.

220 {
221  return murmurhash32((int32) DatumGetInt32(datum));
222 }

References DatumGetInt32(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ nameeqfast()

static bool nameeqfast ( Datum  a,
Datum  b 
)
static

Definition at line 184 of file catcache.c.

185 {
186  char *ca = NameStr(*DatumGetName(a));
187  char *cb = NameStr(*DatumGetName(b));
188 
189  return strncmp(ca, cb, NAMEDATALEN) == 0;
190 }
#define NameStr(name)
Definition: c.h:735
#define NAMEDATALEN
static Name DatumGetName(Datum X)
Definition: postgres.h:360

References a, b, DatumGetName(), NAMEDATALEN, and NameStr.

Referenced by GetCCHashEqFuncs().

◆ namehashfast()

static uint32 namehashfast ( Datum  datum)
static

Definition at line 193 of file catcache.c.

194 {
195  char *key = NameStr(*DatumGetName(datum));
196 
197  return hash_any((unsigned char *) key, strlen(key));
198 }
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31

References DatumGetName(), hash_any(), sort-test::key, and NameStr.

Referenced by GetCCHashEqFuncs().

◆ oidvectoreqfast()

static bool oidvectoreqfast ( Datum  a,
Datum  b 
)
static

Definition at line 242 of file catcache.c.

243 {
245 }
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
Datum oidvectoreq(PG_FUNCTION_ARGS)
Definition: oid.c:344
static bool DatumGetBool(Datum X)
Definition: postgres.h:90

References a, b, DatumGetBool(), DirectFunctionCall2, and oidvectoreq().

Referenced by GetCCHashEqFuncs().

◆ oidvectorhashfast()

static uint32 oidvectorhashfast ( Datum  datum)
static

Definition at line 248 of file catcache.c.

249 {
251 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
Datum hashoidvector(PG_FUNCTION_ARGS)
Definition: hashfunc.c:234

References DatumGetInt32(), DirectFunctionCall1, and hashoidvector().

Referenced by GetCCHashEqFuncs().

◆ PrepareToInvalidateCacheTuple()

void PrepareToInvalidateCacheTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple,
void(*)(int, uint32, Oid function 
)

Definition at line 2155 of file catcache.c.

2159 {
2160  slist_iter iter;
2161  Oid reloid;
2162 
2163  CACHE_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
2164 
2165  /*
2166  * sanity checks
2167  */
2168  Assert(RelationIsValid(relation));
2169  Assert(HeapTupleIsValid(tuple));
2170  Assert(PointerIsValid(function));
2171  Assert(CacheHdr != NULL);
2172 
2173  reloid = RelationGetRelid(relation);
2174 
2175  /* ----------------
2176  * for each cache
2177  * if the cache contains tuples from the specified relation
2178  * compute the tuple's hash value(s) in this cache,
2179  * and call the passed function to register the information.
2180  * ----------------
2181  */
2182 
2184  {
2185  CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
2186  uint32 hashvalue;
2187  Oid dbid;
2188 
2189  if (ccp->cc_reloid != reloid)
2190  continue;
2191 
2192  /* Just in case cache hasn't finished initialization yet... */
2193  if (ccp->cc_tupdesc == NULL)
2195 
2196  hashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, tuple);
2197  dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
2198 
2199  (*function) (ccp->id, hashvalue, dbid);
2200 
2201  if (newtuple)
2202  {
2203  uint32 newhashvalue;
2204 
2205  newhashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, newtuple);
2206 
2207  if (newhashvalue != hashvalue)
2208  (*function) (ccp->id, newhashvalue, dbid);
2209  }
2210  }
2211 }
#define PointerIsValid(pointer)
Definition: c.h:752
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
Definition: catcache.c:367
Oid MyDatabaseId
Definition: globals.c:90
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define RelationGetRelid(relation)
Definition: rel.h:504
#define RelationIsValid(relation)
Definition: rel.h:477

References Assert(), CACHE_elog, CacheHdr, CatalogCacheComputeTupleHashValue(), CatalogCacheInitializeCache(), catcache::cc_nkeys, catcache::cc_relisshared, catcache::cc_reloid, catcache::cc_tupdesc, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, HeapTupleIsValid, catcache::id, MyDatabaseId, PointerIsValid, RelationGetRelid, RelationIsValid, slist_container, and slist_foreach.

Referenced by CacheInvalidateHeapTuple().

◆ RehashCatCache()

static void RehashCatCache ( CatCache cp)
static

Definition at line 910 of file catcache.c.

911 {
912  dlist_head *newbucket;
913  int newnbuckets;
914  int i;
915 
916  elog(DEBUG1, "rehashing catalog cache id %d for %s; %d tups, %d buckets",
917  cp->id, cp->cc_relname, cp->cc_ntup, cp->cc_nbuckets);
918 
919  /* Allocate a new, larger, hash table. */
920  newnbuckets = cp->cc_nbuckets * 2;
921  newbucket = (dlist_head *) MemoryContextAllocZero(CacheMemoryContext, newnbuckets * sizeof(dlist_head));
922 
923  /* Move all entries from old hash table to new. */
924  for (i = 0; i < cp->cc_nbuckets; i++)
925  {
926  dlist_mutable_iter iter;
927 
928  dlist_foreach_modify(iter, &cp->cc_bucket[i])
929  {
930  CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
931  int hashIndex = HASH_INDEX(ct->hash_value, newnbuckets);
932 
933  dlist_delete(iter.cur);
934  dlist_push_head(&newbucket[hashIndex], &ct->cache_elem);
935  }
936  }
937 
938  /* Switch to the new array. */
939  pfree(cp->cc_bucket);
940  cp->cc_nbuckets = newnbuckets;
941  cp->cc_bucket = newbucket;
942 }
#define DEBUG1
Definition: elog.h:30
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1077

References catctup::cache_elem, CacheMemoryContext, catcache::cc_bucket, catcache::cc_nbuckets, catcache::cc_ntup, catcache::cc_relname, dlist_mutable_iter::cur, DEBUG1, dlist_container, dlist_delete(), dlist_foreach_modify, dlist_push_head(), elog(), HASH_INDEX, catctup::hash_value, i, catcache::id, MemoryContextAllocZero(), and pfree().

Referenced by CatalogCacheCreateEntry().

◆ ReleaseCatCache()

void ReleaseCatCache ( HeapTuple  tuple)

Definition at line 1511 of file catcache.c.

1512 {
1514 }
static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner)
Definition: catcache.c:1517
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165

References CurrentResourceOwner, and ReleaseCatCacheWithOwner().

Referenced by ReleaseSysCache().

◆ ReleaseCatCacheList()

◆ ReleaseCatCacheListWithOwner()

static void ReleaseCatCacheListWithOwner ( CatCList list,
ResourceOwner  resowner 
)
static

Definition at line 1897 of file catcache.c.

1898 {
1899  /* Safety checks to ensure we were handed a cache entry */
1900  Assert(list->cl_magic == CL_MAGIC);
1901  Assert(list->refcount > 0);
1902  list->refcount--;
1903  if (resowner)
1905 
1906  if (
1907 #ifndef CATCACHE_FORCE_RELEASE
1908  list->dead &&
1909 #endif
1910  list->refcount == 0)
1911  CatCacheRemoveCList(list->my_cache, list);
1912 }
static void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition: catcache.c:155
#define CL_MAGIC
Definition: catcache.h:160

References Assert(), CatCacheRemoveCList(), CL_MAGIC, CurrentResourceOwner, sort-test::list, and ResourceOwnerForgetCatCacheListRef().

Referenced by ReleaseCatCacheList(), and ResOwnerReleaseCatCacheList().

◆ ReleaseCatCacheWithOwner()

static void ReleaseCatCacheWithOwner ( HeapTuple  tuple,
ResourceOwner  resowner 
)
static

Definition at line 1517 of file catcache.c.

1518 {
1519  CatCTup *ct = (CatCTup *) (((char *) tuple) -
1520  offsetof(CatCTup, tuple));
1521 
1522  /* Safety checks to ensure we were handed a cache entry */
1523  Assert(ct->ct_magic == CT_MAGIC);
1524  Assert(ct->refcount > 0);
1525 
1526  ct->refcount--;
1527  if (resowner)
1529 
1530  if (
1531 #ifndef CATCACHE_FORCE_RELEASE
1532  ct->dead &&
1533 #endif
1534  ct->refcount == 0 &&
1535  (ct->c_list == NULL || ct->c_list->refcount == 0))
1536  CatCacheRemoveCTup(ct->my_cache, ct);
1537 }
static void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition: catcache.c:145

References Assert(), catctup::c_list, CatCacheRemoveCTup(), catctup::ct_magic, CT_MAGIC, CurrentResourceOwner, catctup::dead, catctup::my_cache, catctup::refcount, catclist::refcount, ResourceOwnerForgetCatCacheRef(), and catctup::tuple.

Referenced by ReleaseCatCache(), and ResOwnerReleaseCatCache().

◆ ResetCatalogCache()

static void ResetCatalogCache ( CatCache cache)
static

Definition at line 690 of file catcache.c.

691 {
692  dlist_mutable_iter iter;
693  int i;
694 
695  /* Remove each list in this cache, or at least mark it dead */
696  dlist_foreach_modify(iter, &cache->cc_lists)
697  {
698  CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
699 
700  if (cl->refcount > 0)
701  cl->dead = true;
702  else
703  CatCacheRemoveCList(cache, cl);
704  }
705 
706  /* Remove each tuple in this cache, or at least mark it dead */
707  for (i = 0; i < cache->cc_nbuckets; i++)
708  {
709  dlist_head *bucket = &cache->cc_bucket[i];
710 
711  dlist_foreach_modify(iter, bucket)
712  {
713  CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
714 
715  if (ct->refcount > 0 ||
716  (ct->c_list && ct->c_list->refcount > 0))
717  {
718  ct->dead = true;
719  /* list, if any, was marked dead above */
720  Assert(ct->c_list == NULL || ct->c_list->dead);
721  }
722  else
723  CatCacheRemoveCTup(cache, ct);
724 #ifdef CATCACHE_STATS
725  cache->cc_invals++;
726 #endif
727  }
728  }
729 }

References Assert(), catctup::c_list, CatCacheRemoveCList(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_lists, catcache::cc_nbuckets, dlist_mutable_iter::cur, catctup::dead, catclist::dead, dlist_container, dlist_foreach_modify, i, catctup::refcount, and catclist::refcount.

Referenced by CatalogCacheFlushCatalog(), and ResetCatalogCaches().

◆ ResetCatalogCaches()

void ResetCatalogCaches ( void  )

Definition at line 737 of file catcache.c.

738 {
739  slist_iter iter;
740 
741  CACHE_elog(DEBUG2, "ResetCatalogCaches called");
742 
744  {
745  CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
746 
747  ResetCatalogCache(cache);
748  }
749 
750  CACHE_elog(DEBUG2, "end of ResetCatalogCaches call");
751 }

References CACHE_elog, CacheHdr, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, ResetCatalogCache(), slist_container, and slist_foreach.

Referenced by InvalidateSystemCachesExtended().

◆ ResourceOwnerForgetCatCacheListRef()

static void ResourceOwnerForgetCatCacheListRef ( ResourceOwner  owner,
CatCList list 
)
inlinestatic

Definition at line 155 of file catcache.c.

156 {
158 }
static const ResourceOwnerDesc catlistref_resowner_desc
Definition: catcache.c:128
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554

References catlistref_resowner_desc, sort-test::list, PointerGetDatum(), and ResourceOwnerForget().

Referenced by ReleaseCatCacheListWithOwner().

◆ ResourceOwnerForgetCatCacheRef()

static void ResourceOwnerForgetCatCacheRef ( ResourceOwner  owner,
HeapTuple  tuple 
)
inlinestatic

Definition at line 145 of file catcache.c.

146 {
148 }
static const ResourceOwnerDesc catcache_resowner_desc
Definition: catcache.c:118

References catcache_resowner_desc, PointerGetDatum(), and ResourceOwnerForget().

Referenced by ReleaseCatCacheWithOwner().

◆ ResourceOwnerRememberCatCacheListRef()

static void ResourceOwnerRememberCatCacheListRef ( ResourceOwner  owner,
CatCList list 
)
inlinestatic

Definition at line 150 of file catcache.c.

151 {
153 }
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514

References catlistref_resowner_desc, sort-test::list, PointerGetDatum(), and ResourceOwnerRemember().

Referenced by SearchCatCacheList().

◆ ResourceOwnerRememberCatCacheRef()

static void ResourceOwnerRememberCatCacheRef ( ResourceOwner  owner,
HeapTuple  tuple 
)
inlinestatic

◆ ResOwnerPrintCatCache()

static char * ResOwnerPrintCatCache ( Datum  res)
static

Definition at line 2222 of file catcache.c.

2223 {
2225  CatCTup *ct = (CatCTup *) (((char *) tuple) -
2226  offsetof(CatCTup, tuple));
2227 
2228  /* Safety check to ensure we were handed a cache entry */
2229  Assert(ct->ct_magic == CT_MAGIC);
2230 
2231  return psprintf("cache %s (%d), tuple %u/%u has count %d",
2232  ct->my_cache->cc_relname, ct->my_cache->id,
2233  ItemPointerGetBlockNumber(&(tuple->t_self)),
2235  ct->refcount);
2236 }
HeapTupleData * HeapTuple
Definition: htup.h:71
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References Assert(), catcache::cc_relname, catctup::ct_magic, CT_MAGIC, DatumGetPointer(), catcache::id, ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), catctup::my_cache, psprintf(), catctup::refcount, res, and HeapTupleData::t_self.

◆ ResOwnerPrintCatCacheList()

static char * ResOwnerPrintCatCacheList ( Datum  res)
static

Definition at line 2245 of file catcache.c.

2246 {
2248 
2249  return psprintf("cache %s (%d), list %p has count %d",
2250  list->my_cache->cc_relname, list->my_cache->id,
2251  list, list->refcount);
2252 }

References DatumGetPointer(), sort-test::list, psprintf(), and res.

◆ ResOwnerReleaseCatCache()

static void ResOwnerReleaseCatCache ( Datum  res)
static

Definition at line 2216 of file catcache.c.

2217 {
2219 }

References DatumGetPointer(), ReleaseCatCacheWithOwner(), and res.

◆ ResOwnerReleaseCatCacheList()

static void ResOwnerReleaseCatCacheList ( Datum  res)
static

Definition at line 2239 of file catcache.c.

2240 {
2242 }

References DatumGetPointer(), ReleaseCatCacheListWithOwner(), and res.

◆ SearchCatCache()

HeapTuple SearchCatCache ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1199 of file catcache.c.

1204 {
1205  return SearchCatCacheInternal(cache, cache->cc_nkeys, v1, v2, v3, v4);
1206 }
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1250

References catcache::cc_nkeys, and SearchCatCacheInternal().

Referenced by SearchSysCache().

◆ SearchCatCache1()

HeapTuple SearchCatCache1 ( CatCache cache,
Datum  v1 
)

Definition at line 1216 of file catcache.c.

1218 {
1219  return SearchCatCacheInternal(cache, 1, v1, 0, 0, 0);
1220 }

References SearchCatCacheInternal().

Referenced by SearchSysCache1().

◆ SearchCatCache2()

HeapTuple SearchCatCache2 ( CatCache cache,
Datum  v1,
Datum  v2 
)

Definition at line 1224 of file catcache.c.

1226 {
1227  return SearchCatCacheInternal(cache, 2, v1, v2, 0, 0);
1228 }

References SearchCatCacheInternal().

Referenced by SearchSysCache2().

◆ SearchCatCache3()

HeapTuple SearchCatCache3 ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3 
)

Definition at line 1232 of file catcache.c.

1234 {
1235  return SearchCatCacheInternal(cache, 3, v1, v2, v3, 0);
1236 }

References SearchCatCacheInternal().

Referenced by SearchSysCache3().

◆ SearchCatCache4()

HeapTuple SearchCatCache4 ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1240 of file catcache.c.

1242 {
1243  return SearchCatCacheInternal(cache, 4, v1, v2, v3, v4);
1244 }

References SearchCatCacheInternal().

Referenced by SearchSysCache4().

◆ SearchCatCacheInternal()

static HeapTuple SearchCatCacheInternal ( CatCache cache,
int  nkeys,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)
inlinestatic

Definition at line 1250 of file catcache.c.

1256 {
1258  uint32 hashValue;
1259  Index hashIndex;
1260  dlist_iter iter;
1261  dlist_head *bucket;
1262  CatCTup *ct;
1263 
1264  /* Make sure we're in an xact, even if this ends up being a cache hit */
1266 
1267  Assert(cache->cc_nkeys == nkeys);
1268 
1269  /*
1270  * one-time startup overhead for each cache
1271  */
1272  if (unlikely(cache->cc_tupdesc == NULL))
1274 
1275 #ifdef CATCACHE_STATS
1276  cache->cc_searches++;
1277 #endif
1278 
1279  /* Initialize local parameter array */
1280  arguments[0] = v1;
1281  arguments[1] = v2;
1282  arguments[2] = v3;
1283  arguments[3] = v4;
1284 
1285  /*
1286  * find the hash bucket in which to look for the tuple
1287  */
1288  hashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
1289  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1290 
1291  /*
1292  * scan the hash bucket until we find a match or exhaust our tuples
1293  *
1294  * Note: it's okay to use dlist_foreach here, even though we modify the
1295  * dlist within the loop, because we don't continue the loop afterwards.
1296  */
1297  bucket = &cache->cc_bucket[hashIndex];
1298  dlist_foreach(iter, bucket)
1299  {
1300  ct = dlist_container(CatCTup, cache_elem, iter.cur);
1301 
1302  if (ct->dead)
1303  continue; /* ignore dead entries */
1304 
1305  if (ct->hash_value != hashValue)
1306  continue; /* quickly skip entry if wrong hash val */
1307 
1308  if (!CatalogCacheCompareTuple(cache, nkeys, ct->keys, arguments))
1309  continue;
1310 
1311  /*
1312  * We found a match in the cache. Move it to the front of the list
1313  * for its hashbucket, in order to speed subsequent searches. (The
1314  * most frequently accessed elements in any hashbucket will tend to be
1315  * near the front of the hashbucket's list.)
1316  */
1317  dlist_move_head(bucket, &ct->cache_elem);
1318 
1319  /*
1320  * If it's a positive entry, bump its refcount and return it. If it's
1321  * negative, we can report failure to the caller.
1322  */
1323  if (!ct->negative)
1324  {
1326  ct->refcount++;
1328 
1329  CACHE_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d",
1330  cache->cc_relname, hashIndex);
1331 
1332 #ifdef CATCACHE_STATS
1333  cache->cc_hits++;
1334 #endif
1335 
1336  return &ct->tuple;
1337  }
1338  else
1339  {
1340  CACHE_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d",
1341  cache->cc_relname, hashIndex);
1342 
1343 #ifdef CATCACHE_STATS
1344  cache->cc_neg_hits++;
1345 #endif
1346 
1347  return NULL;
1348  }
1349  }
1350 
1351  return SearchCatCacheMiss(cache, nkeys, hashValue, hashIndex, v1, v2, v3, v4);
1352 }
#define unlikely(x)
Definition: c.h:300
static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1362
static void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition: catcache.c:140
static bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
Definition: catcache.c:422
#define CATCACHE_MAXKEYS
Definition: catcache.h:35
#define dlist_foreach(iter, lhead)
Definition: ilist.h:623
static void dlist_move_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:467
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442
dlist_node * cur
Definition: ilist.h:179
bool IsTransactionState(void)
Definition: xact.c:378

References Assert(), catctup::cache_elem, CACHE_elog, CatalogCacheCompareTuple(), CatalogCacheComputeHashValue(), CatalogCacheInitializeCache(), CATCACHE_MAXKEYS, catcache::cc_bucket, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_relname, catcache::cc_tupdesc, dlist_iter::cur, CurrentResourceOwner, catctup::dead, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), HASH_INDEX, catctup::hash_value, IsTransactionState(), catctup::keys, catctup::negative, catctup::refcount, ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheRef(), SearchCatCacheMiss(), catctup::tuple, and unlikely.

Referenced by SearchCatCache(), SearchCatCache1(), SearchCatCache2(), SearchCatCache3(), and SearchCatCache4().

◆ SearchCatCacheList()

CatCList* SearchCatCacheList ( CatCache cache,
int  nkeys,
Datum  v1,
Datum  v2,
Datum  v3 
)

Definition at line 1584 of file catcache.c.

1589 {
1590  Datum v4 = 0; /* dummy last-column value */
1592  uint32 lHashValue;
1593  dlist_iter iter;
1594  CatCList *cl;
1595  CatCTup *ct;
1596  List *volatile ctlist;
1597  ListCell *ctlist_item;
1598  int nmembers;
1599  bool ordered;
1600  HeapTuple ntp;
1601  MemoryContext oldcxt;
1602  int i;
1603 
1604  /*
1605  * one-time startup overhead for each cache
1606  */
1607  if (cache->cc_tupdesc == NULL)
1609 
1610  Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1611 
1612 #ifdef CATCACHE_STATS
1613  cache->cc_lsearches++;
1614 #endif
1615 
1616  /* Initialize local parameter array */
1617  arguments[0] = v1;
1618  arguments[1] = v2;
1619  arguments[2] = v3;
1620  arguments[3] = v4;
1621 
1622  /*
1623  * compute a hash value of the given keys for faster search. We don't
1624  * presently divide the CatCList items into buckets, but this still lets
1625  * us skip non-matching items quickly most of the time.
1626  */
1627  lHashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
1628 
1629  /*
1630  * scan the items until we find a match or exhaust our list
1631  *
1632  * Note: it's okay to use dlist_foreach here, even though we modify the
1633  * dlist within the loop, because we don't continue the loop afterwards.
1634  */
1635  dlist_foreach(iter, &cache->cc_lists)
1636  {
1637  cl = dlist_container(CatCList, cache_elem, iter.cur);
1638 
1639  if (cl->dead)
1640  continue; /* ignore dead entries */
1641 
1642  if (cl->hash_value != lHashValue)
1643  continue; /* quickly skip entry if wrong hash val */
1644 
1645  /*
1646  * see if the cached list matches our key.
1647  */
1648  if (cl->nkeys != nkeys)
1649  continue;
1650 
1651  if (!CatalogCacheCompareTuple(cache, nkeys, cl->keys, arguments))
1652  continue;
1653 
1654  /*
1655  * We found a matching list. Move the list to the front of the
1656  * cache's list-of-lists, to speed subsequent searches. (We do not
1657  * move the members to the fronts of their hashbucket lists, however,
1658  * since there's no point in that unless they are searched for
1659  * individually.)
1660  */
1661  dlist_move_head(&cache->cc_lists, &cl->cache_elem);
1662 
1663  /* Bump the list's refcount and return it */
1665  cl->refcount++;
1667 
1668  CACHE_elog(DEBUG2, "SearchCatCacheList(%s): found list",
1669  cache->cc_relname);
1670 
1671 #ifdef CATCACHE_STATS
1672  cache->cc_lhits++;
1673 #endif
1674 
1675  return cl;
1676  }
1677 
1678  /*
1679  * List was not found in cache, so we have to build it by reading the
1680  * relation. For each matching tuple found in the relation, use an
1681  * existing cache entry if possible, else build a new one.
1682  *
1683  * We have to bump the member refcounts temporarily to ensure they won't
1684  * get dropped from the cache while loading other members. We use a PG_TRY
1685  * block to ensure we can undo those refcounts if we get an error before
1686  * we finish constructing the CatCList. ctlist must be valid throughout
1687  * the PG_TRY block.
1688  */
1689  ctlist = NIL;
1690 
1691  PG_TRY();
1692  {
1693  ScanKeyData cur_skey[CATCACHE_MAXKEYS];
1694  Relation relation;
1695  SysScanDesc scandesc;
1696  bool stale;
1697 
1698  relation = table_open(cache->cc_reloid, AccessShareLock);
1699 
1700  do
1701  {
1702  /*
1703  * Ok, need to make a lookup in the relation, copy the scankey and
1704  * fill out any per-call fields. (We must re-do this when
1705  * retrying, because systable_beginscan scribbles on the scankey.)
1706  */
1707  memcpy(cur_skey, cache->cc_skey, sizeof(ScanKeyData) * cache->cc_nkeys);
1708  cur_skey[0].sk_argument = v1;
1709  cur_skey[1].sk_argument = v2;
1710  cur_skey[2].sk_argument = v3;
1711  cur_skey[3].sk_argument = v4;
1712 
1713  scandesc = systable_beginscan(relation,
1714  cache->cc_indexoid,
1715  IndexScanOK(cache, cur_skey),
1716  NULL,
1717  nkeys,
1718  cur_skey);
1719 
1720  /* The list will be ordered iff we are doing an index scan */
1721  ordered = (scandesc->irel != NULL);
1722 
1723  stale = false;
1724 
1725  while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
1726  {
1727  uint32 hashValue;
1728  Index hashIndex;
1729  bool found = false;
1730  dlist_head *bucket;
1731 
1732  /*
1733  * See if there's an entry for this tuple already.
1734  */
1735  ct = NULL;
1736  hashValue = CatalogCacheComputeTupleHashValue(cache, cache->cc_nkeys, ntp);
1737  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1738 
1739  bucket = &cache->cc_bucket[hashIndex];
1740  dlist_foreach(iter, bucket)
1741  {
1742  ct = dlist_container(CatCTup, cache_elem, iter.cur);
1743 
1744  if (ct->dead || ct->negative)
1745  continue; /* ignore dead and negative entries */
1746 
1747  if (ct->hash_value != hashValue)
1748  continue; /* quickly skip entry if wrong hash val */
1749 
1750  if (!ItemPointerEquals(&(ct->tuple.t_self), &(ntp->t_self)))
1751  continue; /* not same tuple */
1752 
1753  /*
1754  * Found a match, but can't use it if it belongs to
1755  * another list already
1756  */
1757  if (ct->c_list)
1758  continue;
1759 
1760  found = true;
1761  break; /* A-OK */
1762  }
1763 
1764  if (!found)
1765  {
1766  /* We didn't find a usable entry, so make a new one */
1767  ct = CatalogCacheCreateEntry(cache, ntp, scandesc, NULL,
1768  hashValue, hashIndex);
1769  /* upon failure, we must start the scan over */
1770  if (ct == NULL)
1771  {
1772  /*
1773  * Release refcounts on any items we already had. We
1774  * dare not try to free them if they're now
1775  * unreferenced, since an error while doing that would
1776  * result in the PG_CATCH below doing extra refcount
1777  * decrements. Besides, we'll likely re-adopt those
1778  * items in the next iteration, so it's not worth
1779  * complicating matters to try to get rid of them.
1780  */
1781  foreach(ctlist_item, ctlist)
1782  {
1783  ct = (CatCTup *) lfirst(ctlist_item);
1784  Assert(ct->c_list == NULL);
1785  Assert(ct->refcount > 0);
1786  ct->refcount--;
1787  }
1788  /* Reset ctlist in preparation for new try */
1789  ctlist = NIL;
1790  stale = true;
1791  break;
1792  }
1793  }
1794 
1795  /* Careful here: add entry to ctlist, then bump its refcount */
1796  /* This way leaves state correct if lappend runs out of memory */
1797  ctlist = lappend(ctlist, ct);
1798  ct->refcount++;
1799  }
1800 
1801  systable_endscan(scandesc);
1802  } while (stale);
1803 
1804  table_close(relation, AccessShareLock);
1805 
1806  /* Make sure the resource owner has room to remember this entry. */
1808 
1809  /* Now we can build the CatCList entry. */
1811  nmembers = list_length(ctlist);
1812  cl = (CatCList *)
1813  palloc(offsetof(CatCList, members) + nmembers * sizeof(CatCTup *));
1814 
1815  /* Extract key values */
1816  CatCacheCopyKeys(cache->cc_tupdesc, nkeys, cache->cc_keyno,
1817  arguments, cl->keys);
1818  MemoryContextSwitchTo(oldcxt);
1819 
1820  /*
1821  * We are now past the last thing that could trigger an elog before we
1822  * have finished building the CatCList and remembering it in the
1823  * resource owner. So it's OK to fall out of the PG_TRY, and indeed
1824  * we'd better do so before we start marking the members as belonging
1825  * to the list.
1826  */
1827  }
1828  PG_CATCH();
1829  {
1830  foreach(ctlist_item, ctlist)
1831  {
1832  ct = (CatCTup *) lfirst(ctlist_item);
1833  Assert(ct->c_list == NULL);
1834  Assert(ct->refcount > 0);
1835  ct->refcount--;
1836  if (
1837 #ifndef CATCACHE_FORCE_RELEASE
1838  ct->dead &&
1839 #endif
1840  ct->refcount == 0 &&
1841  (ct->c_list == NULL || ct->c_list->refcount == 0))
1842  CatCacheRemoveCTup(cache, ct);
1843  }
1844 
1845  PG_RE_THROW();
1846  }
1847  PG_END_TRY();
1848 
1849  cl->cl_magic = CL_MAGIC;
1850  cl->my_cache = cache;
1851  cl->refcount = 0; /* for the moment */
1852  cl->dead = false;
1853  cl->ordered = ordered;
1854  cl->nkeys = nkeys;
1855  cl->hash_value = lHashValue;
1856  cl->n_members = nmembers;
1857 
1858  i = 0;
1859  foreach(ctlist_item, ctlist)
1860  {
1861  cl->members[i++] = ct = (CatCTup *) lfirst(ctlist_item);
1862  Assert(ct->c_list == NULL);
1863  ct->c_list = cl;
1864  /* release the temporary refcount on the member */
1865  Assert(ct->refcount > 0);
1866  ct->refcount--;
1867  /* mark list dead if any members already dead */
1868  if (ct->dead)
1869  cl->dead = true;
1870  }
1871  Assert(i == nmembers);
1872 
1873  dlist_push_head(&cache->cc_lists, &cl->cache_elem);
1874 
1875  /* Finally, bump the list's refcount and return it */
1876  cl->refcount++;
1878 
1879  CACHE_elog(DEBUG2, "SearchCatCacheList(%s): made list of %d members",
1880  cache->cc_relname, nmembers);
1881 
1882  return cl;
1883 }
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, SysScanDesc scandesc, Datum *arguments, uint32 hashValue, Index hashIndex)
Definition: catcache.c:1931
static void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition: catcache.c:150
static bool IndexScanOK(CatCache *cache, ScanKey cur_skey)
Definition: catcache.c:1134
#define PG_RE_THROW()
Definition: elog.h:411
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_CATCH(...)
Definition: elog.h:380
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:35
List * lappend(List *list, void *datum)
Definition: list.c:339
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54
Datum sk_argument
Definition: skey.h:72
Relation irel
Definition: relscan.h:184
int cl_magic
Definition: catcache.h:159
bool ordered
Definition: catcache.h:174
uint32 hash_value
Definition: catcache.h:162

References AccessShareLock, Assert(), catctup::c_list, catclist::cache_elem, CACHE_elog, CacheMemoryContext, CatalogCacheCompareTuple(), CatalogCacheComputeHashValue(), CatalogCacheComputeTupleHashValue(), CatalogCacheCreateEntry(), CatalogCacheInitializeCache(), CATCACHE_MAXKEYS, CatCacheCopyKeys(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_keyno, catcache::cc_lists, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcache::cc_tupdesc, catclist::cl_magic, CL_MAGIC, dlist_iter::cur, CurrentResourceOwner, catctup::dead, catclist::dead, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), dlist_push_head(), HASH_INDEX, catctup::hash_value, catclist::hash_value, HeapTupleIsValid, i, IndexScanOK(), SysScanDescData::irel, ItemPointerEquals(), catclist::keys, lappend(), lfirst, list_length(), catclist::members, MemoryContextSwitchTo(), catclist::my_cache, catclist::n_members, catctup::negative, NIL, catclist::nkeys, catclist::ordered, palloc(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, catctup::refcount, catclist::refcount, ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheListRef(), ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), and catctup::tuple.

Referenced by SearchSysCacheList().

◆ SearchCatCacheMiss()

static pg_noinline HeapTuple SearchCatCacheMiss ( CatCache cache,
int  nkeys,
uint32  hashValue,
Index  hashIndex,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)
static

Definition at line 1362 of file catcache.c.

1370 {
1371  ScanKeyData cur_skey[CATCACHE_MAXKEYS];
1372  Relation relation;
1373  SysScanDesc scandesc;
1374  HeapTuple ntp;
1375  CatCTup *ct;
1376  bool stale;
1378 
1379  /* Initialize local parameter array */
1380  arguments[0] = v1;
1381  arguments[1] = v2;
1382  arguments[2] = v3;
1383  arguments[3] = v4;
1384 
1385  /*
1386  * Tuple was not found in cache, so we have to try to retrieve it directly
1387  * from the relation. If found, we will add it to the cache; if not
1388  * found, we will add a negative cache entry instead.
1389  *
1390  * NOTE: it is possible for recursive cache lookups to occur while reading
1391  * the relation --- for example, due to shared-cache-inval messages being
1392  * processed during table_open(). This is OK. It's even possible for one
1393  * of those lookups to find and enter the very same tuple we are trying to
1394  * fetch here. If that happens, we will enter a second copy of the tuple
1395  * into the cache. The first copy will never be referenced again, and
1396  * will eventually age out of the cache, so there's no functional problem.
1397  * This case is rare enough that it's not worth expending extra cycles to
1398  * detect.
1399  *
1400  * Another case, which we *must* handle, is that the tuple could become
1401  * outdated during CatalogCacheCreateEntry's attempt to detoast it (since
1402  * AcceptInvalidationMessages can run during TOAST table access). We do
1403  * not want to return already-stale catcache entries, so we loop around
1404  * and do the table scan again if that happens.
1405  */
1406  relation = table_open(cache->cc_reloid, AccessShareLock);
1407 
1408  do
1409  {
1410  /*
1411  * Ok, need to make a lookup in the relation, copy the scankey and
1412  * fill out any per-call fields. (We must re-do this when retrying,
1413  * because systable_beginscan scribbles on the scankey.)
1414  */
1415  memcpy(cur_skey, cache->cc_skey, sizeof(ScanKeyData) * nkeys);
1416  cur_skey[0].sk_argument = v1;
1417  cur_skey[1].sk_argument = v2;
1418  cur_skey[2].sk_argument = v3;
1419  cur_skey[3].sk_argument = v4;
1420 
1421  scandesc = systable_beginscan(relation,
1422  cache->cc_indexoid,
1423  IndexScanOK(cache, cur_skey),
1424  NULL,
1425  nkeys,
1426  cur_skey);
1427 
1428  ct = NULL;
1429  stale = false;
1430 
1431  while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
1432  {
1433  ct = CatalogCacheCreateEntry(cache, ntp, scandesc, NULL,
1434  hashValue, hashIndex);
1435  /* upon failure, we must start the scan over */
1436  if (ct == NULL)
1437  {
1438  stale = true;
1439  break;
1440  }
1441  /* immediately set the refcount to 1 */
1443  ct->refcount++;
1445  break; /* assume only one match */
1446  }
1447 
1448  systable_endscan(scandesc);
1449  } while (stale);
1450 
1451  table_close(relation, AccessShareLock);
1452 
1453  /*
1454  * If tuple was not found, we need to build a negative cache entry
1455  * containing a fake tuple. The fake tuple has the correct key columns,
1456  * but nulls everywhere else.
1457  *
1458  * In bootstrap mode, we don't build negative entries, because the cache
1459  * invalidation mechanism isn't alive and can't clear them if the tuple
1460  * gets created later. (Bootstrap doesn't do UPDATEs, so it doesn't need
1461  * cache inval for that.)
1462  */
1463  if (ct == NULL)
1464  {
1466  return NULL;
1467 
1468  ct = CatalogCacheCreateEntry(cache, NULL, NULL, arguments,
1469  hashValue, hashIndex);
1470 
1471  /* Creating a negative cache entry shouldn't fail */
1472  Assert(ct != NULL);
1473 
1474  CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1475  cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1476  CACHE_elog(DEBUG2, "SearchCatCache(%s): put neg entry in bucket %d",
1477  cache->cc_relname, hashIndex);
1478 
1479  /*
1480  * We are not returning the negative entry to the caller, so leave its
1481  * refcount zero.
1482  */
1483 
1484  return NULL;
1485  }
1486 
1487  CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1488  cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1489  CACHE_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d",
1490  cache->cc_relname, hashIndex);
1491 
1492 #ifdef CATCACHE_STATS
1493  cache->cc_newloads++;
1494 #endif
1495 
1496  return &ct->tuple;
1497 }
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:416

References AccessShareLock, Assert(), CACHE_elog, CacheHdr, CatalogCacheCreateEntry(), CATCACHE_MAXKEYS, catcache::cc_indexoid, catcache::cc_ntup, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcacheheader::ch_ntup, CurrentResourceOwner, DEBUG2, HeapTupleIsValid, IndexScanOK(), IsBootstrapProcessingMode, catctup::refcount, ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheRef(), ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and catctup::tuple.

Referenced by SearchCatCacheInternal().

◆ texteqfast()

static bool texteqfast ( Datum  a,
Datum  b 
)
static

Definition at line 225 of file catcache.c.

226 {
227  /*
228  * The use of DEFAULT_COLLATION_OID is fairly arbitrary here. We just
229  * want to take the fast "deterministic" path in texteq().
230  */
231  return DatumGetBool(DirectFunctionCall2Coll(texteq, DEFAULT_COLLATION_OID, a, b));
232 }
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:812
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1618

References a, b, DatumGetBool(), DirectFunctionCall2Coll(), and texteq().

Referenced by GetCCHashEqFuncs().

◆ texthashfast()

static uint32 texthashfast ( Datum  datum)
static

Definition at line 235 of file catcache.c.

236 {
237  /* analogously here as in texteqfast() */
238  return DatumGetInt32(DirectFunctionCall1Coll(hashtext, DEFAULT_COLLATION_OID, datum));
239 }
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
Definition: fmgr.c:792
Datum hashtext(PG_FUNCTION_ARGS)
Definition: hashfunc.c:269

References DatumGetInt32(), DirectFunctionCall1Coll(), and hashtext().

Referenced by GetCCHashEqFuncs().

Variable Documentation

◆ CacheHdr

◆ catcache_resowner_desc

const ResourceOwnerDesc catcache_resowner_desc
static
Initial value:
=
{
.name = "catcache reference",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_CATCACHE_REFS,
.ReleaseResource = ResOwnerReleaseCatCache,
.DebugPrint = ResOwnerPrintCatCache
}
static void ResOwnerReleaseCatCache(Datum res)
Definition: catcache.c:2216
static char * ResOwnerPrintCatCache(Datum res)
Definition: catcache.c:2222
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
#define RELEASE_PRIO_CATCACHE_REFS
Definition: resowner.h:71

Definition at line 118 of file catcache.c.

Referenced by ResourceOwnerForgetCatCacheRef(), and ResourceOwnerRememberCatCacheRef().

◆ catlistref_resowner_desc

const ResourceOwnerDesc catlistref_resowner_desc
static
Initial value:
=
{
.name = "catcache list reference",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_CATCACHE_LIST_REFS,
.ReleaseResource = ResOwnerReleaseCatCacheList,
}
static void ResOwnerReleaseCatCacheList(Datum res)
Definition: catcache.c:2239
static char * ResOwnerPrintCatCacheList(Datum res)
Definition: catcache.c:2245
#define RELEASE_PRIO_CATCACHE_LIST_REFS
Definition: resowner.h:72

Definition at line 128 of file catcache.c.

Referenced by ResourceOwnerForgetCatCacheListRef(), and ResourceOwnerRememberCatCacheListRef().