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