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:624
#define pg_fallthrough
Definition c.h:161
#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:943
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 2165 of file catcache.c.

2167{
2168 CatCTup *ct;
2170
2171 if (ntp)
2172 {
2173 int i;
2174 HeapTuple dtp = NULL;
2175
2176 /*
2177 * The invalidation of the in-progress entry essentially never happens
2178 * during our regression tests, and there's no easy way to force it to
2179 * fail for testing purposes. To ensure we have test coverage for the
2180 * retry paths in our callers, make debug builds randomly fail about
2181 * 0.1% of the times through this code path, even when there's no
2182 * toasted fields.
2183 */
2184#ifdef USE_ASSERT_CHECKING
2186 return NULL;
2187#endif
2188
2189 /*
2190 * If there are any out-of-line toasted fields in the tuple, expand
2191 * them in-line. This saves cycles during later use of the catcache
2192 * entry, and also protects us against the possibility of the toast
2193 * tuples being freed before we attempt to fetch them, in case of
2194 * something using a slightly stale catcache entry.
2195 */
2197 {
2200
2201 /*
2202 * The tuple could become stale while we are doing toast table
2203 * access (since AcceptInvalidationMessages can run then). The
2204 * invalidation will mark our in-progress entry as dead.
2205 */
2208 in_progress_ent.cache = cache;
2209 in_progress_ent.hash_value = hashValue;
2210 in_progress_ent.list = false;
2211 in_progress_ent.dead = false;
2213
2214 PG_TRY();
2215 {
2217 }
2218 PG_FINALLY();
2219 {
2222 }
2223 PG_END_TRY();
2224
2225 if (in_progress_ent.dead)
2226 {
2228 return NULL;
2229 }
2230 }
2231 else
2232 dtp = ntp;
2233
2234 /* Allocate memory for CatCTup and the cached tuple in one go */
2235 ct = (CatCTup *)
2237 MAXALIGN(sizeof(CatCTup)) + dtp->t_len);
2238 ct->tuple.t_len = dtp->t_len;
2239 ct->tuple.t_self = dtp->t_self;
2240 ct->tuple.t_tableOid = dtp->t_tableOid;
2241 ct->tuple.t_data = (HeapTupleHeader)
2242 (((char *) ct) + MAXALIGN(sizeof(CatCTup)));
2243 /* copy tuple contents */
2244 memcpy((char *) ct->tuple.t_data,
2245 (const char *) dtp->t_data,
2246 dtp->t_len);
2247
2248 if (dtp != ntp)
2250
2251 /* extract keys - they'll point into the tuple if not by-value */
2252 for (i = 0; i < cache->cc_nkeys; i++)
2253 {
2254 Datum atp;
2255 bool isnull;
2256
2257 atp = heap_getattr(&ct->tuple,
2258 cache->cc_keyno[i],
2259 cache->cc_tupdesc,
2260 &isnull);
2261 Assert(!isnull);
2262 ct->keys[i] = atp;
2263 }
2264 }
2265 else
2266 {
2267 /* Set up keys for a negative cache entry */
2270
2271 /*
2272 * Store keys - they'll point into separately allocated memory if not
2273 * by-value.
2274 */
2275 CatCacheCopyKeys(cache->cc_tupdesc, cache->cc_nkeys, cache->cc_keyno,
2276 arguments, ct->keys);
2278 }
2279
2280 /*
2281 * Finish initializing the CatCTup header, and add it to the cache's
2282 * linked list and counts.
2283 */
2284 ct->ct_magic = CT_MAGIC;
2285 ct->my_cache = cache;
2286 ct->c_list = NULL;
2287 ct->refcount = 0; /* for the moment */
2288 ct->dead = false;
2289 ct->negative = (ntp == NULL);
2290 ct->hash_value = hashValue;
2291
2292 dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem);
2293
2294 cache->cc_ntup++;
2295 CacheHdr->ch_ntup++;
2296
2297 /*
2298 * If the hash table has become too full, enlarge the buckets array. Quite
2299 * arbitrarily, we enlarge when fill factor > 2.
2300 */
2301 if (cache->cc_ntup > cache->cc_nbuckets * 2)
2302 RehashCatCache(cache);
2303
2304 return ct;
2305}
#define MAXALIGN(LEN)
Definition c.h:896
#define PG_UINT32_MAX
Definition c.h:674
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:2333
#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:74
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:1232
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, 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: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 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:734
#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:1781
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 2333 of file catcache.c.

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

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

2312{
2313 int i;
2314
2315 for (i = 0; i < nkeys; i++)
2316 {
2317 int attnum = attnos[i];
2318
2319 /* system attribute are not supported in caches */
2320 Assert(attnum > 0);
2321
2322 if (!TupleDescCompactAttr(tupdesc, attnum - 1)->attbyval)
2323 pfree(DatumGetPointer(keys[i]));
2324 }
2325}
void pfree(void *pointer)
Definition mcxt.c:1616
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:698
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:2311
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:620
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:438
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: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 1718 of file catcache.c.

1723{
1724 /*
1725 * one-time startup overhead for each cache
1726 */
1728
1729 /*
1730 * calculate the hash value
1731 */
1732 return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, v1, v2, v3, v4);
1733}
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
1339 /*
1340 * Protect authentication lookups occurring before relcache has
1341 * collected entries for shared indexes.
1342 */
1344 return false;
1345 break;
1346
1347 default:
1348 break;
1349 }
1350
1351 /* Normal case, allow index scan */
1352 return true;
1353}
bool criticalRelcachesBuilt
Definition relcache.c:142
bool criticalSharedRelcachesBuilt
Definition relcache.c:148

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: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: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:835
#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:686
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:684
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 2403 of file catcache.c.

2408{
2409 slist_iter iter;
2410 Oid reloid;
2411
2412 CACHE_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
2413
2414 /*
2415 * sanity checks
2416 */
2417 Assert(RelationIsValid(relation));
2418 Assert(HeapTupleIsValid(tuple));
2420 Assert(CacheHdr != NULL);
2421
2422 reloid = RelationGetRelid(relation);
2423
2424 /* ----------------
2425 * for each cache
2426 * if the cache contains tuples from the specified relation
2427 * compute the tuple's hash value(s) in this cache,
2428 * and call the passed function to register the information.
2429 * ----------------
2430 */
2431
2433 {
2434 CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
2435 uint32 hashvalue;
2436 Oid dbid;
2437
2438 if (ccp->cc_reloid != reloid)
2439 continue;
2440
2441 /* Just in case cache hasn't finished initialization yet... */
2443
2444 hashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, tuple);
2445 dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
2446
2447 (*function) (ccp->id, hashvalue, dbid, context);
2448
2449 if (newtuple)
2450 {
2452
2453 newhashvalue = CatalogCacheComputeTupleHashValue(ccp, ccp->cc_nkeys, newtuple);
2454
2455 if (newhashvalue != hashvalue)
2456 (*function) (ccp->id, newhashvalue, dbid, context);
2457 }
2458 }
2459}
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: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 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 1679 of file catcache.c.

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

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

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

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

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

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

◆ ResOwnerReleaseCatCache()

static void ResOwnerReleaseCatCache ( Datum  res)
static

Definition at line 2464 of file catcache.c.

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

◆ ResOwnerReleaseCatCacheList()

static void ResOwnerReleaseCatCacheList ( Datum  res)
static

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

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

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

Referenced by SearchSysCache().

◆ SearchCatCache1()

HeapTuple SearchCatCache1 ( CatCache cache,
Datum  v1 
)

Definition at line 1389 of file catcache.c.

1391{
1392 return SearchCatCacheInternal(cache, 1, v1, 0, 0, 0);
1393}

References CatCInProgress::cache, and SearchCatCacheInternal().

Referenced by SearchSysCache1().

◆ SearchCatCache2()

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

Definition at line 1397 of file catcache.c.

1399{
1400 return SearchCatCacheInternal(cache, 2, v1, v2, 0, 0);
1401}

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

Referenced by SearchSysCache2().

◆ SearchCatCache3()

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

Definition at line 1405 of file catcache.c.

1407{
1408 return SearchCatCacheInternal(cache, 3, v1, v2, v3, 0);
1409}

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

1415{
1416 return SearchCatCacheInternal(cache, 4, v1, v2, v3, v4);
1417}

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

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

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

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

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

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:2464
static char * ResOwnerPrintCatCache(Datum res)
Definition catcache.c:2470
@ 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:2487
static char * ResOwnerPrintCatCacheList(Datum res)
Definition catcache.c:2493
#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().