PostgreSQL Source Code  git master
syscache.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * syscache.c
4  * System cache management routines
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/utils/cache/syscache.c
12  *
13  * NOTES
14  * These routines allow the parser/planner/executor to perform
15  * rapid lookups on the contents of the system catalogs.
16  *
17  * see utils/syscache.h for a list of the cache IDs
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include "access/htup_details.h"
24 #include "catalog/pg_db_role_setting_d.h"
25 #include "catalog/pg_depend_d.h"
26 #include "catalog/pg_description_d.h"
27 #include "catalog/pg_seclabel_d.h"
28 #include "catalog/pg_shdepend_d.h"
29 #include "catalog/pg_shdescription_d.h"
30 #include "catalog/pg_shseclabel_d.h"
31 #include "common/int.h"
32 #include "lib/qunique.h"
33 #include "utils/catcache.h"
34 #include "utils/lsyscache.h"
35 #include "utils/rel.h"
36 #include "utils/syscache.h"
37 
38 /*---------------------------------------------------------------------------
39 
40  Adding system caches:
41 
42  There must be a unique index underlying each syscache (ie, an index
43  whose key is the same as that of the cache). If there is not one
44  already, add the definition for it to include/catalog/pg_*.h using
45  DECLARE_UNIQUE_INDEX.
46  (Adding an index requires a catversion.h update, while simply
47  adding/deleting caches only requires a recompile.)
48 
49  Add a MAKE_SYSCACHE call to the same pg_*.h file specifying the name of
50  your cache, the underlying index, and the initial number of hash buckets.
51 
52  The number of hash buckets must be a power of 2. It's reasonable to
53  set this to the number of entries that might be in the particular cache
54  in a medium-size database.
55 
56  Finally, any place your relation gets heap_insert() or
57  heap_update() calls, use CatalogTupleInsert() or CatalogTupleUpdate()
58  instead, which also update indexes. The heap_* calls do not do that.
59 
60 *---------------------------------------------------------------------------
61 */
62 
63 /*
64  * struct cachedesc: information defining a single syscache
65  */
66 struct cachedesc
67 {
68  Oid reloid; /* OID of the relation being cached */
69  Oid indoid; /* OID of index relation for this cache */
70  int nkeys; /* # of keys needed for cache lookup */
71  int key[4]; /* attribute numbers of key attrs */
72  int nbuckets; /* number of hash buckets for this cache */
73 };
74 
75 /* Macro to provide nkeys and key array with convenient syntax. */
76 #define KEY(...) VA_ARGS_NARGS(__VA_ARGS__), { __VA_ARGS__ }
77 
78 #include "catalog/syscache_info.h"
79 
80 StaticAssertDecl(lengthof(cacheinfo) == SysCacheSize,
81  "SysCacheSize does not match syscache.c's array");
82 
83 static CatCache *SysCache[SysCacheSize];
84 
85 static bool CacheInitialized = false;
86 
87 /* Sorted array of OIDs of tables that have caches on them */
88 static Oid SysCacheRelationOid[SysCacheSize];
90 
91 /* Sorted array of OIDs of tables and indexes used by caches */
92 static Oid SysCacheSupportingRelOid[SysCacheSize * 2];
94 
95 static int oid_compare(const void *a, const void *b);
96 
97 
98 /*
99  * InitCatalogCache - initialize the caches
100  *
101  * Note that no database access is done here; we only allocate memory
102  * and initialize the cache structure. Interrogation of the database
103  * to complete initialization of a cache happens upon first use
104  * of that cache.
105  */
106 void
108 {
109  int cacheId;
110 
112 
114 
115  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
116  {
117  /*
118  * Assert that every enumeration value defined in syscache.h has been
119  * populated in the cacheinfo array.
120  */
121  Assert(OidIsValid(cacheinfo[cacheId].reloid));
122  Assert(OidIsValid(cacheinfo[cacheId].indoid));
123  /* .nbuckets and .key[] are checked by InitCatCache() */
124 
125  SysCache[cacheId] = InitCatCache(cacheId,
126  cacheinfo[cacheId].reloid,
127  cacheinfo[cacheId].indoid,
128  cacheinfo[cacheId].nkeys,
129  cacheinfo[cacheId].key,
130  cacheinfo[cacheId].nbuckets);
131  if (!PointerIsValid(SysCache[cacheId]))
132  elog(ERROR, "could not initialize cache %u (%d)",
133  cacheinfo[cacheId].reloid, cacheId);
134  /* Accumulate data for OID lists, too */
136  cacheinfo[cacheId].reloid;
138  cacheinfo[cacheId].reloid;
140  cacheinfo[cacheId].indoid;
141  /* see comments for RelationInvalidatesSnapshotsOnly */
142  Assert(!RelationInvalidatesSnapshotsOnly(cacheinfo[cacheId].reloid));
143  }
144 
147 
148  /* Sort and de-dup OID arrays, so we can use binary search. */
150  sizeof(Oid), oid_compare);
153  oid_compare);
154 
156  sizeof(Oid), oid_compare);
159  sizeof(Oid), oid_compare);
160 
161  CacheInitialized = true;
162 }
163 
164 /*
165  * InitCatalogCachePhase2 - finish initializing the caches
166  *
167  * Finish initializing all the caches, including necessary database
168  * access.
169  *
170  * This is *not* essential; normally we allow syscaches to be initialized
171  * on first use. However, it is useful as a mechanism to preload the
172  * relcache with entries for the most-commonly-used system catalogs.
173  * Therefore, we invoke this routine when we need to write a new relcache
174  * init file.
175  */
176 void
178 {
179  int cacheId;
180 
182 
183  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
184  InitCatCachePhase2(SysCache[cacheId], true);
185 }
186 
187 
188 /*
189  * SearchSysCache
190  *
191  * A layer on top of SearchCatCache that does the initialization and
192  * key-setting for you.
193  *
194  * Returns the cache copy of the tuple if one is found, NULL if not.
195  * The tuple is the 'cache' copy and must NOT be modified!
196  *
197  * When the caller is done using the tuple, call ReleaseSysCache()
198  * to release the reference count grabbed by SearchSysCache(). If this
199  * is not done, the tuple will remain locked in cache until end of
200  * transaction, which is tolerable but not desirable.
201  *
202  * CAUTION: The tuple that is returned must NOT be freed by the caller!
203  */
204 HeapTuple
205 SearchSysCache(int cacheId,
206  Datum key1,
207  Datum key2,
208  Datum key3,
209  Datum key4)
210 {
211  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
212  PointerIsValid(SysCache[cacheId]));
213 
214  return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
215 }
216 
217 HeapTuple
218 SearchSysCache1(int cacheId,
219  Datum key1)
220 {
221  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
222  PointerIsValid(SysCache[cacheId]));
223  Assert(SysCache[cacheId]->cc_nkeys == 1);
224 
225  return SearchCatCache1(SysCache[cacheId], key1);
226 }
227 
228 HeapTuple
229 SearchSysCache2(int cacheId,
230  Datum key1, Datum key2)
231 {
232  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
233  PointerIsValid(SysCache[cacheId]));
234  Assert(SysCache[cacheId]->cc_nkeys == 2);
235 
236  return SearchCatCache2(SysCache[cacheId], key1, key2);
237 }
238 
239 HeapTuple
240 SearchSysCache3(int cacheId,
241  Datum key1, Datum key2, Datum key3)
242 {
243  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
244  PointerIsValid(SysCache[cacheId]));
245  Assert(SysCache[cacheId]->cc_nkeys == 3);
246 
247  return SearchCatCache3(SysCache[cacheId], key1, key2, key3);
248 }
249 
250 HeapTuple
251 SearchSysCache4(int cacheId,
252  Datum key1, Datum key2, Datum key3, Datum key4)
253 {
254  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
255  PointerIsValid(SysCache[cacheId]));
256  Assert(SysCache[cacheId]->cc_nkeys == 4);
257 
258  return SearchCatCache4(SysCache[cacheId], key1, key2, key3, key4);
259 }
260 
261 /*
262  * ReleaseSysCache
263  * Release previously grabbed reference count on a tuple
264  */
265 void
267 {
268  ReleaseCatCache(tuple);
269 }
270 
271 /*
272  * SearchSysCacheCopy
273  *
274  * A convenience routine that does SearchSysCache and (if successful)
275  * returns a modifiable copy of the syscache entry. The original
276  * syscache entry is released before returning. The caller should
277  * heap_freetuple() the result when done with it.
278  */
279 HeapTuple
280 SearchSysCacheCopy(int cacheId,
281  Datum key1,
282  Datum key2,
283  Datum key3,
284  Datum key4)
285 {
286  HeapTuple tuple,
287  newtuple;
288 
289  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
290  if (!HeapTupleIsValid(tuple))
291  return tuple;
292  newtuple = heap_copytuple(tuple);
293  ReleaseSysCache(tuple);
294  return newtuple;
295 }
296 
297 /*
298  * SearchSysCacheExists
299  *
300  * A convenience routine that just probes to see if a tuple can be found.
301  * No lock is retained on the syscache entry.
302  */
303 bool
305  Datum key1,
306  Datum key2,
307  Datum key3,
308  Datum key4)
309 {
310  HeapTuple tuple;
311 
312  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
313  if (!HeapTupleIsValid(tuple))
314  return false;
315  ReleaseSysCache(tuple);
316  return true;
317 }
318 
319 /*
320  * GetSysCacheOid
321  *
322  * A convenience routine that does SearchSysCache and returns the OID in the
323  * oidcol column of the found tuple, or InvalidOid if no tuple could be found.
324  * No lock is retained on the syscache entry.
325  */
326 Oid
327 GetSysCacheOid(int cacheId,
328  AttrNumber oidcol,
329  Datum key1,
330  Datum key2,
331  Datum key3,
332  Datum key4)
333 {
334  HeapTuple tuple;
335  bool isNull;
336  Oid result;
337 
338  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
339  if (!HeapTupleIsValid(tuple))
340  return InvalidOid;
341  result = heap_getattr(tuple, oidcol,
342  SysCache[cacheId]->cc_tupdesc,
343  &isNull);
344  Assert(!isNull); /* columns used as oids should never be NULL */
345  ReleaseSysCache(tuple);
346  return result;
347 }
348 
349 
350 /*
351  * SearchSysCacheAttName
352  *
353  * This routine is equivalent to SearchSysCache on the ATTNAME cache,
354  * except that it will return NULL if the found attribute is marked
355  * attisdropped. This is convenient for callers that want to act as
356  * though dropped attributes don't exist.
357  */
358 HeapTuple
359 SearchSysCacheAttName(Oid relid, const char *attname)
360 {
361  HeapTuple tuple;
362 
363  tuple = SearchSysCache2(ATTNAME,
364  ObjectIdGetDatum(relid),
366  if (!HeapTupleIsValid(tuple))
367  return NULL;
368  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
369  {
370  ReleaseSysCache(tuple);
371  return NULL;
372  }
373  return tuple;
374 }
375 
376 /*
377  * SearchSysCacheCopyAttName
378  *
379  * As above, an attisdropped-aware version of SearchSysCacheCopy.
380  */
381 HeapTuple
383 {
384  HeapTuple tuple,
385  newtuple;
386 
387  tuple = SearchSysCacheAttName(relid, attname);
388  if (!HeapTupleIsValid(tuple))
389  return tuple;
390  newtuple = heap_copytuple(tuple);
391  ReleaseSysCache(tuple);
392  return newtuple;
393 }
394 
395 /*
396  * SearchSysCacheExistsAttName
397  *
398  * As above, an attisdropped-aware version of SearchSysCacheExists.
399  */
400 bool
402 {
403  HeapTuple tuple;
404 
405  tuple = SearchSysCacheAttName(relid, attname);
406  if (!HeapTupleIsValid(tuple))
407  return false;
408  ReleaseSysCache(tuple);
409  return true;
410 }
411 
412 
413 /*
414  * SearchSysCacheAttNum
415  *
416  * This routine is equivalent to SearchSysCache on the ATTNUM cache,
417  * except that it will return NULL if the found attribute is marked
418  * attisdropped. This is convenient for callers that want to act as
419  * though dropped attributes don't exist.
420  */
421 HeapTuple
423 {
424  HeapTuple tuple;
425 
426  tuple = SearchSysCache2(ATTNUM,
427  ObjectIdGetDatum(relid),
429  if (!HeapTupleIsValid(tuple))
430  return NULL;
431  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
432  {
433  ReleaseSysCache(tuple);
434  return NULL;
435  }
436  return tuple;
437 }
438 
439 /*
440  * SearchSysCacheCopyAttNum
441  *
442  * As above, an attisdropped-aware version of SearchSysCacheCopy.
443  */
444 HeapTuple
446 {
447  HeapTuple tuple,
448  newtuple;
449 
450  tuple = SearchSysCacheAttNum(relid, attnum);
451  if (!HeapTupleIsValid(tuple))
452  return NULL;
453  newtuple = heap_copytuple(tuple);
454  ReleaseSysCache(tuple);
455  return newtuple;
456 }
457 
458 
459 /*
460  * SysCacheGetAttr
461  *
462  * Given a tuple previously fetched by SearchSysCache(),
463  * extract a specific attribute.
464  *
465  * This is equivalent to using heap_getattr() on a tuple fetched
466  * from a non-cached relation. Usually, this is only used for attributes
467  * that could be NULL or variable length; the fixed-size attributes in
468  * a system table are accessed just by mapping the tuple onto the C struct
469  * declarations from include/catalog/.
470  *
471  * As with heap_getattr(), if the attribute is of a pass-by-reference type
472  * then a pointer into the tuple data area is returned --- the caller must
473  * not modify or pfree the datum!
474  *
475  * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
476  * a different cache for the same catalog the tuple was fetched from.
477  */
478 Datum
479 SysCacheGetAttr(int cacheId, HeapTuple tup,
480  AttrNumber attributeNumber,
481  bool *isNull)
482 {
483  /*
484  * We just need to get the TupleDesc out of the cache entry, and then we
485  * can apply heap_getattr(). Normally the cache control data is already
486  * valid (because the caller recently fetched the tuple via this same
487  * cache), but there are cases where we have to initialize the cache here.
488  */
489  if (cacheId < 0 || cacheId >= SysCacheSize ||
490  !PointerIsValid(SysCache[cacheId]))
491  elog(ERROR, "invalid cache ID: %d", cacheId);
492  if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
493  {
494  InitCatCachePhase2(SysCache[cacheId], false);
495  Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
496  }
497 
498  return heap_getattr(tup, attributeNumber,
499  SysCache[cacheId]->cc_tupdesc,
500  isNull);
501 }
502 
503 /*
504  * SysCacheGetAttrNotNull
505  *
506  * As above, a version of SysCacheGetAttr which knows that the attr cannot
507  * be NULL.
508  */
509 Datum
511  AttrNumber attributeNumber)
512 {
513  bool isnull;
514  Datum attr;
515 
516  attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
517 
518  if (isnull)
519  {
520  elog(ERROR,
521  "unexpected null value in cached tuple for catalog %s column %s",
522  get_rel_name(cacheinfo[cacheId].reloid),
523  NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc, attributeNumber - 1)->attname));
524  }
525 
526  return attr;
527 }
528 
529 /*
530  * GetSysCacheHashValue
531  *
532  * Get the hash value that would be used for a tuple in the specified cache
533  * with the given search keys.
534  *
535  * The reason for exposing this as part of the API is that the hash value is
536  * exposed in cache invalidation operations, so there are places outside the
537  * catcache code that need to be able to compute the hash values.
538  */
539 uint32
541  Datum key1,
542  Datum key2,
543  Datum key3,
544  Datum key4)
545 {
546  if (cacheId < 0 || cacheId >= SysCacheSize ||
547  !PointerIsValid(SysCache[cacheId]))
548  elog(ERROR, "invalid cache ID: %d", cacheId);
549 
550  return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
551 }
552 
553 /*
554  * List-search interface
555  */
556 struct catclist *
557 SearchSysCacheList(int cacheId, int nkeys,
558  Datum key1, Datum key2, Datum key3)
559 {
560  if (cacheId < 0 || cacheId >= SysCacheSize ||
561  !PointerIsValid(SysCache[cacheId]))
562  elog(ERROR, "invalid cache ID: %d", cacheId);
563 
564  return SearchCatCacheList(SysCache[cacheId], nkeys,
565  key1, key2, key3);
566 }
567 
568 /*
569  * SysCacheInvalidate
570  *
571  * Invalidate entries in the specified cache, given a hash value.
572  * See CatCacheInvalidate() for more info.
573  *
574  * This routine is only quasi-public: it should only be used by inval.c.
575  */
576 void
577 SysCacheInvalidate(int cacheId, uint32 hashValue)
578 {
579  if (cacheId < 0 || cacheId >= SysCacheSize)
580  elog(ERROR, "invalid cache ID: %d", cacheId);
581 
582  /* if this cache isn't initialized yet, no need to do anything */
583  if (!PointerIsValid(SysCache[cacheId]))
584  return;
585 
586  CatCacheInvalidate(SysCache[cacheId], hashValue);
587 }
588 
589 /*
590  * Certain relations that do not have system caches send snapshot invalidation
591  * messages in lieu of catcache messages. This is for the benefit of
592  * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
593  * for scanning one of those catalogs, rather than taking a new one, if no
594  * invalidation has been received.
595  *
596  * Relations that have syscaches need not (and must not) be listed here. The
597  * catcache invalidation messages will also flush the snapshot. If you add a
598  * syscache for one of these relations, remove it from this list.
599  */
600 bool
602 {
603  switch (relid)
604  {
605  case DbRoleSettingRelationId:
606  case DependRelationId:
607  case SharedDependRelationId:
608  case DescriptionRelationId:
609  case SharedDescriptionRelationId:
610  case SecLabelRelationId:
611  case SharedSecLabelRelationId:
612  return true;
613  default:
614  break;
615  }
616 
617  return false;
618 }
619 
620 /*
621  * Test whether a relation has a system cache.
622  */
623 bool
625 {
626  int low = 0,
627  high = SysCacheRelationOidSize - 1;
628 
629  while (low <= high)
630  {
631  int middle = low + (high - low) / 2;
632 
633  if (SysCacheRelationOid[middle] == relid)
634  return true;
635  if (SysCacheRelationOid[middle] < relid)
636  low = middle + 1;
637  else
638  high = middle - 1;
639  }
640 
641  return false;
642 }
643 
644 /*
645  * Test whether a relation supports a system cache, ie it is either a
646  * cached table or the index used for a cache.
647  */
648 bool
650 {
651  int low = 0,
652  high = SysCacheSupportingRelOidSize - 1;
653 
654  while (low <= high)
655  {
656  int middle = low + (high - low) / 2;
657 
658  if (SysCacheSupportingRelOid[middle] == relid)
659  return true;
660  if (SysCacheSupportingRelOid[middle] < relid)
661  low = middle + 1;
662  else
663  high = middle - 1;
664  }
665 
666  return false;
667 }
668 
669 
670 /*
671  * OID comparator for qsort
672  */
673 static int
674 oid_compare(const void *a, const void *b)
675 {
676  Oid oa = *((const Oid *) a);
677  Oid ob = *((const Oid *) b);
678 
679  return pg_cmp_u32(oa, ob);
680 }
int16 AttrNumber
Definition: attnum.h:21
#define NameStr(name)
Definition: c.h:733
unsigned int uint32
Definition: c.h:493
signed short int16
Definition: c.h:480
#define PointerIsValid(pointer)
Definition: c.h:750
#define lengthof(array)
Definition: c.h:775
#define OidIsValid(objectId)
Definition: c.h:762
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
Definition: catcache.c:1222
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
Definition: catcache.c:1230
void InitCatCachePhase2(CatCache *cache, bool touch_index)
Definition: catcache.c:1080
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1548
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1238
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Definition: catcache.c:809
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
Definition: catcache.c:1582
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
Definition: catcache.c:598
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
Definition: catcache.c:1214
void ReleaseCatCache(HeapTuple tuple)
Definition: catcache.c:1509
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1197
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:489
int b
Definition: isn.c:70
int a
Definition: isn.c:69
Assert(fmt[strlen(fmt) - 1] !='\n')
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1906
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
#define qsort(a, b, c, d)
Definition: port.h:449
uintptr_t Datum
Definition: postgres.h:64
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
int key[4]
Definition: syscache.c:71
int nkeys
Definition: syscache.c:70
int nbuckets
Definition: syscache.c:72
Oid indoid
Definition: syscache.c:69
Oid reloid
Definition: syscache.c:68
short nkeys
Definition: catcache.h:175
HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname)
Definition: syscache.c:382
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:577
bool RelationHasSysCache(Oid relid)
Definition: syscache.c:624
HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
Definition: syscache.c:445
void InitCatalogCache(void)
Definition: syscache.c:107
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
static bool CacheInitialized
Definition: syscache.c:85
static int oid_compare(const void *a, const void *b)
Definition: syscache.c:674
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:205
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
uint32 GetSysCacheHashValue(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:540
struct catclist * SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:557
StaticAssertDecl(lengthof(cacheinfo)==SysCacheSize, "SysCacheSize does not match syscache.c's array")
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:240
static int SysCacheSupportingRelOidSize
Definition: syscache.c:93
HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum)
Definition: syscache.c:422
bool RelationSupportsSysCache(Oid relid)
Definition: syscache.c:649
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:479
bool SearchSysCacheExistsAttName(Oid relid, const char *attname)
Definition: syscache.c:401
void InitCatalogCachePhase2(void)
Definition: syscache.c:177
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:229
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:359
bool SearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:304
HeapTuple SearchSysCacheCopy(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:280
static Oid SysCacheRelationOid[SysCacheSize]
Definition: syscache.c:88
static CatCache * SysCache[SysCacheSize]
Definition: syscache.c:83
static Oid SysCacheSupportingRelOid[SysCacheSize *2]
Definition: syscache.c:92
static int SysCacheRelationOidSize
Definition: syscache.c:89
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:601
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:251
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:510
Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:327
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92