PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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 "miscadmin.h"
34#include "storage/lmgr.h"
35#include "storage/lock.h"
36#include "utils/catcache.h"
37#include "utils/inval.h"
38#include "utils/lsyscache.h"
39#include "utils/rel.h"
40#include "utils/syscache.h"
41
42/*---------------------------------------------------------------------------
43
44 Adding system caches:
45
46 There must be a unique index underlying each syscache (ie, an index
47 whose key is the same as that of the cache). If there is not one
48 already, add the definition for it to include/catalog/pg_*.h using
49 DECLARE_UNIQUE_INDEX.
50 (Adding an index requires a catversion.h update, while simply
51 adding/deleting caches only requires a recompile.)
52
53 Add a MAKE_SYSCACHE call to the same pg_*.h file specifying the name of
54 your cache, the underlying index, and the initial number of hash buckets.
55
56 The number of hash buckets must be a power of 2. It's reasonable to
57 set this to the number of entries that might be in the particular cache
58 in a medium-size database.
59
60 Finally, any place your relation gets heap_insert() or
61 heap_update() calls, use CatalogTupleInsert() or CatalogTupleUpdate()
62 instead, which also update indexes. The heap_* calls do not do that.
63
64*---------------------------------------------------------------------------
65*/
66
67/*
68 * struct cachedesc: information defining a single syscache
69 */
71{
72 Oid reloid; /* OID of the relation being cached */
73 Oid indoid; /* OID of index relation for this cache */
74 int nkeys; /* # of keys needed for cache lookup */
75 int key[4]; /* attribute numbers of key attrs */
76 int nbuckets; /* number of hash buckets for this cache */
77};
78
79/* Macro to provide nkeys and key array with convenient syntax. */
80#define KEY(...) VA_ARGS_NARGS(__VA_ARGS__), { __VA_ARGS__ }
81
82#include "catalog/syscache_info.h"
83
85 "SysCacheSize does not match syscache.c's array");
86
88
89static bool CacheInitialized = false;
90
91/* Sorted array of OIDs of tables that have caches on them */
94
95/* Sorted array of OIDs of tables and indexes used by caches */
98
99static int oid_compare(const void *a, const void *b);
100
101
102/*
103 * InitCatalogCache - initialize the caches
104 *
105 * Note that no database access is done here; we only allocate memory
106 * and initialize the cache structure. Interrogation of the database
107 * to complete initialization of a cache happens upon first use
108 * of that cache.
109 */
110void
112{
113 SysCacheIdentifier cacheId;
114
116
118
119 for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
120 {
121 /*
122 * Assert that every enumeration value defined in syscache.h has been
123 * populated in the cacheinfo array.
124 */
125 Assert(OidIsValid(cacheinfo[cacheId].reloid));
126 Assert(OidIsValid(cacheinfo[cacheId].indoid));
127 /* .nbuckets and .key[] are checked by InitCatCache() */
128
129 SysCache[cacheId] = InitCatCache(cacheId,
130 cacheinfo[cacheId].reloid,
131 cacheinfo[cacheId].indoid,
132 cacheinfo[cacheId].nkeys,
133 cacheinfo[cacheId].key,
134 cacheinfo[cacheId].nbuckets);
135 if (!SysCache[cacheId])
136 elog(ERROR, "could not initialize cache %u (%d)",
137 cacheinfo[cacheId].reloid, cacheId);
138 /* Accumulate data for OID lists, too */
140 cacheinfo[cacheId].reloid;
142 cacheinfo[cacheId].reloid;
144 cacheinfo[cacheId].indoid;
145 /* see comments for RelationInvalidatesSnapshotsOnly */
147 }
148
151
152 /* Sort and de-dup OID arrays, so we can use binary search. */
154 sizeof(Oid), oid_compare);
158
160 sizeof(Oid), oid_compare);
163 sizeof(Oid), oid_compare);
164
165 CacheInitialized = true;
166}
167
168/*
169 * InitCatalogCachePhase2 - finish initializing the caches
170 *
171 * Finish initializing all the caches, including necessary database
172 * access.
173 *
174 * This is *not* essential; normally we allow syscaches to be initialized
175 * on first use. However, it is useful as a mechanism to preload the
176 * relcache with entries for the most-commonly-used system catalogs.
177 * Therefore, we invoke this routine when we need to write a new relcache
178 * init file.
179 */
180void
182{
183 SysCacheIdentifier cacheId;
184
186
187 for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
188 InitCatCachePhase2(SysCache[cacheId], true);
189}
190
191
192/*
193 * SearchSysCache
194 *
195 * A layer on top of SearchCatCache that does the initialization and
196 * key-setting for you.
197 *
198 * Returns the cache copy of the tuple if one is found, NULL if not.
199 * The tuple is the 'cache' copy and must NOT be modified!
200 *
201 * When the caller is done using the tuple, call ReleaseSysCache()
202 * to release the reference count grabbed by SearchSysCache(). If this
203 * is not done, the tuple will remain locked in cache until end of
204 * transaction, which is tolerable but not desirable.
205 *
206 * CAUTION: The tuple that is returned must NOT be freed by the caller!
207 */
210 Datum key1,
211 Datum key2,
212 Datum key3,
213 Datum key4)
214{
215 Assert(cacheId >= 0 && cacheId < SysCacheSize && SysCache[cacheId]);
216
217 return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
218}
219
222 Datum key1)
223{
224 Assert(cacheId >= 0 && cacheId < SysCacheSize && SysCache[cacheId]);
225 Assert(SysCache[cacheId]->cc_nkeys == 1);
226
227 return SearchCatCache1(SysCache[cacheId], key1);
228}
229
233{
234 Assert(cacheId >= 0 && cacheId < SysCacheSize && SysCache[cacheId]);
235 Assert(SysCache[cacheId]->cc_nkeys == 2);
236
237 return SearchCatCache2(SysCache[cacheId], key1, key2);
238}
239
243{
244 Assert(cacheId >= 0 && cacheId < SysCacheSize && SysCache[cacheId]);
245 Assert(SysCache[cacheId]->cc_nkeys == 3);
246
247 return SearchCatCache3(SysCache[cacheId], key1, key2, key3);
248}
249
253{
254 Assert(cacheId >= 0 && cacheId < SysCacheSize && SysCache[cacheId]);
255 Assert(SysCache[cacheId]->cc_nkeys == 4);
256
257 return SearchCatCache4(SysCache[cacheId], key1, key2, key3, key4);
258}
259
260/*
261 * ReleaseSysCache
262 * Release previously grabbed reference count on a tuple
263 */
264void
266{
267 ReleaseCatCache(tuple);
268}
269
270/*
271 * SearchSysCacheLocked1
272 *
273 * Combine SearchSysCache1() with acquiring a LOCKTAG_TUPLE at mode
274 * InplaceUpdateTupleLock. This is a tool for complying with the
275 * README.tuplock section "Locking to write inplace-updated tables". After
276 * the caller's heap_update(), it should UnlockTuple(InplaceUpdateTupleLock)
277 * and ReleaseSysCache().
278 *
279 * The returned tuple may be the subject of an uncommitted update, so this
280 * doesn't prevent the "tuple concurrently updated" error.
281 */
284 Datum key1)
285{
286 CatCache *cache = SysCache[cacheId];
287 ItemPointerData tid;
288 LOCKTAG tag;
289
290 /*----------
291 * Since inplace updates may happen just before our LockTuple(), we must
292 * return content acquired after LockTuple() of the TID we return. If we
293 * just fetched twice instead of looping, the following sequence would
294 * defeat our locking:
295 *
296 * GRANT: SearchSysCache1() = TID (1,5)
297 * GRANT: LockTuple(pg_class, (1,5))
298 * [no more inplace update of (1,5) until we release the lock]
299 * CLUSTER: SearchSysCache1() = TID (1,5)
300 * CLUSTER: heap_update() = TID (1,8)
301 * CLUSTER: COMMIT
302 * GRANT: SearchSysCache1() = TID (1,8)
303 * GRANT: return (1,8) from SearchSysCacheLocked1()
304 * VACUUM: SearchSysCache1() = TID (1,8)
305 * VACUUM: LockTuple(pg_class, (1,8)) # two TIDs now locked for one rel
306 * VACUUM: inplace update
307 * GRANT: heap_update() = (1,9) # lose inplace update
308 *
309 * In the happy case, this takes two fetches, one to determine the TID to
310 * lock and another to get the content and confirm the TID didn't change.
311 *
312 * This is valid even if the row gets updated to a new TID, the old TID
313 * becomes LP_UNUSED, and the row gets updated back to its old TID. We'd
314 * still hold the right LOCKTAG_TUPLE and a copy of the row captured after
315 * the LOCKTAG_TUPLE.
316 */
318 for (;;)
319 {
320 HeapTuple tuple;
322
323 tuple = SearchSysCache1(cacheId, key1);
324 if (ItemPointerIsValid(&tid))
325 {
326 if (!HeapTupleIsValid(tuple))
327 {
328 LockRelease(&tag, lockmode, false);
329 return tuple;
330 }
331 if (ItemPointerEquals(&tid, &tuple->t_self))
332 return tuple;
333 LockRelease(&tag, lockmode, false);
334 }
335 else if (!HeapTupleIsValid(tuple))
336 return tuple;
337
338 tid = tuple->t_self;
339 ReleaseSysCache(tuple);
340
341 /*
342 * Do like LockTuple(rel, &tid, lockmode). While cc_relisshared won't
343 * change from one iteration to another, it may have been a temporary
344 * "false" until our first SearchSysCache1().
345 */
348 cache->cc_reloid,
351 (void) LockAcquire(&tag, lockmode, false, false);
352
353 /*
354 * If an inplace update just finished, ensure we process the syscache
355 * inval.
356 *
357 * If a heap_update() call just released its LOCKTAG_TUPLE, we'll
358 * probably find the old tuple and reach "tuple concurrently updated".
359 * If that heap_update() aborts, our LOCKTAG_TUPLE blocks inplace
360 * updates while our caller works.
361 */
363 }
364}
365
366/*
367 * SearchSysCacheCopy
368 *
369 * A convenience routine that does SearchSysCache and (if successful)
370 * returns a modifiable copy of the syscache entry. The original
371 * syscache entry is released before returning. The caller should
372 * heap_freetuple() the result when done with it.
373 */
376 Datum key1,
377 Datum key2,
378 Datum key3,
379 Datum key4)
380{
381 HeapTuple tuple,
382 newtuple;
383
384 tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
385 if (!HeapTupleIsValid(tuple))
386 return tuple;
387 newtuple = heap_copytuple(tuple);
388 ReleaseSysCache(tuple);
389 return newtuple;
390}
391
392/*
393 * SearchSysCacheLockedCopy1
394 *
395 * Meld SearchSysCacheLocked1 with SearchSysCacheCopy(). After the
396 * caller's heap_update(), it should UnlockTuple(InplaceUpdateTupleLock) and
397 * heap_freetuple().
398 */
401 Datum key1)
402{
403 HeapTuple tuple,
404 newtuple;
405
406 tuple = SearchSysCacheLocked1(cacheId, key1);
407 if (!HeapTupleIsValid(tuple))
408 return tuple;
409 newtuple = heap_copytuple(tuple);
410 ReleaseSysCache(tuple);
411 return newtuple;
412}
413
414/*
415 * SearchSysCacheExists
416 *
417 * A convenience routine that just probes to see if a tuple can be found.
418 * No lock is retained on the syscache entry.
419 */
420bool
422 Datum key1,
423 Datum key2,
424 Datum key3,
425 Datum key4)
426{
427 HeapTuple tuple;
428
429 tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
430 if (!HeapTupleIsValid(tuple))
431 return false;
432 ReleaseSysCache(tuple);
433 return true;
434}
435
436/*
437 * GetSysCacheOid
438 *
439 * A convenience routine that does SearchSysCache and returns the OID in the
440 * oidcol column of the found tuple, or InvalidOid if no tuple could be found.
441 * No lock is retained on the syscache entry.
442 */
443Oid
446 Datum key1,
447 Datum key2,
448 Datum key3,
449 Datum key4)
450{
451 HeapTuple tuple;
452 bool isNull;
453 Oid result;
454
455 tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
456 if (!HeapTupleIsValid(tuple))
457 return InvalidOid;
459 SysCache[cacheId]->cc_tupdesc,
460 &isNull));
461 Assert(!isNull); /* columns used as oids should never be NULL */
462 ReleaseSysCache(tuple);
463 return result;
464}
465
466
467/*
468 * SearchSysCacheAttName
469 *
470 * This routine is equivalent to SearchSysCache on the ATTNAME cache,
471 * except that it will return NULL if the found attribute is marked
472 * attisdropped. This is convenient for callers that want to act as
473 * though dropped attributes don't exist.
474 */
477{
478 HeapTuple tuple;
479
480 tuple = SearchSysCache2(ATTNAME,
481 ObjectIdGetDatum(relid),
483 if (!HeapTupleIsValid(tuple))
484 return NULL;
485 if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
486 {
487 ReleaseSysCache(tuple);
488 return NULL;
489 }
490 return tuple;
491}
492
493/*
494 * SearchSysCacheCopyAttName
495 *
496 * As above, an attisdropped-aware version of SearchSysCacheCopy.
497 */
500{
501 HeapTuple tuple,
502 newtuple;
503
504 tuple = SearchSysCacheAttName(relid, attname);
505 if (!HeapTupleIsValid(tuple))
506 return tuple;
507 newtuple = heap_copytuple(tuple);
508 ReleaseSysCache(tuple);
509 return newtuple;
510}
511
512/*
513 * SearchSysCacheExistsAttName
514 *
515 * As above, an attisdropped-aware version of SearchSysCacheExists.
516 */
517bool
519{
520 HeapTuple tuple;
521
522 tuple = SearchSysCacheAttName(relid, attname);
523 if (!HeapTupleIsValid(tuple))
524 return false;
525 ReleaseSysCache(tuple);
526 return true;
527}
528
529
530/*
531 * SearchSysCacheAttNum
532 *
533 * This routine is equivalent to SearchSysCache on the ATTNUM cache,
534 * except that it will return NULL if the found attribute is marked
535 * attisdropped. This is convenient for callers that want to act as
536 * though dropped attributes don't exist.
537 */
540{
541 HeapTuple tuple;
542
543 tuple = SearchSysCache2(ATTNUM,
544 ObjectIdGetDatum(relid),
546 if (!HeapTupleIsValid(tuple))
547 return NULL;
548 if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
549 {
550 ReleaseSysCache(tuple);
551 return NULL;
552 }
553 return tuple;
554}
555
556/*
557 * SearchSysCacheCopyAttNum
558 *
559 * As above, an attisdropped-aware version of SearchSysCacheCopy.
560 */
563{
564 HeapTuple tuple,
565 newtuple;
566
567 tuple = SearchSysCacheAttNum(relid, attnum);
568 if (!HeapTupleIsValid(tuple))
569 return NULL;
570 newtuple = heap_copytuple(tuple);
571 ReleaseSysCache(tuple);
572 return newtuple;
573}
574
575
576/*
577 * SysCacheGetAttr
578 *
579 * Given a tuple previously fetched by SearchSysCache(),
580 * extract a specific attribute.
581 *
582 * This is equivalent to using heap_getattr() on a tuple fetched
583 * from a non-cached relation. Usually, this is only used for attributes
584 * that could be NULL or variable length; the fixed-size attributes in
585 * a system table are accessed just by mapping the tuple onto the C struct
586 * declarations from include/catalog/.
587 *
588 * As with heap_getattr(), if the attribute is of a pass-by-reference type
589 * then a pointer into the tuple data area is returned --- the caller must
590 * not modify or pfree the datum!
591 *
592 * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
593 * a different cache for the same catalog the tuple was fetched from.
594 */
595Datum
598 bool *isNull)
599{
600 /*
601 * We just need to get the TupleDesc out of the cache entry, and then we
602 * can apply heap_getattr(). Normally the cache control data is already
603 * valid (because the caller recently fetched the tuple via this same
604 * cache), but there are cases where we have to initialize the cache here.
605 */
607 elog(ERROR, "invalid cache ID: %d", cacheId);
608 if (!SysCache[cacheId]->cc_tupdesc)
609 {
610 InitCatCachePhase2(SysCache[cacheId], false);
611 Assert(SysCache[cacheId]->cc_tupdesc);
612 }
613
615 SysCache[cacheId]->cc_tupdesc,
616 isNull);
617}
618
619/*
620 * SysCacheGetAttrNotNull
621 *
622 * As above, a version of SysCacheGetAttr which knows that the attr cannot
623 * be NULL.
624 */
625Datum
628{
629 bool isnull;
630 Datum attr;
631
632 attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
633
634 if (isnull)
635 {
636 elog(ERROR,
637 "unexpected null value in cached tuple for catalog %s column %s",
638 get_rel_name(cacheinfo[cacheId].reloid),
639 NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc, attributeNumber - 1)->attname));
640 }
641
642 return attr;
643}
644
645/*
646 * GetSysCacheHashValue
647 *
648 * Get the hash value that would be used for a tuple in the specified cache
649 * with the given search keys.
650 *
651 * The reason for exposing this as part of the API is that the hash value is
652 * exposed in cache invalidation operations, so there are places outside the
653 * catcache code that need to be able to compute the hash values.
654 */
655uint32
657 Datum key1,
658 Datum key2,
659 Datum key3,
660 Datum key4)
661{
663 elog(ERROR, "invalid cache ID: %d", cacheId);
664
665 return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
666}
667
668/*
669 * List-search interface
670 */
671struct catclist *
674{
676 elog(ERROR, "invalid cache ID: %d", cacheId);
677
678 return SearchCatCacheList(SysCache[cacheId], nkeys,
679 key1, key2, key3);
680}
681
682/*
683 * SysCacheInvalidate
684 *
685 * Invalidate entries in the specified cache, given a hash value.
686 * See CatCacheInvalidate() for more info.
687 *
688 * This routine is only quasi-public: it should only be used by inval.c.
689 */
690void
692{
694 elog(ERROR, "invalid cache ID: %d", cacheId);
695
696 /* if this cache isn't initialized yet, no need to do anything */
697 if (!SysCache[cacheId])
698 return;
699
700 CatCacheInvalidate(SysCache[cacheId], hashValue);
701}
702
703/*
704 * Certain relations that do not have system caches send snapshot invalidation
705 * messages in lieu of catcache messages. This is for the benefit of
706 * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
707 * for scanning one of those catalogs, rather than taking a new one, if no
708 * invalidation has been received.
709 *
710 * Relations that have syscaches need not (and must not) be listed here. The
711 * catcache invalidation messages will also flush the snapshot. If you add a
712 * syscache for one of these relations, remove it from this list.
713 */
714bool
716{
717 switch (relid)
718 {
720 case DependRelationId:
726 return true;
727 default:
728 break;
729 }
730
731 return false;
732}
733
734/*
735 * Test whether a relation has a system cache.
736 */
737bool
739{
740 int low = 0,
741 high = SysCacheRelationOidSize - 1;
742
743 while (low <= high)
744 {
745 int middle = low + (high - low) / 2;
746
747 if (SysCacheRelationOid[middle] == relid)
748 return true;
749 if (SysCacheRelationOid[middle] < relid)
750 low = middle + 1;
751 else
752 high = middle - 1;
753 }
754
755 return false;
756}
757
758/*
759 * Test whether a relation supports a system cache, ie it is either a
760 * cached table or the index used for a cache.
761 */
762bool
764{
765 int low = 0,
767
768 while (low <= high)
769 {
770 int middle = low + (high - low) / 2;
771
772 if (SysCacheSupportingRelOid[middle] == relid)
773 return true;
774 if (SysCacheSupportingRelOid[middle] < relid)
775 low = middle + 1;
776 else
777 high = middle - 1;
778 }
779
780 return false;
781}
782
783
784/*
785 * OID comparator for qsort
786 */
787static int
788oid_compare(const void *a, const void *b)
789{
790 Oid oa = *((const Oid *) a);
791 Oid ob = *((const Oid *) b);
792
793 return pg_cmp_u32(oa, ob);
794}
int16 AttrNumber
Definition attnum.h:21
#define NameStr(name)
Definition c.h:835
#define Assert(condition)
Definition c.h:943
int16_t int16
Definition c.h:619
uint32_t uint32
Definition c.h:624
#define lengthof(array)
Definition c.h:873
#define StaticAssertDecl(condition, errmessage)
Definition c.h:1008
#define OidIsValid(objectId)
Definition c.h:858
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Definition catcache.c:885
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
Definition catcache.c:1386
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
Definition catcache.c:1394
void InitCatCachePhase2(CatCache *cache, bool touch_index)
Definition catcache.c:1245
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
Definition catcache.c:1740
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1707
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1402
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
Definition catcache.c:632
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
Definition catcache.c:1378
void ReleaseCatCache(HeapTuple tuple)
Definition catcache.c:1668
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition catcache.c:1361
uint32 result
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
Oid MyDatabaseId
Definition globals.c:96
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:686
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
static int pg_cmp_u32(uint32 a, uint32 b)
Definition int.h:719
void AcceptInvalidationMessages(void)
Definition inval.c:930
int b
Definition isn.c:74
int a
Definition isn.c:73
bool ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *pointer2)
Definition itemptr.c:35
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition itemptr.h:184
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition itemptr.h:103
static bool ItemPointerIsValid(const ItemPointerData *pointer)
Definition itemptr.h:83
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition lock.c:807
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition lock.c:2111
int LOCKMODE
Definition lockdefs.h:26
#define InplaceUpdateTupleLock
Definition lockdefs.h:48
#define SET_LOCKTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
Definition locktag.h:117
char * get_rel_name(Oid relid)
Definition lsyscache.c:2148
NameData attname
int16 attnum
FormData_pg_attribute * Form_pg_attribute
#define qsort(a, b, c, d)
Definition port.h:495
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
#define InvalidOid
unsigned int Oid
static int fb(int x)
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition qunique.h:21
ItemPointerData t_self
Definition htup.h:65
int key[4]
Definition syscache.c:75
int nkeys
Definition syscache.c:74
int nbuckets
Definition syscache.c:76
Oid indoid
Definition syscache.c:73
Oid reloid
Definition syscache.c:72
Oid cc_reloid
Definition catcache.h:60
bool cc_relisshared
Definition catcache.h:62
short nkeys
Definition catcache.h:179
Oid GetSysCacheOid(SysCacheIdentifier cacheId, AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:444
HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname)
Definition syscache.c:499
bool RelationHasSysCache(Oid relid)
Definition syscache.c:738
HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
Definition syscache.c:562
void InitCatalogCache(void)
Definition syscache.c:111
HeapTuple SearchSysCacheLockedCopy1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:400
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
static bool CacheInitialized
Definition syscache.c:89
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
static int oid_compare(const void *a, const void *b)
Definition syscache.c:788
uint32 GetSysCacheHashValue(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:656
static int SysCacheSupportingRelOidSize
Definition syscache.c:97
HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum)
Definition syscache.c:539
bool RelationSupportsSysCache(Oid relid)
Definition syscache.c:763
HeapTuple SearchSysCacheCopy(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:375
bool SearchSysCacheExistsAttName(Oid relid, const char *attname)
Definition syscache.c:518
HeapTuple SearchSysCacheLocked1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:283
HeapTuple SearchSysCache(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:209
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:241
void InitCatalogCachePhase2(void)
Definition syscache.c:181
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:476
void SysCacheInvalidate(SysCacheIdentifier cacheId, uint32 hashValue)
Definition syscache.c:691
static Oid SysCacheRelationOid[SysCacheSize]
Definition syscache.c:92
bool SearchSysCacheExists(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:421
static CatCache * SysCache[SysCacheSize]
Definition syscache.c:87
static Oid SysCacheSupportingRelOid[SysCacheSize *2]
Definition syscache.c:96
static int SysCacheRelationOidSize
Definition syscache.c:93
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition syscache.c:715
struct catclist * SearchSysCacheList(SysCacheIdentifier cacheId, int nkeys, Datum key1, Datum key2, Datum key3)
Definition syscache.c:672
HeapTuple SearchSysCache4(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:251
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178