PostgreSQL Source Code git master
Loading...
Searching...
No Matches
catcache.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heaptoast.h"
#include "access/relscan.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/pg_collation.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/injection_point.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.

Data Structures

struct  CatCInProgress
 

Macros

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

Typedefs

typedef struct CatCInProgress CatCInProgress
 

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 RehashCatCache (CatCache *cp)
 
static void RehashCatCacheLists (CatCache *cp)
 
static void CatalogCacheInitializeCache (CatCache *cache)
 
static CatCTupCatalogCacheCreateEntry (CatCache *cache, HeapTuple ntp, 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, const int *attnos, const Datum *keys)
 
static void CatCacheCopyKeys (TupleDesc tupdesc, int nkeys, const int *attnos, const Datum *srckeys, Datum *dstkeys)
 
static void ResOwnerReleaseCatCache (Datum res)
 
static charResOwnerPrintCatCache (Datum res)
 
static void ResOwnerReleaseCatCacheList (Datum res)
 
static charResOwnerPrintCatCacheList (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, bool debug_discard)
 
void ResetCatalogCaches (void)
 
void ResetCatalogCachesExt (bool debug_discard)
 
void CatalogCacheFlushCatalog (Oid catId)
 
CatCacheInitCatCache (int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
 
static pg_attribute_always_inline void ConditionalCatalogCacheInitializeCache (CatCache *cache)
 
void InitCatCachePhase2 (CatCache *cache, bool touch_index)
 
static bool IndexScanOK (CatCache *cache)
 
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, void *), void *context)
 

Variables

static CatCInProgresscatcache_in_progress_stack = NULL
 
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 80 of file catcache.c.

◆ CatalogCacheInitializeCache_DEBUG1

#define CatalogCacheInitializeCache_DEBUG1

Definition at line 1131 of file catcache.c.

◆ CatalogCacheInitializeCache_DEBUG2

#define CatalogCacheInitializeCache_DEBUG2

Definition at line 1132 of file catcache.c.

◆ HASH_INDEX

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

Definition at line 70 of file catcache.c.

◆ InitCatCache_DEBUG2

#define InitCatCache_DEBUG2

Definition at line 881 of file catcache.c.

Typedef Documentation

◆ CatCInProgress

Function Documentation

◆ CatalogCacheCompareTuple()

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

Definition at line 442 of file catcache.c.

445{
446 const CCFastEqualFN *cc_fastequal = cache->cc_fastequal;
447 int i;
448
449 for (i = 0; i < nkeys; i++)
450 {
451 if (!(cc_fastequal[i]) (cachekeys[i], searchkeys[i]))
452 return false;
453 }
454 return true;
455}
bool(* CCFastEqualFN)(Datum a, Datum b)
Definition catcache.h:42
int i
Definition isn.c:77
static int fb(int x)
CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]
Definition catcache.h:51

References CatCInProgress::cache, catcache::cc_fastequal, fb(), 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 345 of file catcache.c.

347{
348 uint32 hashValue = 0;
350 CCHashFN *cc_hashfunc = cache->cc_hashfunc;
351
352 CACHE_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p",
353 cache->cc_relname, nkeys, cache);
354
355 switch (nkeys)
356 {
357 case 4:
358 oneHash = (cc_hashfunc[3]) (v4);
359 hashValue ^= pg_rotate_left32(oneHash, 24);
360 /* FALLTHROUGH */
361 case 3:
362 oneHash = (cc_hashfunc[2]) (v3);
363 hashValue ^= pg_rotate_left32(oneHash, 16);
364 /* FALLTHROUGH */
365 case 2:
366 oneHash = (cc_hashfunc[1]) (v2);
367 hashValue ^= pg_rotate_left32(oneHash, 8);
368 /* FALLTHROUGH */
369 case 1:
370 oneHash = (cc_hashfunc[0]) (v1);
371 hashValue ^= oneHash;
372 break;
373 default:
374 elog(FATAL, "wrong number of hash keys: %d", nkeys);
375 break;
376 }
377
378 return hashValue;
379}
uint32_t uint32
Definition c.h:546
#define CACHE_elog(...)
Definition catcache.c:80
uint32(* CCHashFN)(Datum datum)
Definition catcache.h:39
#define FATAL
Definition elog.h:41
#define DEBUG2
Definition elog.h:29
#define elog(elevel,...)
Definition elog.h:226
static uint32 pg_rotate_left32(uint32 word, int n)
const char * cc_relname
Definition catcache.h:59
CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]
Definition catcache.h:50

References CatCInProgress::cache, CACHE_elog, catcache::cc_hashfunc, catcache::cc_relname, DEBUG2, elog, FATAL, fb(), 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 387 of file catcache.c.

388{
389 Datum v1 = 0,
390 v2 = 0,
391 v3 = 0,
392 v4 = 0;
393 bool isNull = false;
394 int *cc_keyno = cache->cc_keyno;
395 TupleDesc cc_tupdesc = cache->cc_tupdesc;
396
397 /* Now extract key fields from tuple, insert into scankey */
398 switch (nkeys)
399 {
400 case 4:
401 v4 = fastgetattr(tuple,
402 cc_keyno[3],
403 cc_tupdesc,
404 &isNull);
405 Assert(!isNull);
406 /* FALLTHROUGH */
407 case 3:
408 v3 = fastgetattr(tuple,
409 cc_keyno[2],
410 cc_tupdesc,
411 &isNull);
412 Assert(!isNull);
413 /* FALLTHROUGH */
414 case 2:
415 v2 = fastgetattr(tuple,
416 cc_keyno[1],
417 cc_tupdesc,
418 &isNull);
419 Assert(!isNull);
420 /* FALLTHROUGH */
421 case 1:
422 v1 = fastgetattr(tuple,
423 cc_keyno[0],
424 cc_tupdesc,
425 &isNull);
426 Assert(!isNull);
427 break;
428 default:
429 elog(FATAL, "wrong number of hash keys: %d", nkeys);
430 break;
431 }
432
433 return CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
434}
#define Assert(condition)
Definition c.h:873
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:345
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
uint64_t Datum
Definition postgres.h:70
int cc_keyno[CATCACHE_MAXKEYS]
Definition catcache.h:53
TupleDesc cc_tupdesc
Definition catcache.h:48

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

Referenced by PrepareToInvalidateCacheTuple(), and SearchCatCacheList().

◆ CatalogCacheCreateEntry()

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

Definition at line 2154 of file catcache.c.

2156{
2157 CatCTup *ct;
2159
2160 if (ntp)
2161 {
2162 int i;
2163 HeapTuple dtp = NULL;
2164
2165 /*
2166 * The invalidation of the in-progress entry essentially never happens
2167 * during our regression tests, and there's no easy way to force it to
2168 * fail for testing purposes. To ensure we have test coverage for the
2169 * retry paths in our callers, make debug builds randomly fail about
2170 * 0.1% of the times through this code path, even when there's no
2171 * toasted fields.
2172 */
2173#ifdef USE_ASSERT_CHECKING
2175 return NULL;
2176#endif
2177
2178 /*
2179 * If there are any out-of-line toasted fields in the tuple, expand
2180 * them in-line. This saves cycles during later use of the catcache
2181 * entry, and also protects us against the possibility of the toast
2182 * tuples being freed before we attempt to fetch them, in case of
2183 * something using a slightly stale catcache entry.
2184 */
2186 {
2189
2190 /*
2191 * The tuple could become stale while we are doing toast table
2192 * access (since AcceptInvalidationMessages can run then). The
2193 * invalidation will mark our in-progress entry as dead.
2194 */
2197 in_progress_ent.cache = cache;
2198 in_progress_ent.hash_value = hashValue;
2199 in_progress_ent.list = false;
2200 in_progress_ent.dead = false;
2202
2203 PG_TRY();
2204 {
2206 }
2207 PG_FINALLY();
2208 {
2211 }
2212 PG_END_TRY();
2213
2214 if (in_progress_ent.dead)
2215 {
2217 return NULL;
2218 }
2219 }
2220 else
2221 dtp = ntp;
2222
2223 /* Allocate memory for CatCTup and the cached tuple in one go */
2225
2226 ct = (CatCTup *) palloc(sizeof(CatCTup) +
2227 MAXIMUM_ALIGNOF + dtp->t_len);
2228 ct->tuple.t_len = dtp->t_len;
2229 ct->tuple.t_self = dtp->t_self;
2230 ct->tuple.t_tableOid = dtp->t_tableOid;
2231 ct->tuple.t_data = (HeapTupleHeader)
2232 MAXALIGN(((char *) ct) + sizeof(CatCTup));
2233 /* copy tuple contents */
2234 memcpy((char *) ct->tuple.t_data,
2235 (const char *) dtp->t_data,
2236 dtp->t_len);
2238
2239 if (dtp != ntp)
2241
2242 /* extract keys - they'll point into the tuple if not by-value */
2243 for (i = 0; i < cache->cc_nkeys; i++)
2244 {
2245 Datum atp;
2246 bool isnull;
2247
2248 atp = heap_getattr(&ct->tuple,
2249 cache->cc_keyno[i],
2250 cache->cc_tupdesc,
2251 &isnull);
2252 Assert(!isnull);
2253 ct->keys[i] = atp;
2254 }
2255 }
2256 else
2257 {
2258 /* Set up keys for a negative cache entry */
2261
2262 /*
2263 * Store keys - they'll point into separately allocated memory if not
2264 * by-value.
2265 */
2266 CatCacheCopyKeys(cache->cc_tupdesc, cache->cc_nkeys, cache->cc_keyno,
2267 arguments, ct->keys);
2269 }
2270
2271 /*
2272 * Finish initializing the CatCTup header, and add it to the cache's
2273 * linked list and counts.
2274 */
2275 ct->ct_magic = CT_MAGIC;
2276 ct->my_cache = cache;
2277 ct->c_list = NULL;
2278 ct->refcount = 0; /* for the moment */
2279 ct->dead = false;
2280 ct->negative = (ntp == NULL);
2281 ct->hash_value = hashValue;
2282
2283 dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem);
2284
2285 cache->cc_ntup++;
2286 CacheHdr->ch_ntup++;
2287
2288 /*
2289 * If the hash table has become too full, enlarge the buckets array. Quite
2290 * arbitrarily, we enlarge when fill factor > 2.
2291 */
2292 if (cache->cc_ntup > cache->cc_nbuckets * 2)
2293 RehashCatCache(cache);
2294
2295 return ct;
2296}
#define MAXALIGN(LEN)
Definition c.h:826
#define PG_UINT32_MAX
Definition c.h:604
static CatCInProgress * catcache_in_progress_stack
Definition catcache.c:61
static void RehashCatCache(CatCache *cp)
Definition catcache.c:992
static CatCacheHeader * CacheHdr
Definition catcache.c:84
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, const int *attnos, const Datum *srckeys, Datum *dstkeys)
Definition catcache.c:2324
#define CT_MAGIC
Definition catcache.h:99
#define PG_TRY(...)
Definition elog.h:372
#define PG_END_TRY(...)
Definition elog.h:397
#define PG_FINALLY(...)
Definition elog.h:389
#define palloc_object(type)
Definition fe_memutils.h:74
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)
static bool HeapTupleHasExternal(const HeapTupleData *tuple)
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition ilist.h:347
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CacheMemoryContext
Definition mcxt.c:169
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
uint32 pg_prng_uint32(pg_prng_state *state)
Definition pg_prng.c:227
pg_prng_state pg_global_prng_state
Definition pg_prng.c:34
struct CatCInProgress * next
Definition catcache.c:58
CatCache * cache
Definition catcache.c:54
dlist_head * cc_bucket
Definition catcache.h:49
int cc_nkeys
Definition catcache.h:54
int cc_nbuckets
Definition catcache.h:47
int cc_ntup
Definition catcache.h:55

References Assert, CatCInProgress::cache, CacheHdr, CacheMemoryContext, catcache_in_progress_stack, CatCacheCopyKeys(), catcache::cc_bucket, catcache::cc_keyno, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_tupdesc, catcacheheader::ch_ntup, CT_MAGIC, dlist_push_head(), fb(), heap_freetuple(), heap_getattr(), HeapTupleHasExternal(), i, MAXALIGN, MemoryContextSwitchTo(), CatCInProgress::next, palloc(), palloc_object, PG_END_TRY, PG_FINALLY, pg_global_prng_state, pg_prng_uint32(), PG_TRY, PG_UINT32_MAX, RehashCatCache(), and toast_flatten_tuple().

Referenced by SearchCatCacheList(), and SearchCatCacheMiss().

◆ CatalogCacheFlushCatalog()

void CatalogCacheFlushCatalog ( Oid  catId)

Definition at line 841 of file catcache.c.

842{
843 slist_iter iter;
844
845 CACHE_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
846
848 {
849 CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
850
851 /* Does this cache store tuples of the target catalog? */
852 if (cache->cc_reloid == catId)
853 {
854 /* Yes, so flush all its contents */
855 ResetCatalogCache(cache, false);
856
857 /* Tell inval.c to call syscache callbacks for this cache */
858 CallSyscacheCallbacks(cache->id, 0);
859 }
860 }
861
862 CACHE_elog(DEBUG2, "end of CatalogCacheFlushCatalog call");
863}
static void ResetCatalogCache(CatCache *cache, bool debug_discard)
Definition catcache.c:743
#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:1898
Oid cc_reloid
Definition catcache.h:60
int id
Definition catcache.h:46
slist_head ch_caches
Definition catcache.h:188
slist_node * cur
Definition ilist.h:259

References CatCInProgress::cache, 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 1136 of file catcache.c.

1137{
1138 Relation relation;
1140 TupleDesc tupdesc;
1141 int i;
1142
1144
1145 relation = table_open(cache->cc_reloid, AccessShareLock);
1146
1147 /*
1148 * switch to the cache context so our allocations do not vanish at the end
1149 * of a transaction
1150 */
1152
1154
1155 /*
1156 * copy the relcache's tuple descriptor to permanent cache storage
1157 */
1158 tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
1159
1160 /*
1161 * save the relation's name and relisshared flag, too (cc_relname is used
1162 * only for debugging purposes)
1163 */
1164 cache->cc_relname = pstrdup(RelationGetRelationName(relation));
1165 cache->cc_relisshared = RelationGetForm(relation)->relisshared;
1166
1167 /*
1168 * return to the caller's memory context and close the rel
1169 */
1171
1172 table_close(relation, AccessShareLock);
1173
1174 CACHE_elog(DEBUG2, "CatalogCacheInitializeCache: %s, %d keys",
1175 cache->cc_relname, cache->cc_nkeys);
1176
1177 /*
1178 * initialize cache's key information
1179 */
1180 for (i = 0; i < cache->cc_nkeys; ++i)
1181 {
1182 Oid keytype;
1183 RegProcedure eqfunc;
1184
1186
1187 if (cache->cc_keyno[i] > 0)
1188 {
1189 Form_pg_attribute attr = TupleDescAttr(tupdesc,
1190 cache->cc_keyno[i] - 1);
1191
1192 keytype = attr->atttypid;
1193 /* cache key columns should always be NOT NULL */
1194 Assert(attr->attnotnull);
1195 }
1196 else
1197 {
1198 if (cache->cc_keyno[i] < 0)
1199 elog(FATAL, "sys attributes are not supported in caches");
1200 keytype = OIDOID;
1201 }
1202
1204 &cache->cc_hashfunc[i],
1205 &eqfunc,
1206 &cache->cc_fastequal[i]);
1207
1208 /*
1209 * Do equality-function lookup (we assume this won't need a catalog
1210 * lookup for any supported type)
1211 */
1212 fmgr_info_cxt(eqfunc,
1213 &cache->cc_skey[i].sk_func,
1215
1216 /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
1217 cache->cc_skey[i].sk_attno = cache->cc_keyno[i];
1218
1219 /* Fill in sk_strategy as well --- always standard equality */
1221 cache->cc_skey[i].sk_subtype = InvalidOid;
1222 /* If a catcache key requires a collation, it must be C collation */
1224
1225 CACHE_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p",
1226 cache->cc_relname, i, cache);
1227 }
1228
1229 /*
1230 * mark this cache fully initialized
1231 */
1232 cache->cc_tupdesc = tupdesc;
1233}
regproc RegProcedure
Definition c.h:664
#define CatalogCacheInitializeCache_DEBUG1
Definition catcache.c:1131
static void GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
Definition catcache.c:274
#define CatalogCacheInitializeCache_DEBUG2
Definition catcache.c:1132
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition fmgr.c:138
#define AccessShareLock
Definition lockdefs.h:36
char * pstrdup(const char *in)
Definition mcxt.c:1781
FormData_pg_attribute * Form_pg_attribute
#define InvalidOid
unsigned int Oid
#define RelationGetForm(relation)
Definition rel.h:508
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetRelationName(relation)
Definition rel.h:548
#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:62
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Definition catcache.h:64
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:340
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:160

References AccessShareLock, Assert, BTEqualStrategyNumber, CatCInProgress::cache, 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, fb(), 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 ConditionalCatalogCacheInitializeCache().

◆ CatCacheCopyKeys()

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

Definition at line 2324 of file catcache.c.

2326{
2327 int i;
2328
2329 /*
2330 * XXX: memory and lookup performance could possibly be improved by
2331 * storing all keys in one allocation.
2332 */
2333
2334 for (i = 0; i < nkeys; i++)
2335 {
2336 int attnum = attnos[i];
2337 Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
2338 Datum src = srckeys[i];
2340
2341 /*
2342 * Must be careful in case the caller passed a C string where a NAME
2343 * is wanted: convert the given argument to a correctly padded NAME.
2344 * Otherwise the memcpy() done by datumCopy() could fall off the end
2345 * of memory.
2346 */
2347 if (att->atttypid == NAMEOID)
2348 {
2350 src = NameGetDatum(&srcname);
2351 }
2352
2353 dstkeys[i] = datumCopy(src,
2354 att->attbyval,
2355 att->attlen);
2356 }
2357}
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
static char * DatumGetCString(Datum X)
Definition postgres.h:365
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:403
Definition c.h:760

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

Referenced by CatalogCacheCreateEntry(), and SearchCatCacheList().

◆ CatCacheFreeKeys()

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

Definition at line 2302 of file catcache.c.

2303{
2304 int i;
2305
2306 for (i = 0; i < nkeys; i++)
2307 {
2308 int attnum = attnos[i];
2309
2310 /* system attribute are not supported in caches */
2311 Assert(attnum > 0);
2312
2313 if (!TupleDescCompactAttr(tupdesc, attnum - 1)->attbyval)
2314 pfree(DatumGetPointer(keys[i]));
2315 }
2316}
void pfree(void *pointer)
Definition mcxt.c:1616
bool attbyval
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:175

References Assert, attbyval, attnum, DatumGetPointer(), fb(), i, pfree(), and TupleDescCompactAttr().

Referenced by CatCacheRemoveCList(), and CatCacheRemoveCTup().

◆ CatCacheInvalidate()

void CatCacheInvalidate ( CatCache cache,
uint32  hashValue 
)

Definition at line 632 of file catcache.c.

633{
636
637 CACHE_elog(DEBUG2, "CatCacheInvalidate: called");
638
639 /*
640 * We don't bother to check whether the cache has finished initialization
641 * yet; if not, there will be no entries in it so no problem.
642 */
643
644 /*
645 * Invalidate *all* CatCLists in this cache; it's too hard to tell which
646 * searches might still be correct, so just zap 'em all.
647 */
648 for (int i = 0; i < cache->cc_nlbuckets; i++)
649 {
650 dlist_head *bucket = &cache->cc_lbucket[i];
651
653 {
654 CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
655
656 if (cl->refcount > 0)
657 cl->dead = true;
658 else
659 CatCacheRemoveCList(cache, cl);
660 }
661 }
662
663 /*
664 * inspect the proper hash bucket for tuple matches
665 */
666 hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
668 {
669 CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
670
671 if (hashValue == ct->hash_value)
672 {
673 if (ct->refcount > 0 ||
674 (ct->c_list && ct->c_list->refcount > 0))
675 {
676 ct->dead = true;
677 /* list, if any, was marked dead above */
678 Assert(ct->c_list == NULL || ct->c_list->dead);
679 }
680 else
681 CatCacheRemoveCTup(cache, ct);
682 CACHE_elog(DEBUG2, "CatCacheInvalidate: invalidated");
683#ifdef CATCACHE_STATS
684 cache->cc_invals++;
685#endif
686 /* could be multiple matches, so keep looking! */
687 }
688 }
689
690 /* Also invalidate any entries that are being built */
692 {
693 if (e->cache == cache)
694 {
695 if (e->list || e->hash_value == hashValue)
696 e->dead = true;
697 }
698 }
699}
unsigned int Index
Definition c.h:628
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition catcache.c:535
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Definition catcache.c:577
#define HASH_INDEX(h, sz)
Definition catcache.c:70
#define dlist_foreach_modify(iter, lhead)
Definition ilist.h:640
#define dlist_container(type, membername, ptr)
Definition ilist.h:593
e
int cc_nlbuckets
Definition catcache.h:57
dlist_head * cc_lbucket
Definition catcache.h:58
dlist_node * cur
Definition ilist.h:200

References Assert, CatCInProgress::cache, CACHE_elog, catcache_in_progress_stack, CatCacheRemoveCList(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_lbucket, catcache::cc_nbuckets, catcache::cc_nlbuckets, dlist_mutable_iter::cur, DEBUG2, dlist_container, dlist_foreach_modify, fb(), HASH_INDEX, i, and CatCInProgress::next.

Referenced by SysCacheInvalidate().

◆ CatCacheRemoveCList()

static void CatCacheRemoveCList ( CatCache cache,
CatCList cl 
)
static

Definition at line 577 of file catcache.c.

578{
579 int i;
580
581 Assert(cl->refcount == 0);
582 Assert(cl->my_cache == cache);
583
584 /* delink from member tuples */
585 for (i = cl->n_members; --i >= 0;)
586 {
587 CatCTup *ct = cl->members[i];
588
589 Assert(ct->c_list == cl);
590 ct->c_list = NULL;
591 /* if the member is dead and now has no references, remove it */
592 if (
594 ct->dead &&
595#endif
596 ct->refcount == 0)
597 CatCacheRemoveCTup(cache, ct);
598 }
599
600 /* delink from linked list */
601 dlist_delete(&cl->cache_elem);
602
603 /* free associated column data */
604 CatCacheFreeKeys(cache->cc_tupdesc, cl->nkeys,
605 cache->cc_keyno, cl->keys);
606
607 pfree(cl);
608
609 --cache->cc_nlist;
610}
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, const int *attnos, const Datum *keys)
Definition catcache.c:2302
static void dlist_delete(dlist_node *node)
Definition ilist.h:405
int cc_nlist
Definition catcache.h:56

References Assert, CatCInProgress::cache, CatCacheFreeKeys(), CatCacheRemoveCTup(), catcache::cc_keyno, catcache::cc_nlist, catcache::cc_tupdesc, dlist_delete(), fb(), i, and pfree().

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

◆ CatCacheRemoveCTup()

static void CatCacheRemoveCTup ( CatCache cache,
CatCTup ct 
)
static

Definition at line 535 of file catcache.c.

536{
537 Assert(ct->refcount == 0);
538 Assert(ct->my_cache == cache);
539
540 if (ct->c_list)
541 {
542 /*
543 * The cleanest way to handle this is to call CatCacheRemoveCList,
544 * which will recurse back to me, and the recursive call will do the
545 * work. Set the "dead" flag to make sure it does recurse.
546 */
547 ct->dead = true;
548 CatCacheRemoveCList(cache, ct->c_list);
549 return; /* nothing left to do */
550 }
551
552 /* delink from linked list */
553 dlist_delete(&ct->cache_elem);
554
555 /*
556 * Free keys when we're dealing with a negative entry, normal entries just
557 * point into tuple, allocated together with the CatCTup.
558 */
559 if (ct->negative)
560 CatCacheFreeKeys(cache->cc_tupdesc, cache->cc_nkeys,
561 cache->cc_keyno, ct->keys);
562
563 pfree(ct);
564
565 --cache->cc_ntup;
566 --CacheHdr->ch_ntup;
567}

References Assert, CatCInProgress::cache, CacheHdr, CatCacheFreeKeys(), CatCacheRemoveCList(), catcache::cc_keyno, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_tupdesc, catcacheheader::ch_ntup, dlist_delete(), fb(), and pfree().

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

◆ chareqfast()

static bool chareqfast ( Datum  a,
Datum  b 
)
static

Definition at line 191 of file catcache.c.

192{
193 return DatumGetChar(a) == DatumGetChar(b);
194}
int b
Definition isn.c:74
int a
Definition isn.c:73
static char DatumGetChar(Datum X)
Definition postgres.h:122

References a, b, and DatumGetChar().

Referenced by GetCCHashEqFuncs().

◆ charhashfast()

static uint32 charhashfast ( Datum  datum)
static

Definition at line 197 of file catcache.c.

198{
199 return murmurhash32((int32) DatumGetChar(datum));
200}
int32_t int32
Definition c.h:542
static uint32 murmurhash32(uint32 data)
Definition hashfn.h:92

References DatumGetChar(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ ConditionalCatalogCacheInitializeCache()

static pg_attribute_always_inline void ConditionalCatalogCacheInitializeCache ( CatCache cache)
static

Definition at line 1085 of file catcache.c.

1086{
1087#ifdef USE_ASSERT_CHECKING
1088 /*
1089 * TypeCacheRelCallback() runs outside transactions and relies on TYPEOID
1090 * for hashing. This isn't ideal. Since lookup_type_cache() both
1091 * registers the callback and searches TYPEOID, reaching trouble likely
1092 * requires OOM at an unlucky moment.
1093 *
1094 * InvalidateAttoptCacheCallback() runs outside transactions and likewise
1095 * relies on ATTNUM. InitPostgres() initializes ATTNUM, so it's reliable.
1096 */
1097 if (!(cache->id == TYPEOID || cache->id == ATTNUM) ||
1100 else
1101 Assert(cache->cc_tupdesc != NULL);
1102#endif
1103
1104 if (unlikely(cache->cc_tupdesc == NULL))
1106}
#define unlikely(x)
Definition c.h:412
static void CatalogCacheInitializeCache(CatCache *cache)
Definition catcache.c:1136
static void AssertCouldGetRelation(void)
Definition relcache.h:44
bool IsTransactionState(void)
Definition xact.c:388

References Assert, AssertCouldGetRelation(), CatCInProgress::cache, CatalogCacheInitializeCache(), catcache::cc_tupdesc, fb(), catcache::id, IsTransactionState(), and unlikely.

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

◆ CreateCacheMemoryContext()

void CreateCacheMemoryContext ( void  )

Definition at line 715 of file catcache.c.

716{
717 /*
718 * Purely for paranoia, check that context doesn't exist; caller probably
719 * did so already.
720 */
723 "CacheMemoryContext",
725}
MemoryContext TopMemoryContext
Definition mcxt.c:166
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160

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 1707 of file catcache.c.

1712{
1713 /*
1714 * one-time startup overhead for each cache
1715 */
1717
1718 /*
1719 * calculate the hash value
1720 */
1721 return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, v1, v2, v3, v4);
1722}
static pg_attribute_always_inline void ConditionalCatalogCacheInitializeCache(CatCache *cache)
Definition catcache.c:1085

References CatCInProgress::cache, CatalogCacheComputeHashValue(), catcache::cc_nkeys, ConditionalCatalogCacheInitializeCache(), and fb().

Referenced by GetSysCacheHashValue().

◆ GetCCHashEqFuncs()

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

Definition at line 274 of file catcache.c.

275{
276 switch (keytype)
277 {
278 case BOOLOID:
281 *eqfunc = F_BOOLEQ;
282 break;
283 case CHAROID:
286 *eqfunc = F_CHAREQ;
287 break;
288 case NAMEOID:
291 *eqfunc = F_NAMEEQ;
292 break;
293 case INT2OID:
296 *eqfunc = F_INT2EQ;
297 break;
298 case INT4OID:
301 *eqfunc = F_INT4EQ;
302 break;
303 case TEXTOID:
306 *eqfunc = F_TEXTEQ;
307 break;
308 case OIDOID:
309 case REGPROCOID:
310 case REGPROCEDUREOID:
311 case REGOPEROID:
312 case REGOPERATOROID:
313 case REGCLASSOID:
314 case REGTYPEOID:
315 case REGCOLLATIONOID:
316 case REGCONFIGOID:
317 case REGDICTIONARYOID:
318 case REGROLEOID:
319 case REGNAMESPACEOID:
320 case REGDATABASEOID:
323 *eqfunc = F_OIDEQ;
324 break;
325 case OIDVECTOROID:
328 *eqfunc = F_OIDVECTOREQ;
329 break;
330 default:
331 elog(FATAL, "type %u not supported as catcache key", keytype);
332 *hashfunc = NULL; /* keep compiler quiet */
333
334 *eqfunc = InvalidOid;
335 break;
336 }
337}
static bool chareqfast(Datum a, Datum b)
Definition catcache.c:191
static bool int4eqfast(Datum a, Datum b)
Definition catcache.c:232
static bool int2eqfast(Datum a, Datum b)
Definition catcache.c:220
static uint32 int4hashfast(Datum datum)
Definition catcache.c:238
static uint32 namehashfast(Datum datum)
Definition catcache.c:212
static bool nameeqfast(Datum a, Datum b)
Definition catcache.c:203
static uint32 charhashfast(Datum datum)
Definition catcache.c:197
static uint32 oidvectorhashfast(Datum datum)
Definition catcache.c:267
static bool texteqfast(Datum a, Datum b)
Definition catcache.c:244
static bool oidvectoreqfast(Datum a, Datum b)
Definition catcache.c:261
static uint32 int2hashfast(Datum datum)
Definition catcache.c:226
static uint32 texthashfast(Datum datum)
Definition catcache.c:254

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

Referenced by CatalogCacheInitializeCache().

◆ IndexScanOK()

static bool IndexScanOK ( CatCache cache)
static

Definition at line 1296 of file catcache.c.

1297{
1298 switch (cache->id)
1299 {
1300 case INDEXRELID:
1301
1302 /*
1303 * Rather than tracking exactly which indexes have to be loaded
1304 * before we can use indexscans (which changes from time to time),
1305 * just force all pg_index searches to be heap scans until we've
1306 * built the critical relcaches.
1307 */
1309 return false;
1310 break;
1311
1312 case AMOID:
1313 case AMNAME:
1314
1315 /*
1316 * Always do heap scans in pg_am, because it's so small there's
1317 * not much point in an indexscan anyway. We *must* do this when
1318 * initially building critical relcache entries, but we might as
1319 * well just always do it.
1320 */
1321 return false;
1322
1323 case AUTHNAME:
1324 case AUTHOID:
1325 case AUTHMEMMEMROLE:
1326 case DATABASEOID:
1327
1328 /*
1329 * Protect authentication lookups occurring before relcache has
1330 * collected entries for shared indexes.
1331 */
1333 return false;
1334 break;
1335
1336 default:
1337 break;
1338 }
1339
1340 /* Normal case, allow index scan */
1341 return true;
1342}
bool criticalRelcachesBuilt
Definition relcache.c:140
bool criticalSharedRelcachesBuilt
Definition relcache.c:146

References CatCInProgress::cache, criticalRelcachesBuilt, criticalSharedRelcachesBuilt, fb(), 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 885 of file catcache.c.

891{
892 CatCache *cp;
894 int i;
895
896 /*
897 * nbuckets is the initial number of hash buckets to use in this catcache.
898 * It will be enlarged later if it becomes too full.
899 *
900 * nbuckets must be a power of two. We check this via Assert rather than
901 * a full runtime check because the values will be coming from constant
902 * tables.
903 *
904 * If you're confused by the power-of-two check, see comments in
905 * bitmapset.c for an explanation.
906 */
907 Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
908
909 /*
910 * first switch to the cache context so our allocations do not vanish at
911 * the end of a transaction
912 */
915
917
918 /*
919 * if first time through, initialize the cache group header
920 */
921 if (CacheHdr == NULL)
922 {
925 CacheHdr->ch_ntup = 0;
926#ifdef CATCACHE_STATS
927 /* set up to dump stats at backend exit */
929#endif
930 }
931
932 /*
933 * Allocate a new cache structure, aligning to a cacheline boundary
934 *
935 * Note: we rely on zeroing to initialize all the dlist headers correctly
936 */
939 cp->cc_bucket = palloc0(nbuckets * sizeof(dlist_head));
940
941 /*
942 * Many catcaches never receive any list searches. Therefore, we don't
943 * allocate the cc_lbuckets till we get a list search.
944 */
945 cp->cc_lbucket = NULL;
946
947 /*
948 * initialize the cache's relation information for the relation
949 * corresponding to this cache, and initialize some of the new cache's
950 * other internal fields. But don't open the relation yet.
951 */
952 cp->id = id;
953 cp->cc_relname = "(not known yet)";
954 cp->cc_reloid = reloid;
955 cp->cc_indexoid = indexoid;
956 cp->cc_relisshared = false; /* temporary */
957 cp->cc_tupdesc = (TupleDesc) NULL;
958 cp->cc_ntup = 0;
959 cp->cc_nlist = 0;
960 cp->cc_nbuckets = nbuckets;
961 cp->cc_nlbuckets = 0;
962 cp->cc_nkeys = nkeys;
963 for (i = 0; i < nkeys; ++i)
964 {
966 cp->cc_keyno[i] = key[i];
967 }
968
969 /*
970 * new cache is initialized as far as we can go for now. print some
971 * debugging information, if appropriate.
972 */
974
975 /*
976 * add completed cache to top of group header's list
977 */
978 slist_push_head(&CacheHdr->ch_caches, &cp->cc_next);
979
980 /*
981 * back to the old context before we return...
982 */
984
985 return cp;
986}
#define AttributeNumberIsValid(attributeNumber)
Definition attnum.h:34
void CreateCacheMemoryContext(void)
Definition catcache.c:715
#define InitCatCache_DEBUG2
Definition catcache.c:881
#define MCXT_ALLOC_ZERO
Definition fe_memutils.h:30
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:316
void * palloc0(Size size)
Definition mcxt.c:1417
void * palloc_aligned(Size size, Size alignto, int flags)
Definition mcxt.c:1606
#define PG_CACHE_LINE_SIZE
struct TupleDescData * TupleDesc
Definition tupdesc.h:145

References Assert, AttributeNumberIsValid, CacheHdr, CacheMemoryContext, catcacheheader::ch_caches, catcacheheader::ch_ntup, CreateCacheMemoryContext(), fb(), i, InitCatCache_DEBUG2, MCXT_ALLOC_ZERO, MemoryContextSwitchTo(), on_proc_exit(), palloc0(), palloc_aligned(), palloc_object, PG_CACHE_LINE_SIZE, slist_init(), and slist_push_head().

Referenced by InitCatalogCache().

◆ InitCatCachePhase2()

void InitCatCachePhase2 ( CatCache cache,
bool  touch_index 
)

Definition at line 1245 of file catcache.c.

1246{
1248
1249 if (touch_index &&
1250 cache->id != AMOID &&
1251 cache->id != AMNAME)
1252 {
1254
1255 /*
1256 * We must lock the underlying catalog before opening the index to
1257 * avoid deadlock, since index_open could possibly result in reading
1258 * this same catalog, and if anyone else is exclusive-locking this
1259 * catalog and index they'll be doing it in that order.
1260 */
1263
1264 /*
1265 * While we've got the index open, let's check that it's unique (and
1266 * not just deferrable-unique, thank you very much). This is just to
1267 * catch thinkos in definitions of new catcaches, so we don't worry
1268 * about the pg_am indexes not getting tested.
1269 */
1270 Assert(idesc->rd_index->indisunique &&
1271 idesc->rd_index->indimmediate);
1272
1275 }
1276}
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:229
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:107
Oid cc_indexoid
Definition catcache.h:61

References AccessShareLock, Assert, CatCInProgress::cache, catcache::cc_indexoid, catcache::cc_reloid, ConditionalCatalogCacheInitializeCache(), fb(), catcache::id, index_close(), index_open(), LockRelationOid(), and UnlockRelationOid().

Referenced by InitCatalogCachePhase2(), and SysCacheGetAttr().

◆ int2eqfast()

static bool int2eqfast ( Datum  a,
Datum  b 
)
static

Definition at line 220 of file catcache.c.

221{
222 return DatumGetInt16(a) == DatumGetInt16(b);
223}
static int16 DatumGetInt16(Datum X)
Definition postgres.h:172

References a, b, and DatumGetInt16().

Referenced by GetCCHashEqFuncs().

◆ int2hashfast()

static uint32 int2hashfast ( Datum  datum)
static

Definition at line 226 of file catcache.c.

227{
228 return murmurhash32((int32) DatumGetInt16(datum));
229}

References DatumGetInt16(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ int4eqfast()

static bool int4eqfast ( Datum  a,
Datum  b 
)
static

Definition at line 232 of file catcache.c.

233{
234 return DatumGetInt32(a) == DatumGetInt32(b);
235}
static int32 DatumGetInt32(Datum X)
Definition postgres.h:212

References a, b, and DatumGetInt32().

Referenced by GetCCHashEqFuncs().

◆ int4hashfast()

static uint32 int4hashfast ( Datum  datum)
static

Definition at line 238 of file catcache.c.

239{
240 return murmurhash32((int32) DatumGetInt32(datum));
241}

References DatumGetInt32(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ nameeqfast()

static bool nameeqfast ( Datum  a,
Datum  b 
)
static

Definition at line 203 of file catcache.c.

204{
205 char *ca = NameStr(*DatumGetName(a));
206 char *cb = NameStr(*DatumGetName(b));
207
208 return strncmp(ca, cb, NAMEDATALEN) == 0;
209}
#define NameStr(name)
Definition c.h:765
#define NAMEDATALEN
static Name DatumGetName(Datum X)
Definition postgres.h:390

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

Referenced by GetCCHashEqFuncs().

◆ namehashfast()

static uint32 namehashfast ( Datum  datum)
static

Definition at line 212 of file catcache.c.

213{
214 char *key = NameStr(*DatumGetName(datum));
215
216 return hash_bytes((unsigned char *) key, strlen(key));
217}
uint32 hash_bytes(const unsigned char *k, int keylen)
Definition hashfn.c:146

References DatumGetName(), fb(), hash_bytes(), and NameStr.

Referenced by GetCCHashEqFuncs().

◆ oidvectoreqfast()

static bool oidvectoreqfast ( Datum  a,
Datum  b 
)
static

Definition at line 261 of file catcache.c.

262{
264}
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:686
Datum oidvectoreq(PG_FUNCTION_ARGS)
Definition oid.c:344
static bool DatumGetBool(Datum X)
Definition postgres.h:100

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

Referenced by GetCCHashEqFuncs().

◆ oidvectorhashfast()

static uint32 oidvectorhashfast ( Datum  datum)
static

Definition at line 267 of file catcache.c.

268{
270}
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
Datum hashoidvector(PG_FUNCTION_ARGS)
Definition hashfunc.c:232

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

Referenced by GetCCHashEqFuncs().

◆ PrepareToInvalidateCacheTuple()

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

Definition at line 2394 of file catcache.c.

2399{
2400 slist_iter iter;
2401 Oid reloid;
2402
2403 CACHE_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
2404
2405 /*
2406 * sanity checks
2407 */
2408 Assert(RelationIsValid(relation));
2409 Assert(HeapTupleIsValid(tuple));
2411 Assert(CacheHdr != NULL);
2412
2413 reloid = RelationGetRelid(relation);
2414
2415 /* ----------------
2416 * for each cache
2417 * if the cache contains tuples from the specified relation
2418 * compute the tuple's hash value(s) in this cache,
2419 * and call the passed function to register the information.
2420 * ----------------
2421 */
2422
2424 {
2425 CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
2426 uint32 hashvalue;
2427 Oid dbid;
2428
2429 if (ccp->cc_reloid != reloid)
2430 continue;
2431
2432 /* Just in case cache hasn't finished initialization yet... */
2434
2435 hashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, tuple);
2436 dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
2437
2438 (*function) (ccp->id, hashvalue, dbid, context);
2439
2440 if (newtuple)
2441 {
2443
2444 newhashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, newtuple);
2445
2446 if (newhashvalue != hashvalue)
2447 (*function) (ccp->id, newhashvalue, dbid, context);
2448 }
2449 }
2450}
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
Definition catcache.c:387
Oid MyDatabaseId
Definition globals.c:94
#define HeapTupleIsValid(tuple)
Definition htup.h:78
on_exit_nicely_callback function
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationIsValid(relation)
Definition rel.h:489

References Assert, CACHE_elog, CacheHdr, CatalogCacheComputeTupleHashValue(), catcacheheader::ch_caches, ConditionalCatalogCacheInitializeCache(), slist_iter::cur, DEBUG2, fb(), function, HeapTupleIsValid, MyDatabaseId, RelationGetRelid, RelationIsValid, slist_container, and slist_foreach.

Referenced by CacheInvalidateHeapTupleCommon().

◆ RehashCatCache()

static void RehashCatCache ( CatCache cp)
static

Definition at line 992 of file catcache.c.

993{
995 int newnbuckets;
996 int i;
997
998 elog(DEBUG1, "rehashing catalog cache id %d for %s; %d tups, %d buckets",
999 cp->id, cp->cc_relname, cp->cc_ntup, cp->cc_nbuckets);
1000
1001 /* Allocate a new, larger, hash table. */
1002 newnbuckets = cp->cc_nbuckets * 2;
1004
1005 /* Move all entries from old hash table to new. */
1006 for (i = 0; i < cp->cc_nbuckets; i++)
1007 {
1008 dlist_mutable_iter iter;
1009
1010 dlist_foreach_modify(iter, &cp->cc_bucket[i])
1011 {
1012 CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
1013 int hashIndex = HASH_INDEX(ct->hash_value, newnbuckets);
1014
1015 dlist_delete(iter.cur);
1016
1017 /*
1018 * Note that each item is pushed at the tail of the new bucket,
1019 * not its head. This is consistent with the SearchCatCache*()
1020 * routines, where matching entries are moved at the front of the
1021 * list to speed subsequent searches.
1022 */
1023 dlist_push_tail(&newbucket[hashIndex], &ct->cache_elem);
1024 }
1025 }
1026
1027 /* Switch to the new array. */
1028 pfree(cp->cc_bucket);
1029 cp->cc_nbuckets = newnbuckets;
1030 cp->cc_bucket = newbucket;
1031}
#define DEBUG1
Definition elog.h:30
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition ilist.h:364
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266

References CacheMemoryContext, dlist_mutable_iter::cur, DEBUG1, dlist_container, dlist_delete(), dlist_foreach_modify, dlist_push_tail(), elog, fb(), HASH_INDEX, i, MemoryContextAllocZero(), and pfree().

Referenced by CatalogCacheCreateEntry().

◆ RehashCatCacheLists()

static void RehashCatCacheLists ( CatCache cp)
static

Definition at line 1037 of file catcache.c.

1038{
1040 int newnbuckets;
1041 int i;
1042
1043 elog(DEBUG1, "rehashing catalog cache id %d for %s; %d lists, %d buckets",
1044 cp->id, cp->cc_relname, cp->cc_nlist, cp->cc_nlbuckets);
1045
1046 /* Allocate a new, larger, hash table. */
1047 newnbuckets = cp->cc_nlbuckets * 2;
1049
1050 /* Move all entries from old hash table to new. */
1051 for (i = 0; i < cp->cc_nlbuckets; i++)
1052 {
1053 dlist_mutable_iter iter;
1054
1055 dlist_foreach_modify(iter, &cp->cc_lbucket[i])
1056 {
1057 CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
1058 int hashIndex = HASH_INDEX(cl->hash_value, newnbuckets);
1059
1060 dlist_delete(iter.cur);
1061
1062 /*
1063 * Note that each item is pushed at the tail of the new bucket,
1064 * not its head. This is consistent with the SearchCatCache*()
1065 * routines, where matching entries are moved at the front of the
1066 * list to speed subsequent searches.
1067 */
1068 dlist_push_tail(&newbucket[hashIndex], &cl->cache_elem);
1069 }
1070 }
1071
1072 /* Switch to the new array. */
1073 pfree(cp->cc_lbucket);
1074 cp->cc_nlbuckets = newnbuckets;
1075 cp->cc_lbucket = newbucket;
1076}

References CacheMemoryContext, dlist_mutable_iter::cur, DEBUG1, dlist_container, dlist_delete(), dlist_foreach_modify, dlist_push_tail(), elog, fb(), HASH_INDEX, i, MemoryContextAllocZero(), and pfree().

Referenced by SearchCatCacheList().

◆ ReleaseCatCache()

void ReleaseCatCache ( HeapTuple  tuple)

Definition at line 1668 of file catcache.c.

1669{
1671}
static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner)
Definition catcache.c:1674
ResourceOwner CurrentResourceOwner
Definition resowner.c:173

References CurrentResourceOwner, and ReleaseCatCacheWithOwner().

Referenced by ReleaseSysCache().

◆ ReleaseCatCacheList()

◆ ReleaseCatCacheListWithOwner()

static void ReleaseCatCacheListWithOwner ( CatCList list,
ResourceOwner  resowner 
)
static

Definition at line 2120 of file catcache.c.

2121{
2122 /* Safety checks to ensure we were handed a cache entry */
2123 Assert(list->cl_magic == CL_MAGIC);
2124 Assert(list->refcount > 0);
2125 list->refcount--;
2126 if (resowner)
2127 ResourceOwnerForgetCatCacheListRef(resowner, list);
2128
2129 if (
2131 list->dead &&
2132#endif
2133 list->refcount == 0)
2134 CatCacheRemoveCList(list->my_cache, list);
2135}
static void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition catcache.c:174
#define CL_MAGIC
Definition catcache.h:166

References Assert, CatCacheRemoveCList(), CL_MAGIC, fb(), CatCInProgress::list, and ResourceOwnerForgetCatCacheListRef().

Referenced by ReleaseCatCacheList(), and ResOwnerReleaseCatCacheList().

◆ ReleaseCatCacheWithOwner()

static void ReleaseCatCacheWithOwner ( HeapTuple  tuple,
ResourceOwner  resowner 
)
static

Definition at line 1674 of file catcache.c.

1675{
1676 CatCTup *ct = (CatCTup *) (((char *) tuple) -
1677 offsetof(CatCTup, tuple));
1678
1679 /* Safety checks to ensure we were handed a cache entry */
1680 Assert(ct->ct_magic == CT_MAGIC);
1681 Assert(ct->refcount > 0);
1682
1683 ct->refcount--;
1684 if (resowner)
1685 ResourceOwnerForgetCatCacheRef(resowner, &ct->tuple);
1686
1687 if (
1689 ct->dead &&
1690#endif
1691 ct->refcount == 0 &&
1692 (ct->c_list == NULL || ct->c_list->refcount == 0))
1693 CatCacheRemoveCTup(ct->my_cache, ct);
1694}
static void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition catcache.c:164

References Assert, CatCacheRemoveCTup(), CT_MAGIC, fb(), and ResourceOwnerForgetCatCacheRef().

Referenced by ReleaseCatCache(), and ResOwnerReleaseCatCache().

◆ ResetCatalogCache()

static void ResetCatalogCache ( CatCache cache,
bool  debug_discard 
)
static

Definition at line 743 of file catcache.c.

744{
746 int i;
747
748 /* Remove each list in this cache, or at least mark it dead */
749 for (i = 0; i < cache->cc_nlbuckets; i++)
750 {
751 dlist_head *bucket = &cache->cc_lbucket[i];
752
754 {
755 CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
756
757 if (cl->refcount > 0)
758 cl->dead = true;
759 else
760 CatCacheRemoveCList(cache, cl);
761 }
762 }
763
764 /* Remove each tuple in this cache, or at least mark it dead */
765 for (i = 0; i < cache->cc_nbuckets; i++)
766 {
767 dlist_head *bucket = &cache->cc_bucket[i];
768
770 {
771 CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
772
773 if (ct->refcount > 0 ||
774 (ct->c_list && ct->c_list->refcount > 0))
775 {
776 ct->dead = true;
777 /* list, if any, was marked dead above */
778 Assert(ct->c_list == NULL || ct->c_list->dead);
779 }
780 else
781 CatCacheRemoveCTup(cache, ct);
782#ifdef CATCACHE_STATS
783 cache->cc_invals++;
784#endif
785 }
786 }
787
788 /* Also invalidate any entries that are being built */
789 if (!debug_discard)
790 {
792 {
793 if (e->cache == cache)
794 e->dead = true;
795 }
796 }
797}

References Assert, CatCInProgress::cache, catcache_in_progress_stack, CatCacheRemoveCList(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_lbucket, catcache::cc_nbuckets, catcache::cc_nlbuckets, dlist_mutable_iter::cur, dlist_container, dlist_foreach_modify, fb(), i, and CatCInProgress::next.

Referenced by CatalogCacheFlushCatalog(), and ResetCatalogCachesExt().

◆ ResetCatalogCaches()

void ResetCatalogCaches ( void  )

Definition at line 805 of file catcache.c.

806{
808}
void ResetCatalogCachesExt(bool debug_discard)
Definition catcache.c:811

References ResetCatalogCachesExt().

◆ ResetCatalogCachesExt()

void ResetCatalogCachesExt ( bool  debug_discard)

Definition at line 811 of file catcache.c.

812{
813 slist_iter iter;
814
815 CACHE_elog(DEBUG2, "ResetCatalogCaches called");
816
818 {
819 CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
820
822 }
823
824 CACHE_elog(DEBUG2, "end of ResetCatalogCaches call");
825}

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

Referenced by InvalidateSystemCachesExtended(), and ResetCatalogCaches().

◆ ResourceOwnerForgetCatCacheListRef()

static void ResourceOwnerForgetCatCacheListRef ( ResourceOwner  owner,
CatCList list 
)
inlinestatic

Definition at line 174 of file catcache.c.

175{
177}
static const ResourceOwnerDesc catlistref_resowner_desc
Definition catcache.c:147
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:561

References catlistref_resowner_desc, CatCInProgress::list, PointerGetDatum(), and ResourceOwnerForget().

Referenced by ReleaseCatCacheListWithOwner().

◆ ResourceOwnerForgetCatCacheRef()

static void ResourceOwnerForgetCatCacheRef ( ResourceOwner  owner,
HeapTuple  tuple 
)
inlinestatic

Definition at line 164 of file catcache.c.

165{
167}
static const ResourceOwnerDesc catcache_resowner_desc
Definition catcache.c:137

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

Referenced by ReleaseCatCacheWithOwner().

◆ ResourceOwnerRememberCatCacheListRef()

static void ResourceOwnerRememberCatCacheListRef ( ResourceOwner  owner,
CatCList list 
)
inlinestatic

Definition at line 169 of file catcache.c.

170{
172}
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:521

References catlistref_resowner_desc, CatCInProgress::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 2461 of file catcache.c.

2462{
2463 HeapTuple tuple = (HeapTuple) DatumGetPointer(res);
2464 CatCTup *ct = (CatCTup *) (((char *) tuple) -
2465 offsetof(CatCTup, tuple));
2466
2467 /* Safety check to ensure we were handed a cache entry */
2468 Assert(ct->ct_magic == CT_MAGIC);
2469
2470 return psprintf("cache %s (%d), tuple %u/%u has count %d",
2471 ct->my_cache->cc_relname, ct->my_cache->id,
2474 ct->refcount);
2475}
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:43
ItemPointerData t_self
Definition htup.h:65

References Assert, CT_MAGIC, DatumGetPointer(), fb(), ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), psprintf(), and HeapTupleData::t_self.

◆ ResOwnerPrintCatCacheList()

static char * ResOwnerPrintCatCacheList ( Datum  res)
static

Definition at line 2484 of file catcache.c.

2485{
2487
2488 return psprintf("cache %s (%d), list %p has count %d",
2489 list->my_cache->cc_relname, list->my_cache->id,
2490 list, list->refcount);
2491}

References DatumGetPointer(), CatCInProgress::list, and psprintf().

◆ ResOwnerReleaseCatCache()

static void ResOwnerReleaseCatCache ( Datum  res)
static

Definition at line 2455 of file catcache.c.

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

◆ ResOwnerReleaseCatCacheList()

static void ResOwnerReleaseCatCacheList ( Datum  res)
static

Definition at line 2478 of file catcache.c.

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

◆ SearchCatCache()

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

Definition at line 1361 of file catcache.c.

1366{
1367 return SearchCatCacheInternal(cache, cache->cc_nkeys, v1, v2, v3, v4);
1368}
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1412

References CatCInProgress::cache, catcache::cc_nkeys, fb(), and SearchCatCacheInternal().

Referenced by SearchSysCache().

◆ SearchCatCache1()

HeapTuple SearchCatCache1 ( CatCache cache,
Datum  v1 
)

Definition at line 1378 of file catcache.c.

1380{
1381 return SearchCatCacheInternal(cache, 1, v1, 0, 0, 0);
1382}

References CatCInProgress::cache, fb(), and SearchCatCacheInternal().

Referenced by SearchSysCache1().

◆ SearchCatCache2()

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

Definition at line 1386 of file catcache.c.

1388{
1389 return SearchCatCacheInternal(cache, 2, v1, v2, 0, 0);
1390}

References CatCInProgress::cache, fb(), and SearchCatCacheInternal().

Referenced by SearchSysCache2().

◆ SearchCatCache3()

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

Definition at line 1394 of file catcache.c.

1396{
1397 return SearchCatCacheInternal(cache, 3, v1, v2, v3, 0);
1398}

References CatCInProgress::cache, fb(), and SearchCatCacheInternal().

Referenced by SearchSysCache3().

◆ SearchCatCache4()

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

Definition at line 1402 of file catcache.c.

1404{
1405 return SearchCatCacheInternal(cache, 4, v1, v2, v3, v4);
1406}

References CatCInProgress::cache, fb(), and SearchCatCacheInternal().

Referenced by SearchSysCache4().

◆ SearchCatCacheInternal()

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

Definition at line 1412 of file catcache.c.

1418{
1420 uint32 hashValue;
1422 dlist_iter iter;
1424 CatCTup *ct;
1425
1426 Assert(cache->cc_nkeys == nkeys);
1427
1428 /*
1429 * one-time startup overhead for each cache
1430 */
1432
1433#ifdef CATCACHE_STATS
1434 cache->cc_searches++;
1435#endif
1436
1437 /* Initialize local parameter array */
1438 arguments[0] = v1;
1439 arguments[1] = v2;
1440 arguments[2] = v3;
1441 arguments[3] = v4;
1442
1443 /*
1444 * find the hash bucket in which to look for the tuple
1445 */
1446 hashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
1447 hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1448
1449 /*
1450 * scan the hash bucket until we find a match or exhaust our tuples
1451 *
1452 * Note: it's okay to use dlist_foreach here, even though we modify the
1453 * dlist within the loop, because we don't continue the loop afterwards.
1454 */
1455 bucket = &cache->cc_bucket[hashIndex];
1456 dlist_foreach(iter, bucket)
1457 {
1458 ct = dlist_container(CatCTup, cache_elem, iter.cur);
1459
1460 if (ct->dead)
1461 continue; /* ignore dead entries */
1462
1463 if (ct->hash_value != hashValue)
1464 continue; /* quickly skip entry if wrong hash val */
1465
1466 if (!CatalogCacheCompareTuple(cache, nkeys, ct->keys, arguments))
1467 continue;
1468
1469 /*
1470 * We found a match in the cache. Move it to the front of the list
1471 * for its hashbucket, in order to speed subsequent searches. (The
1472 * most frequently accessed elements in any hashbucket will tend to be
1473 * near the front of the hashbucket's list.)
1474 */
1475 dlist_move_head(bucket, &ct->cache_elem);
1476
1477 /*
1478 * If it's a positive entry, bump its refcount and return it. If it's
1479 * negative, we can report failure to the caller.
1480 */
1481 if (!ct->negative)
1482 {
1484 ct->refcount++;
1486
1487 CACHE_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d",
1488 cache->cc_relname, hashIndex);
1489
1490#ifdef CATCACHE_STATS
1491 cache->cc_hits++;
1492#endif
1493
1494 return &ct->tuple;
1495 }
1496 else
1497 {
1498 CACHE_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d",
1499 cache->cc_relname, hashIndex);
1500
1501#ifdef CATCACHE_STATS
1502 cache->cc_neg_hits++;
1503#endif
1504
1505 return NULL;
1506 }
1507 }
1508
1509 return SearchCatCacheMiss(cache, nkeys, hashValue, hashIndex, v1, v2, v3, v4);
1510}
static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1520
static void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition catcache.c:159
static bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
Definition catcache.c:442
#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:449
dlist_node * cur
Definition ilist.h:179

References Assert, CatCInProgress::cache, CACHE_elog, CatalogCacheCompareTuple(), CatalogCacheComputeHashValue(), CATCACHE_MAXKEYS, catcache::cc_bucket, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_relname, ConditionalCatalogCacheInitializeCache(), dlist_iter::cur, CurrentResourceOwner, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), fb(), HASH_INDEX, ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheRef(), and SearchCatCacheMiss().

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

◆ SearchCatCacheList()

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

Definition at line 1740 of file catcache.c.

1745{
1746 Datum v4 = 0; /* dummy last-column value */
1750 dlist_iter iter;
1752 CatCList *cl;
1753 CatCTup *ct;
1754 List *volatile ctlist;
1756 int nmembers;
1757 bool ordered;
1758 HeapTuple ntp;
1760 int i;
1763
1764 /*
1765 * one-time startup overhead for each cache
1766 */
1768
1769 Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1770
1771#ifdef CATCACHE_STATS
1772 cache->cc_lsearches++;
1773#endif
1774
1775 /* Initialize local parameter array */
1776 arguments[0] = v1;
1777 arguments[1] = v2;
1778 arguments[2] = v3;
1779 arguments[3] = v4;
1780
1781 /*
1782 * If we haven't previously done a list search in this cache, create the
1783 * bucket header array; otherwise, consider whether it's time to enlarge
1784 * it.
1785 */
1786 if (cache->cc_lbucket == NULL)
1787 {
1788 /* Arbitrary initial size --- must be a power of 2 */
1789 int nbuckets = 16;
1790
1791 cache->cc_lbucket = (dlist_head *)
1793 nbuckets * sizeof(dlist_head));
1794 /* Don't set cc_nlbuckets if we get OOM allocating cc_lbucket */
1795 cache->cc_nlbuckets = nbuckets;
1796 }
1797 else
1798 {
1799 /*
1800 * If the hash table has become too full, enlarge the buckets array.
1801 * Quite arbitrarily, we enlarge when fill factor > 2.
1802 */
1803 if (cache->cc_nlist > cache->cc_nlbuckets * 2)
1804 RehashCatCacheLists(cache);
1805 }
1806
1807 /*
1808 * Find the hash bucket in which to look for the CatCList.
1809 */
1810 lHashValue = CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
1812
1813 /*
1814 * scan the items until we find a match or exhaust our list
1815 *
1816 * Note: it's okay to use dlist_foreach here, even though we modify the
1817 * dlist within the loop, because we don't continue the loop afterwards.
1818 */
1819 lbucket = &cache->cc_lbucket[lHashIndex];
1820 dlist_foreach(iter, lbucket)
1821 {
1822 cl = dlist_container(CatCList, cache_elem, iter.cur);
1823
1824 if (cl->dead)
1825 continue; /* ignore dead entries */
1826
1827 if (cl->hash_value != lHashValue)
1828 continue; /* quickly skip entry if wrong hash val */
1829
1830 /*
1831 * see if the cached list matches our key.
1832 */
1833 if (cl->nkeys != nkeys)
1834 continue;
1835
1836 if (!CatalogCacheCompareTuple(cache, nkeys, cl->keys, arguments))
1837 continue;
1838
1839 /*
1840 * We found a matching list. Move the list to the front of the list
1841 * for its hashbucket, so as to speed subsequent searches. (We do not
1842 * move the members to the fronts of their hashbucket lists, however,
1843 * since there's no point in that unless they are searched for
1844 * individually.)
1845 */
1846 dlist_move_head(lbucket, &cl->cache_elem);
1847
1848 /* Bump the list's refcount and return it */
1850 cl->refcount++;
1852
1853 CACHE_elog(DEBUG2, "SearchCatCacheList(%s): found list",
1854 cache->cc_relname);
1855
1856#ifdef CATCACHE_STATS
1857 cache->cc_lhits++;
1858#endif
1859
1860 return cl;
1861 }
1862
1863 /*
1864 * List was not found in cache, so we have to build it by reading the
1865 * relation. For each matching tuple found in the relation, use an
1866 * existing cache entry if possible, else build a new one.
1867 *
1868 * We have to bump the member refcounts temporarily to ensure they won't
1869 * get dropped from the cache while loading other members. We use a PG_TRY
1870 * block to ensure we can undo those refcounts if we get an error before
1871 * we finish constructing the CatCList. ctlist must be valid throughout
1872 * the PG_TRY block.
1873 */
1874 ctlist = NIL;
1875
1876 /*
1877 * Cache invalidation can happen while we're building the list.
1878 * CatalogCacheCreateEntry() handles concurrent invalidation of individual
1879 * tuples, but it's also possible that a new entry is concurrently added
1880 * that should be part of the list we're building. Register an
1881 * "in-progress" entry that will receive the invalidation, until we have
1882 * built the final list entry.
1883 */
1886 in_progress_ent.cache = cache;
1887 in_progress_ent.hash_value = lHashValue;
1888 in_progress_ent.list = true;
1889 in_progress_ent.dead = false;
1891
1892 PG_TRY();
1893 {
1895 Relation relation;
1896 SysScanDesc scandesc;
1897 bool first_iter = true;
1898
1899 relation = table_open(cache->cc_reloid, AccessShareLock);
1900
1901 /*
1902 * Ok, need to make a lookup in the relation, copy the scankey and
1903 * fill out any per-call fields.
1904 */
1905 memcpy(cur_skey, cache->cc_skey, sizeof(ScanKeyData) * cache->cc_nkeys);
1906 cur_skey[0].sk_argument = v1;
1907 cur_skey[1].sk_argument = v2;
1908 cur_skey[2].sk_argument = v3;
1909 cur_skey[3].sk_argument = v4;
1910
1911 /*
1912 * Scan the table for matching entries. If an invalidation arrives
1913 * mid-build, we will loop back here to retry.
1914 */
1915 do
1916 {
1917 /*
1918 * If we are retrying, release refcounts on any items created on
1919 * the previous iteration. We dare not try to free them if
1920 * they're now unreferenced, since an error while doing that would
1921 * result in the PG_CATCH below doing extra refcount decrements.
1922 * Besides, we'll likely re-adopt those items in the next
1923 * iteration, so it's not worth complicating matters to try to get
1924 * rid of them.
1925 */
1926 foreach(ctlist_item, ctlist)
1927 {
1929 Assert(ct->c_list == NULL);
1930 Assert(ct->refcount > 0);
1931 ct->refcount--;
1932 }
1933 /* Reset ctlist in preparation for new try */
1934 ctlist = NIL;
1935 in_progress_ent.dead = false;
1936
1937 scandesc = systable_beginscan(relation,
1938 cache->cc_indexoid,
1939 IndexScanOK(cache),
1940 NULL,
1941 nkeys,
1942 cur_skey);
1943
1944 /* The list will be ordered iff we are doing an index scan */
1945 ordered = (scandesc->irel != NULL);
1946
1947 /* Injection point to help testing the recursive invalidation case */
1948 if (first_iter)
1949 {
1950 INJECTION_POINT("catcache-list-miss-systable-scan-started", NULL);
1951 first_iter = false;
1952 }
1953
1954 while (HeapTupleIsValid(ntp = systable_getnext(scandesc)) &&
1955 !in_progress_ent.dead)
1956 {
1957 uint32 hashValue;
1959 bool found = false;
1961
1962 /*
1963 * See if there's an entry for this tuple already.
1964 */
1965 ct = NULL;
1966 hashValue = CatalogCacheComputeTupleHashValue(cache, cache->cc_nkeys, ntp);
1967 hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1968
1969 bucket = &cache->cc_bucket[hashIndex];
1970 dlist_foreach(iter, bucket)
1971 {
1972 ct = dlist_container(CatCTup, cache_elem, iter.cur);
1973
1974 if (ct->dead || ct->negative)
1975 continue; /* ignore dead and negative entries */
1976
1977 if (ct->hash_value != hashValue)
1978 continue; /* quickly skip entry if wrong hash val */
1979
1980 if (!ItemPointerEquals(&(ct->tuple.t_self), &(ntp->t_self)))
1981 continue; /* not same tuple */
1982
1983 /*
1984 * Found a match, but can't use it if it belongs to
1985 * another list already
1986 */
1987 if (ct->c_list)
1988 continue;
1989
1990 found = true;
1991 break; /* A-OK */
1992 }
1993
1994 if (!found)
1995 {
1996 /* We didn't find a usable entry, so make a new one */
1998 hashValue, hashIndex);
1999
2000 /* upon failure, we must start the scan over */
2001 if (ct == NULL)
2002 {
2003 in_progress_ent.dead = true;
2004 break;
2005 }
2006 }
2007
2008 /* Careful here: add entry to ctlist, then bump its refcount */
2009 /* This way leaves state correct if lappend runs out of memory */
2010 ctlist = lappend(ctlist, ct);
2011 ct->refcount++;
2012 }
2013
2014 systable_endscan(scandesc);
2015 } while (in_progress_ent.dead);
2016
2017 table_close(relation, AccessShareLock);
2018
2019 /* Make sure the resource owner has room to remember this entry. */
2021
2022 /* Now we can build the CatCList entry. */
2024 nmembers = list_length(ctlist);
2025 cl = (CatCList *)
2026 palloc(offsetof(CatCList, members) + nmembers * sizeof(CatCTup *));
2027
2028 /* Extract key values */
2029 CatCacheCopyKeys(cache->cc_tupdesc, nkeys, cache->cc_keyno,
2030 arguments, cl->keys);
2032
2033 /*
2034 * We are now past the last thing that could trigger an elog before we
2035 * have finished building the CatCList and remembering it in the
2036 * resource owner. So it's OK to fall out of the PG_TRY, and indeed
2037 * we'd better do so before we start marking the members as belonging
2038 * to the list.
2039 */
2040 }
2041 PG_CATCH();
2042 {
2045
2046 foreach(ctlist_item, ctlist)
2047 {
2049 Assert(ct->c_list == NULL);
2050 Assert(ct->refcount > 0);
2051 ct->refcount--;
2052 if (
2054 ct->dead &&
2055#endif
2056 ct->refcount == 0 &&
2057 (ct->c_list == NULL || ct->c_list->refcount == 0))
2058 CatCacheRemoveCTup(cache, ct);
2059 }
2060
2061 PG_RE_THROW();
2062 }
2063 PG_END_TRY();
2066
2067 cl->cl_magic = CL_MAGIC;
2068 cl->my_cache = cache;
2069 cl->refcount = 0; /* for the moment */
2070 cl->dead = false;
2071 cl->ordered = ordered;
2072 cl->nkeys = nkeys;
2073 cl->hash_value = lHashValue;
2074 cl->n_members = nmembers;
2075
2076 i = 0;
2077 foreach(ctlist_item, ctlist)
2078 {
2079 cl->members[i++] = ct = (CatCTup *) lfirst(ctlist_item);
2080 Assert(ct->c_list == NULL);
2081 ct->c_list = cl;
2082 /* release the temporary refcount on the member */
2083 Assert(ct->refcount > 0);
2084 ct->refcount--;
2085 /* mark list dead if any members already dead */
2086 if (ct->dead)
2087 cl->dead = true;
2088 }
2089 Assert(i == nmembers);
2090
2091 /*
2092 * Add the CatCList to the appropriate bucket, and count it.
2093 */
2094 dlist_push_head(lbucket, &cl->cache_elem);
2095
2096 cache->cc_nlist++;
2097
2098 /* Finally, bump the list's refcount and return it */
2099 cl->refcount++;
2101
2102 CACHE_elog(DEBUG2, "SearchCatCacheList(%s): made list of %d members",
2103 cache->cc_relname, nmembers);
2104
2105 return cl;
2106}
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments, uint32 hashValue, Index hashIndex)
Definition catcache.c:2154
static bool IndexScanOK(CatCache *cache)
Definition catcache.c:1296
static void RehashCatCacheLists(CatCache *cp)
Definition catcache.c:1037
static void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition catcache.c:169
#define PG_RE_THROW()
Definition elog.h:405
#define PG_CATCH(...)
Definition elog.h:382
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
#define INJECTION_POINT(name, arg)
bool ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *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
Relation irel
Definition relscan.h:211

References AccessShareLock, Assert, CatCInProgress::cache, CACHE_elog, CacheMemoryContext, CatalogCacheCompareTuple(), CatalogCacheComputeHashValue(), CatalogCacheComputeTupleHashValue(), CatalogCacheCreateEntry(), catcache_in_progress_stack, CATCACHE_MAXKEYS, CatCacheCopyKeys(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_keyno, catcache::cc_lbucket, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_nlbuckets, catcache::cc_nlist, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcache::cc_tupdesc, CL_MAGIC, ConditionalCatalogCacheInitializeCache(), dlist_iter::cur, CurrentResourceOwner, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), dlist_push_head(), fb(), HASH_INDEX, HeapTupleIsValid, i, IndexScanOK(), INJECTION_POINT, SysScanDescData::irel, ItemPointerEquals(), lappend(), lfirst, list_length(), MemoryContextAllocZero(), MemoryContextSwitchTo(), CatCInProgress::next, NIL, palloc(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, RehashCatCacheLists(), ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheListRef(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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 1520 of file catcache.c.

1528{
1530 Relation relation;
1531 SysScanDesc scandesc;
1532 HeapTuple ntp;
1533 CatCTup *ct;
1534 bool stale;
1536
1537 /* Initialize local parameter array */
1538 arguments[0] = v1;
1539 arguments[1] = v2;
1540 arguments[2] = v3;
1541 arguments[3] = v4;
1542
1543 /*
1544 * Tuple was not found in cache, so we have to try to retrieve it directly
1545 * from the relation. If found, we will add it to the cache; if not
1546 * found, we will add a negative cache entry instead.
1547 *
1548 * NOTE: it is possible for recursive cache lookups to occur while reading
1549 * the relation --- for example, due to shared-cache-inval messages being
1550 * processed during table_open(). This is OK. It's even possible for one
1551 * of those lookups to find and enter the very same tuple we are trying to
1552 * fetch here. If that happens, we will enter a second copy of the tuple
1553 * into the cache. The first copy will never be referenced again, and
1554 * will eventually age out of the cache, so there's no functional problem.
1555 * This case is rare enough that it's not worth expending extra cycles to
1556 * detect.
1557 *
1558 * Another case, which we *must* handle, is that the tuple could become
1559 * outdated during CatalogCacheCreateEntry's attempt to detoast it (since
1560 * AcceptInvalidationMessages can run during TOAST table access). We do
1561 * not want to return already-stale catcache entries, so we loop around
1562 * and do the table scan again if that happens.
1563 */
1564 relation = table_open(cache->cc_reloid, AccessShareLock);
1565
1566 /*
1567 * Ok, need to make a lookup in the relation, copy the scankey and fill
1568 * out any per-call fields.
1569 */
1570 memcpy(cur_skey, cache->cc_skey, sizeof(ScanKeyData) * nkeys);
1571 cur_skey[0].sk_argument = v1;
1572 cur_skey[1].sk_argument = v2;
1573 cur_skey[2].sk_argument = v3;
1574 cur_skey[3].sk_argument = v4;
1575
1576 do
1577 {
1578 scandesc = systable_beginscan(relation,
1579 cache->cc_indexoid,
1580 IndexScanOK(cache),
1581 NULL,
1582 nkeys,
1583 cur_skey);
1584
1585 ct = NULL;
1586 stale = false;
1587
1588 while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
1589 {
1591 hashValue, hashIndex);
1592 /* upon failure, we must start the scan over */
1593 if (ct == NULL)
1594 {
1595 stale = true;
1596 break;
1597 }
1598 /* immediately set the refcount to 1 */
1600 ct->refcount++;
1602 break; /* assume only one match */
1603 }
1604
1605 systable_endscan(scandesc);
1606 } while (stale);
1607
1608 table_close(relation, AccessShareLock);
1609
1610 /*
1611 * If tuple was not found, we need to build a negative cache entry
1612 * containing a fake tuple. The fake tuple has the correct key columns,
1613 * but nulls everywhere else.
1614 *
1615 * In bootstrap mode, we don't build negative entries, because the cache
1616 * invalidation mechanism isn't alive and can't clear them if the tuple
1617 * gets created later. (Bootstrap doesn't do UPDATEs, so it doesn't need
1618 * cache inval for that.)
1619 */
1620 if (ct == NULL)
1621 {
1623 return NULL;
1624
1626 hashValue, hashIndex);
1627
1628 /* Creating a negative cache entry shouldn't fail */
1629 Assert(ct != NULL);
1630
1631 CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1632 cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1633 CACHE_elog(DEBUG2, "SearchCatCache(%s): put neg entry in bucket %d",
1634 cache->cc_relname, hashIndex);
1635
1636 /*
1637 * We are not returning the negative entry to the caller, so leave its
1638 * refcount zero.
1639 */
1640
1641 return NULL;
1642 }
1643
1644 CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1645 cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1646 CACHE_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d",
1647 cache->cc_relname, hashIndex);
1648
1649#ifdef CATCACHE_STATS
1650 cache->cc_newloads++;
1651#endif
1652
1653 return &ct->tuple;
1654}
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477

References AccessShareLock, Assert, CatCInProgress::cache, 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, fb(), HeapTupleIsValid, IndexScanOK(), IsBootstrapProcessingMode, ResourceOwnerEnlarge(), ResourceOwnerRememberCatCacheRef(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by SearchCatCacheInternal().

◆ texteqfast()

static bool texteqfast ( Datum  a,
Datum  b 
)
static

Definition at line 244 of file catcache.c.

245{
246 /*
247 * The use of DEFAULT_COLLATION_OID is fairly arbitrary here. We just
248 * want to take the fast "deterministic" path in texteq().
249 */
251}
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition fmgr.c:813
Datum texteq(PG_FUNCTION_ARGS)
Definition varlena.c:1381

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

Referenced by GetCCHashEqFuncs().

◆ texthashfast()

static uint32 texthashfast ( Datum  datum)
static

Definition at line 254 of file catcache.c.

255{
256 /* analogously here as in texteqfast() */
258}
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
Definition fmgr.c:793
Datum hashtext(PG_FUNCTION_ARGS)
Definition hashfunc.c:267

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

Referenced by GetCCHashEqFuncs().

Variable Documentation

◆ CacheHdr

◆ catcache_in_progress_stack

CatCInProgress* catcache_in_progress_stack = NULL
static

◆ 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:2455
static char * ResOwnerPrintCatCache(Datum res)
Definition catcache.c:2461
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition resowner.h:56
#define RELEASE_PRIO_CATCACHE_REFS
Definition resowner.h:71

Definition at line 137 of file catcache.c.

138{
139 /* catcache references */
140 .name = "catcache reference",
141 .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
142 .release_priority = RELEASE_PRIO_CATCACHE_REFS,
143 .ReleaseResource = ResOwnerReleaseCatCache,
144 .DebugPrint = ResOwnerPrintCatCache
145};

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:2478
static char * ResOwnerPrintCatCacheList(Datum res)
Definition catcache.c:2484
#define RELEASE_PRIO_CATCACHE_LIST_REFS
Definition resowner.h:72

Definition at line 147 of file catcache.c.

148{
149 /* catcache-list pins */
150 .name = "catcache list reference",
151 .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
152 .release_priority = RELEASE_PRIO_CATCACHE_LIST_REFS,
153 .ReleaseResource = ResOwnerReleaseCatCacheList,
154 .DebugPrint = ResOwnerPrintCatCacheList
155};

Referenced by ResourceOwnerForgetCatCacheListRef(), and ResourceOwnerRememberCatCacheListRef().