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

◆ CatalogCacheInitializeCache_DEBUG2

#define CatalogCacheInitializeCache_DEBUG2

Definition at line 1143 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 892 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 453 of file catcache.c.

456{
457 const CCFastEqualFN *cc_fastequal = cache->cc_fastequal;
458 int i;
459
460 for (i = 0; i < nkeys; i++)
461 {
462 if (!(cc_fastequal[i]) (cachekeys[i], searchkeys[i]))
463 return false;
464 }
465 return true;
466}
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 356 of file catcache.c.

358{
359 uint32 hashValue = 0;
361 CCHashFN *cc_hashfunc = cache->cc_hashfunc;
362
363 CACHE_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p",
364 cache->cc_relname, nkeys, cache);
365
366 switch (nkeys)
367 {
368 case 4:
369 oneHash = (cc_hashfunc[3]) (v4);
370 hashValue ^= pg_rotate_left32(oneHash, 24);
372 case 3:
373 oneHash = (cc_hashfunc[2]) (v3);
374 hashValue ^= pg_rotate_left32(oneHash, 16);
376 case 2:
377 oneHash = (cc_hashfunc[1]) (v2);
378 hashValue ^= pg_rotate_left32(oneHash, 8);
380 case 1:
381 oneHash = (cc_hashfunc[0]) (v1);
382 hashValue ^= oneHash;
383 break;
384 default:
385 elog(FATAL, "wrong number of hash keys: %d", nkeys);
386 break;
387 }
388
389 return hashValue;
390}
uint32_t uint32
Definition c.h:680
#define pg_fallthrough
Definition c.h:217
#define CACHE_elog(...)
Definition catcache.c:80
uint32(* CCHashFN)(Datum datum)
Definition catcache.h:39
#define FATAL
Definition elog.h:42
#define DEBUG2
Definition elog.h:30
#define elog(elevel,...)
Definition elog.h:228
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(), pg_fallthrough, 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 398 of file catcache.c.

399{
400 Datum v1 = 0,
401 v2 = 0,
402 v3 = 0,
403 v4 = 0;
404 bool isNull = false;
405 int *cc_keyno = cache->cc_keyno;
406 TupleDesc cc_tupdesc = cache->cc_tupdesc;
407
408 /* Now extract key fields from tuple, insert into scankey */
409 switch (nkeys)
410 {
411 case 4:
412 v4 = fastgetattr(tuple,
413 cc_keyno[3],
414 cc_tupdesc,
415 &isNull);
416 Assert(!isNull);
418 case 3:
419 v3 = fastgetattr(tuple,
420 cc_keyno[2],
421 cc_tupdesc,
422 &isNull);
423 Assert(!isNull);
425 case 2:
426 v2 = fastgetattr(tuple,
427 cc_keyno[1],
428 cc_tupdesc,
429 &isNull);
430 Assert(!isNull);
432 case 1:
433 v1 = fastgetattr(tuple,
434 cc_keyno[0],
435 cc_tupdesc,
436 &isNull);
437 Assert(!isNull);
438 break;
439 default:
440 elog(FATAL, "wrong number of hash keys: %d", nkeys);
441 break;
442 }
443
444 return CatalogCacheComputeHashValue(cache, nkeys, v1, v2, v3, v4);
445}
#define Assert(condition)
Definition c.h:999
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:356
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, fb(), and pg_fallthrough.

Referenced by PrepareToInvalidateCacheTuple(), and SearchCatCacheList().

◆ CatalogCacheCreateEntry()

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

Definition at line 2167 of file catcache.c.

2169{
2170 CatCTup *ct;
2172
2173 if (ntp)
2174 {
2175 int i;
2176 HeapTuple dtp = NULL;
2177
2178 /*
2179 * The invalidation of the in-progress entry essentially never happens
2180 * during our regression tests, and there's no easy way to force it to
2181 * fail for testing purposes. To ensure we have test coverage for the
2182 * retry paths in our callers, make debug builds randomly fail about
2183 * 0.1% of the times through this code path, even when there's no
2184 * toasted fields.
2185 */
2186#ifdef USE_ASSERT_CHECKING
2188 return NULL;
2189#endif
2190
2191 /*
2192 * If there are any out-of-line toasted fields in the tuple, expand
2193 * them in-line. This saves cycles during later use of the catcache
2194 * entry, and also protects us against the possibility of the toast
2195 * tuples being freed before we attempt to fetch them, in case of
2196 * something using a slightly stale catcache entry.
2197 */
2199 {
2202
2203 /*
2204 * The tuple could become stale while we are doing toast table
2205 * access (since AcceptInvalidationMessages can run then). The
2206 * invalidation will mark our in-progress entry as dead.
2207 */
2210 in_progress_ent.cache = cache;
2211 in_progress_ent.hash_value = hashValue;
2212 in_progress_ent.list = false;
2213 in_progress_ent.dead = false;
2215
2216 PG_TRY();
2217 {
2219 }
2220 PG_FINALLY();
2221 {
2224 }
2225 PG_END_TRY();
2226
2227 if (in_progress_ent.dead)
2228 {
2230 return NULL;
2231 }
2232 }
2233 else
2234 dtp = ntp;
2235
2236 /* Allocate memory for CatCTup and the cached tuple in one go */
2237 ct = (CatCTup *)
2239 MAXALIGN(sizeof(CatCTup)) + dtp->t_len);
2240 ct->tuple.t_len = dtp->t_len;
2241 ct->tuple.t_self = dtp->t_self;
2242 ct->tuple.t_tableOid = dtp->t_tableOid;
2243 ct->tuple.t_data = (HeapTupleHeader)
2244 (((char *) ct) + MAXALIGN(sizeof(CatCTup)));
2245 /* copy tuple contents */
2246 memcpy((char *) ct->tuple.t_data,
2247 (const char *) dtp->t_data,
2248 dtp->t_len);
2249
2250 if (dtp != ntp)
2252
2253 /* extract keys - they'll point into the tuple if not by-value */
2254 for (i = 0; i < cache->cc_nkeys; i++)
2255 {
2256 Datum atp;
2257 bool isnull;
2258
2259 atp = heap_getattr(&ct->tuple,
2260 cache->cc_keyno[i],
2261 cache->cc_tupdesc,
2262 &isnull);
2263 Assert(!isnull);
2264 ct->keys[i] = atp;
2265 }
2266 }
2267 else
2268 {
2269 /* Set up keys for a negative cache entry */
2272
2273 /*
2274 * Store keys - they'll point into separately allocated memory if not
2275 * by-value.
2276 */
2277 CatCacheCopyKeys(cache->cc_tupdesc, cache->cc_nkeys, cache->cc_keyno,
2278 arguments, ct->keys);
2280 }
2281
2282 /*
2283 * Finish initializing the CatCTup header, and add it to the cache's
2284 * linked list and counts.
2285 */
2286 ct->ct_magic = CT_MAGIC;
2287 ct->my_cache = cache;
2288 ct->c_list = NULL;
2289 ct->refcount = 0; /* for the moment */
2290 ct->dead = false;
2291 ct->negative = (ntp == NULL);
2292 ct->hash_value = hashValue;
2293
2294 dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem);
2295
2296 cache->cc_ntup++;
2297 CacheHdr->ch_ntup++;
2298
2299 /*
2300 * If the hash table has become too full, enlarge the buckets array. Quite
2301 * arbitrarily, we enlarge when fill factor > 2.
2302 */
2303 if (cache->cc_ntup > cache->cc_nbuckets * 2)
2304 RehashCatCache(cache);
2305
2306 return ct;
2307}
#define MAXALIGN(LEN)
Definition c.h:952
#define PG_UINT32_MAX
Definition c.h:730
static CatCInProgress * catcache_in_progress_stack
Definition catcache.c:61
static void RehashCatCache(CatCache *cp)
Definition catcache.c:1003
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:2335
#define CT_MAGIC
Definition catcache.h:99
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define PG_TRY(...)
Definition elog.h:374
#define PG_END_TRY(...)
Definition elog.h:399
#define PG_FINALLY(...)
Definition elog.h:391
#define palloc_object(type)
Definition fe_memutils.h:89
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
Definition heaptoast.c:350
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1372
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 * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1235
MemoryContext CacheMemoryContext
Definition mcxt.c:170
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
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, memcpy(), MemoryContextAlloc(), MemoryContextSwitchTo(), CatCInProgress::next, 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 852 of file catcache.c.

853{
854 slist_iter iter;
855
856 CACHE_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
857
859 {
860 CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
861
862 /* Does this cache store tuples of the target catalog? */
863 if (cache->cc_reloid == catId)
864 {
865 /* Yes, so flush all its contents */
866 ResetCatalogCache(cache, false);
867
868 /* Tell inval.c to call syscache callbacks for this cache */
869 CallSyscacheCallbacks(cache->id, 0);
870 }
871 }
872
873 CACHE_elog(DEBUG2, "end of CatalogCacheFlushCatalog call");
874}
static void ResetCatalogCache(CatCache *cache, bool debug_discard)
Definition catcache.c:754
#define slist_container(type, membername, ptr)
Definition ilist.h:1106
#define slist_foreach(iter, lhead)
Definition ilist.h:1132
void CallSyscacheCallbacks(SysCacheIdentifier cacheid, uint32 hashvalue)
Definition inval.c:1895
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 1147 of file catcache.c.

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

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

2337{
2338 int i;
2339
2340 /*
2341 * XXX: memory and lookup performance could possibly be improved by
2342 * storing all keys in one allocation.
2343 */
2344
2345 for (i = 0; i < nkeys; i++)
2346 {
2347 int attnum = attnos[i];
2348 Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
2349 Datum src = srckeys[i];
2351
2352 /*
2353 * Must be careful in case the caller passed a C string where a NAME
2354 * is wanted: convert the given argument to a correctly padded NAME.
2355 * Otherwise the memcpy() done by datumCopy() could fall off the end
2356 * of memory.
2357 */
2358 if (att->atttypid == NAMEOID)
2359 {
2361 src = NameGetDatum(&srcname);
2362 }
2363
2364 dstkeys[i] = datumCopy(src,
2365 att->attbyval,
2366 att->attlen);
2367 }
2368}
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:406
Definition c.h:886

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

2314{
2315 int i;
2316
2317 for (i = 0; i < nkeys; i++)
2318 {
2319 int attnum = attnos[i];
2320
2321 /* system attribute are not supported in caches */
2322 Assert(attnum > 0);
2323
2324 if (!TupleDescCompactAttr(tupdesc, attnum - 1)->attbyval)
2325 pfree(DatumGetPointer(keys[i]));
2326 }
2327}
void pfree(void *pointer)
Definition mcxt.c:1619
bool attbyval
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195

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

644{
647
648 CACHE_elog(DEBUG2, "CatCacheInvalidate: called");
649
650 /*
651 * We don't bother to check whether the cache has finished initialization
652 * yet; if not, there will be no entries in it so no problem.
653 */
654
655 /*
656 * Invalidate *all* CatCLists in this cache; it's too hard to tell which
657 * searches might still be correct, so just zap 'em all.
658 */
659 for (int i = 0; i < cache->cc_nlbuckets; i++)
660 {
661 dlist_head *bucket = &cache->cc_lbucket[i];
662
664 {
665 CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
666
667 if (cl->refcount > 0)
668 cl->dead = true;
669 else
670 CatCacheRemoveCList(cache, cl);
671 }
672 }
673
674 /*
675 * inspect the proper hash bucket for tuple matches
676 */
677 hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
679 {
680 CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
681
682 if (hashValue == ct->hash_value)
683 {
684 if (ct->refcount > 0 ||
685 (ct->c_list && ct->c_list->refcount > 0))
686 {
687 ct->dead = true;
688 /* list, if any, was marked dead above */
689 Assert(ct->c_list == NULL || ct->c_list->dead);
690 }
691 else
692 CatCacheRemoveCTup(cache, ct);
693 CACHE_elog(DEBUG2, "CatCacheInvalidate: invalidated");
694#ifdef CATCACHE_STATS
695 cache->cc_invals++;
696#endif
697 /* could be multiple matches, so keep looking! */
698 }
699 }
700
701 /* Also invalidate any entries that are being built */
703 {
704 if (e->cache == cache)
705 {
706 if (e->list || e->hash_value == hashValue)
707 e->dead = true;
708 }
709 }
710}
unsigned int Index
Definition c.h:754
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition catcache.c:546
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Definition catcache.c:588
#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 588 of file catcache.c.

589{
590 int i;
591
592 Assert(cl->refcount == 0);
593 Assert(cl->my_cache == cache);
594
595 /* delink from member tuples */
596 for (i = cl->n_members; --i >= 0;)
597 {
598 CatCTup *ct = cl->members[i];
599
600 Assert(ct->c_list == cl);
601 ct->c_list = NULL;
602 /* if the member is dead and now has no references, remove it */
603 if (
605 ct->dead &&
606#endif
607 ct->refcount == 0)
608 CatCacheRemoveCTup(cache, ct);
609 }
610
611 /* delink from linked list */
612 dlist_delete(&cl->cache_elem);
613
614 /* free associated column data */
615 CatCacheFreeKeys(cache->cc_tupdesc, cl->nkeys,
616 cache->cc_keyno, cl->keys);
617
618 pfree(cl);
619
620 --cache->cc_nlist;
621}
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, const int *attnos, const Datum *keys)
Definition catcache.c:2313
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 546 of file catcache.c.

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

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:676
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 1096 of file catcache.c.

1097{
1098#ifdef USE_ASSERT_CHECKING
1099 /*
1100 * TypeCacheRelCallback() runs outside transactions and relies on TYPEOID
1101 * for hashing. This isn't ideal. Since lookup_type_cache() both
1102 * registers the callback and searches TYPEOID, reaching trouble likely
1103 * requires OOM at an unlucky moment.
1104 *
1105 * InvalidateAttoptCacheCallback() runs outside transactions and likewise
1106 * relies on ATTNUM. InitPostgres() initializes ATTNUM, so it's reliable.
1107 */
1108 if (!(cache->id == TYPEOID || cache->id == ATTNUM) ||
1111 else
1112 Assert(cache->cc_tupdesc != NULL);
1113#endif
1114
1115 if (unlikely(cache->cc_tupdesc == NULL))
1117}
#define unlikely(x)
Definition c.h:494
static void CatalogCacheInitializeCache(CatCache *cache)
Definition catcache.c:1147
static void AssertCouldGetRelation(void)
Definition relcache.h:44
bool IsTransactionState(void)
Definition xact.c:389

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

727{
728 /*
729 * Purely for paranoia, check that context doesn't exist; caller probably
730 * did so already.
731 */
734 "CacheMemoryContext",
736}
MemoryContext TopMemoryContext
Definition mcxt.c:167
#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 1720 of file catcache.c.

1725{
1726 /*
1727 * one-time startup overhead for each cache
1728 */
1730
1731 /*
1732 * calculate the hash value
1733 */
1734 return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, v1, v2, v3, v4);
1735}
static pg_attribute_always_inline void ConditionalCatalogCacheInitializeCache(CatCache *cache)
Definition catcache.c:1096

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

286{
287 switch (keytype)
288 {
289 case BOOLOID:
292 *eqfunc = F_BOOLEQ;
293 break;
294 case CHAROID:
297 *eqfunc = F_CHAREQ;
298 break;
299 case NAMEOID:
302 *eqfunc = F_NAMEEQ;
303 break;
304 case INT2OID:
307 *eqfunc = F_INT2EQ;
308 break;
309 case INT4OID:
312 *eqfunc = F_INT4EQ;
313 break;
314 case TEXTOID:
317 *eqfunc = F_TEXTEQ;
318 break;
319 case OIDOID:
320 case REGPROCOID:
321 case REGPROCEDUREOID:
322 case REGOPEROID:
323 case REGOPERATOROID:
324 case REGCLASSOID:
325 case REGTYPEOID:
326 case REGCOLLATIONOID:
327 case REGCONFIGOID:
328 case REGDICTIONARYOID:
329 case REGROLEOID:
330 case REGNAMESPACEOID:
331 case REGDATABASEOID:
334 *eqfunc = F_OIDEQ;
335 break;
336 case OIDVECTOROID:
339 *eqfunc = F_OIDVECTOREQ;
340 break;
341 default:
342 elog(FATAL, "type %u not supported as catcache key", keytype);
343 *hashfunc = NULL; /* keep compiler quiet */
344
345 *eqfunc = InvalidOid;
346 break;
347 }
348}
static bool chareqfast(Datum a, Datum b)
Definition catcache.c:191
static bool int4eqfast(Datum a, Datum b)
Definition catcache.c:240
static bool int2eqfast(Datum a, Datum b)
Definition catcache.c:228
static uint32 int4hashfast(Datum datum)
Definition catcache.c:246
static uint32 namehashfast(Datum datum)
Definition catcache.c:216
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:278
static bool texteqfast(Datum a, Datum b)
Definition catcache.c:252
static bool oidvectoreqfast(Datum a, Datum b)
Definition catcache.c:272
static uint32 int2hashfast(Datum datum)
Definition catcache.c:234
static uint32 texthashfast(Datum datum)
Definition catcache.c:262

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

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

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

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

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

1257{
1259
1260 if (touch_index &&
1261 cache->id != AMOID &&
1262 cache->id != AMNAME)
1263 {
1265
1266 /*
1267 * We must lock the underlying catalog before opening the index to
1268 * avoid deadlock, since index_open could possibly result in reading
1269 * this same catalog, and if anyone else is exclusive-locking this
1270 * catalog and index they'll be doing it in that order.
1271 */
1274
1275 /*
1276 * While we've got the index open, let's check that it's unique (and
1277 * not just deferrable-unique, thank you very much). This is just to
1278 * catch thinkos in definitions of new catcaches, so we don't worry
1279 * about the pg_am indexes not getting tested.
1280 */
1281 Assert(idesc->rd_index->indisunique &&
1282 idesc->rd_index->indimmediate);
1283
1286 }
1287}
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
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 228 of file catcache.c.

229{
230 return DatumGetInt16(a) == DatumGetInt16(b);
231}
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 234 of file catcache.c.

235{
236 return murmurhash32((int32) DatumGetInt16(datum));
237}

References DatumGetInt16(), and murmurhash32().

Referenced by GetCCHashEqFuncs().

◆ int4eqfast()

static bool int4eqfast ( Datum  a,
Datum  b 
)
static

Definition at line 240 of file catcache.c.

241{
242 return DatumGetInt32(a) == DatumGetInt32(b);
243}
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 246 of file catcache.c.

247{
248 return murmurhash32((int32) DatumGetInt32(datum));
249}

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 /*
209 * Catalogs only use deterministic collations, so ignore column collation
210 * and use fast path.
211 */
212 return strncmp(ca, cb, NAMEDATALEN) == 0;
213}
#define NameStr(name)
Definition c.h:891
#define NAMEDATALEN
static Name DatumGetName(Datum X)
Definition postgres.h:393

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

Referenced by GetCCHashEqFuncs().

◆ namehashfast()

static uint32 namehashfast ( Datum  datum)
static

Definition at line 216 of file catcache.c.

217{
218 char *key = NameStr(*DatumGetName(datum));
219
220 /*
221 * Catalogs only use deterministic collations, so ignore column collation
222 * and use fast path.
223 */
224 return hash_bytes((unsigned char *) key, strlen(key));
225}
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 272 of file catcache.c.

273{
275}
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:690
Datum oidvectoreq(PG_FUNCTION_ARGS)
Definition oid.c:373
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 278 of file catcache.c.

279{
281}
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:688
Datum hashoidvector(PG_FUNCTION_ARGS)
Definition hashfunc.c:233

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

2410{
2411 slist_iter iter;
2412 Oid reloid;
2413
2414 CACHE_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
2415
2416 /*
2417 * sanity checks
2418 */
2419 Assert(RelationIsValid(relation));
2420 Assert(HeapTupleIsValid(tuple));
2422 Assert(CacheHdr != NULL);
2423
2424 reloid = RelationGetRelid(relation);
2425
2426 /* ----------------
2427 * for each cache
2428 * if the cache contains tuples from the specified relation
2429 * compute the tuple's hash value(s) in this cache,
2430 * and call the passed function to register the information.
2431 * ----------------
2432 */
2433
2435 {
2436 CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
2437 uint32 hashvalue;
2438 Oid dbid;
2439
2440 if (ccp->cc_reloid != reloid)
2441 continue;
2442
2443 /* Just in case cache hasn't finished initialization yet... */
2445
2446 hashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, tuple);
2447 dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
2448
2449 (*function) (ccp->id, hashvalue, dbid, context);
2450
2451 if (newtuple)
2452 {
2454
2455 newhashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, newtuple);
2456
2457 if (newhashvalue != hashvalue)
2458 (*function) (ccp->id, newhashvalue, dbid, context);
2459 }
2460 }
2461}
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
Definition catcache.c:398
Oid MyDatabaseId
Definition globals.c:96
#define HeapTupleIsValid(tuple)
Definition htup.h:78
on_exit_nicely_callback function
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationIsValid(relation)
Definition rel.h:491

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

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

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

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

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

1682{
1684}
static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner)
Definition catcache.c:1687
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 2133 of file catcache.c.

2134{
2135 /* Safety checks to ensure we were handed a cache entry */
2136 Assert(list->cl_magic == CL_MAGIC);
2137 Assert(list->refcount > 0);
2138 list->refcount--;
2139 if (resowner)
2140 ResourceOwnerForgetCatCacheListRef(resowner, list);
2141
2142 if (
2144 list->dead &&
2145#endif
2146 list->refcount == 0)
2147 CatCacheRemoveCList(list->my_cache, list);
2148}
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 1687 of file catcache.c.

1688{
1689 CatCTup *ct = (CatCTup *) (((char *) tuple) -
1690 offsetof(CatCTup, tuple));
1691
1692 /* Safety checks to ensure we were handed a cache entry */
1693 Assert(ct->ct_magic == CT_MAGIC);
1694 Assert(ct->refcount > 0);
1695
1696 ct->refcount--;
1697 if (resowner)
1698 ResourceOwnerForgetCatCacheRef(resowner, &ct->tuple);
1699
1700 if (
1702 ct->dead &&
1703#endif
1704 ct->refcount == 0 &&
1705 (ct->c_list == NULL || ct->c_list->refcount == 0))
1706 CatCacheRemoveCTup(ct->my_cache, ct);
1707}
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 754 of file catcache.c.

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

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

817{
819}
void ResetCatalogCachesExt(bool debug_discard)
Definition catcache.c:822

References ResetCatalogCachesExt().

◆ ResetCatalogCachesExt()

void ResetCatalogCachesExt ( bool  debug_discard)

Definition at line 822 of file catcache.c.

823{
824 slist_iter iter;
825
826 CACHE_elog(DEBUG2, "ResetCatalogCaches called");
827
829 {
830 CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
831
833 }
834
835 CACHE_elog(DEBUG2, "end of ResetCatalogCaches call");
836}

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
#define PointerGetDatum(X)
Definition postgres.h:354
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:571

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:531

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

2473{
2474 HeapTuple tuple = (HeapTuple) DatumGetPointer(res);
2475 CatCTup *ct = (CatCTup *) (((char *) tuple) -
2476 offsetof(CatCTup, tuple));
2477
2478 /* Safety check to ensure we were handed a cache entry */
2479 Assert(ct->ct_magic == CT_MAGIC);
2480
2481 return psprintf("cache %s (%d), tuple %u/%u has count %d",
2482 ct->my_cache->cc_relname, ct->my_cache->id,
2485 ct->refcount);
2486}
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 2495 of file catcache.c.

2496{
2498
2499 return psprintf("cache %s (%d), list %p has count %d",
2500 list->my_cache->cc_relname, list->my_cache->id,
2501 list, list->refcount);
2502}

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

◆ ResOwnerReleaseCatCache()

static void ResOwnerReleaseCatCache ( Datum  res)
static

Definition at line 2466 of file catcache.c.

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

◆ ResOwnerReleaseCatCacheList()

static void ResOwnerReleaseCatCacheList ( Datum  res)
static

Definition at line 2489 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 1374 of file catcache.c.

1379{
1380 return SearchCatCacheInternal(cache, cache->cc_nkeys, v1, v2, v3, v4);
1381}
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1425

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

Referenced by SearchSysCache().

◆ SearchCatCache1()

HeapTuple SearchCatCache1 ( CatCache cache,
Datum  v1 
)

Definition at line 1391 of file catcache.c.

1393{
1394 return SearchCatCacheInternal(cache, 1, v1, 0, 0, 0);
1395}

References CatCInProgress::cache, and SearchCatCacheInternal().

Referenced by SearchSysCache1().

◆ SearchCatCache2()

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

Definition at line 1399 of file catcache.c.

1401{
1402 return SearchCatCacheInternal(cache, 2, v1, v2, 0, 0);
1403}

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

Referenced by SearchSysCache2().

◆ SearchCatCache3()

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

Definition at line 1407 of file catcache.c.

1409{
1410 return SearchCatCacheInternal(cache, 3, v1, v2, v3, 0);
1411}

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

1417{
1418 return SearchCatCacheInternal(cache, 4, v1, v2, v3, v4);
1419}

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

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

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

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(), memcpy(), 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 1533 of file catcache.c.

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

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, memcpy(), 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 252 of file catcache.c.

253{
254 /*
255 * Catalogs only use deterministic collations, so ignore column collation
256 * and use "C" locale for efficiency.
257 */
259}
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition fmgr.c:814
Datum texteq(PG_FUNCTION_ARGS)
Definition varlena.c:1429

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

Referenced by GetCCHashEqFuncs().

◆ texthashfast()

static uint32 texthashfast ( Datum  datum)
static

Definition at line 262 of file catcache.c.

263{
264 /*
265 * Catalogs only use deterministic collations, so ignore column collation
266 * and use "C" locale for efficiency.
267 */
269}
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
Definition fmgr.c:794
Datum hashtext(PG_FUNCTION_ARGS)
Definition hashfunc.c:270

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:2466
static char * ResOwnerPrintCatCache(Datum res)
Definition catcache.c:2472
@ 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:2489
static char * ResOwnerPrintCatCacheList(Datum res)
Definition catcache.c:2495
#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().