PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2016, 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/indexing.h"
26 #include "catalog/pg_aggregate.h"
27 #include "catalog/pg_am.h"
28 #include "catalog/pg_amop.h"
29 #include "catalog/pg_amproc.h"
31 #include "catalog/pg_authid.h"
32 #include "catalog/pg_cast.h"
33 #include "catalog/pg_collation.h"
34 #include "catalog/pg_constraint.h"
35 #include "catalog/pg_conversion.h"
36 #include "catalog/pg_database.h"
38 #include "catalog/pg_default_acl.h"
39 #include "catalog/pg_depend.h"
40 #include "catalog/pg_description.h"
41 #include "catalog/pg_enum.h"
46 #include "catalog/pg_language.h"
47 #include "catalog/pg_namespace.h"
48 #include "catalog/pg_opclass.h"
49 #include "catalog/pg_operator.h"
50 #include "catalog/pg_opfamily.h"
51 #include "catalog/pg_proc.h"
52 #include "catalog/pg_range.h"
53 #include "catalog/pg_rewrite.h"
54 #include "catalog/pg_seclabel.h"
55 #include "catalog/pg_shdepend.h"
57 #include "catalog/pg_shseclabel.h"
59 #include "catalog/pg_statistic.h"
60 #include "catalog/pg_tablespace.h"
61 #include "catalog/pg_transform.h"
62 #include "catalog/pg_ts_config.h"
64 #include "catalog/pg_ts_dict.h"
65 #include "catalog/pg_ts_parser.h"
66 #include "catalog/pg_ts_template.h"
67 #include "catalog/pg_type.h"
69 #include "utils/rel.h"
70 #include "utils/catcache.h"
71 #include "utils/syscache.h"
72 
73 
74 /*---------------------------------------------------------------------------
75 
76  Adding system caches:
77 
78  Add your new cache to the list in include/utils/syscache.h.
79  Keep the list sorted alphabetically.
80 
81  Add your entry to the cacheinfo[] array below. All cache lists are
82  alphabetical, so add it in the proper place. Specify the relation OID,
83  index OID, number of keys, key attribute numbers, and initial number of
84  hash buckets.
85 
86  The number of hash buckets must be a power of 2. It's reasonable to
87  set this to the number of entries that might be in the particular cache
88  in a medium-size database.
89 
90  There must be a unique index underlying each syscache (ie, an index
91  whose key is the same as that of the cache). If there is not one
92  already, add definitions for it to include/catalog/indexing.h: you need
93  to add a DECLARE_UNIQUE_INDEX macro and a #define for the index OID.
94  (Adding an index requires a catversion.h update, while simply
95  adding/deleting caches only requires a recompile.)
96 
97  Finally, any place your relation gets heap_insert() or
98  heap_update() calls, make sure there is a CatalogUpdateIndexes() or
99  similar call. The heap_* calls do not update indexes.
100 
101  bjm 1999/11/22
102 
103 *---------------------------------------------------------------------------
104 */
105 
106 /*
107  * struct cachedesc: information defining a single syscache
108  */
109 struct cachedesc
110 {
111  Oid reloid; /* OID of the relation being cached */
112  Oid indoid; /* OID of index relation for this cache */
113  int nkeys; /* # of keys needed for cache lookup */
114  int key[4]; /* attribute numbers of key attrs */
115  int nbuckets; /* number of hash buckets for this cache */
116 };
117 
118 static const struct cachedesc cacheinfo[] = {
119  {AggregateRelationId, /* AGGFNOID */
121  1,
122  {
124  0,
125  0,
126  0
127  },
128  16
129  },
130  {AccessMethodRelationId, /* AMNAME */
132  1,
133  {
135  0,
136  0,
137  0
138  },
139  4
140  },
141  {AccessMethodRelationId, /* AMOID */
142  AmOidIndexId,
143  1,
144  {
146  0,
147  0,
148  0
149  },
150  4
151  },
152  {AccessMethodOperatorRelationId, /* AMOPOPID */
154  3,
155  {
159  0
160  },
161  64
162  },
163  {AccessMethodOperatorRelationId, /* AMOPSTRATEGY */
165  4,
166  {
171  },
172  64
173  },
174  {AccessMethodProcedureRelationId, /* AMPROCNUM */
176  4,
177  {
182  },
183  16
184  },
185  {AttributeRelationId, /* ATTNAME */
187  2,
188  {
191  0,
192  0
193  },
194  32
195  },
196  {AttributeRelationId, /* ATTNUM */
198  2,
199  {
202  0,
203  0
204  },
205  128
206  },
207  {AuthMemRelationId, /* AUTHMEMMEMROLE */
209  2,
210  {
213  0,
214  0
215  },
216  8
217  },
218  {AuthMemRelationId, /* AUTHMEMROLEMEM */
220  2,
221  {
224  0,
225  0
226  },
227  8
228  },
229  {AuthIdRelationId, /* AUTHNAME */
231  1,
232  {
234  0,
235  0,
236  0
237  },
238  8
239  },
240  {AuthIdRelationId, /* AUTHOID */
242  1,
243  {
245  0,
246  0,
247  0
248  },
249  8
250  },
251  {
252  CastRelationId, /* CASTSOURCETARGET */
254  2,
255  {
258  0,
259  0
260  },
261  256
262  },
263  {OperatorClassRelationId, /* CLAAMNAMENSP */
265  3,
266  {
270  0
271  },
272  8
273  },
274  {OperatorClassRelationId, /* CLAOID */
276  1,
277  {
279  0,
280  0,
281  0
282  },
283  8
284  },
285  {CollationRelationId, /* COLLNAMEENCNSP */
287  3,
288  {
292  0
293  },
294  8
295  },
296  {CollationRelationId, /* COLLOID */
298  1,
299  {
301  0,
302  0,
303  0
304  },
305  8
306  },
307  {ConversionRelationId, /* CONDEFAULT */
309  4,
310  {
315  },
316  8
317  },
318  {ConversionRelationId, /* CONNAMENSP */
320  2,
321  {
324  0,
325  0
326  },
327  8
328  },
329  {ConstraintRelationId, /* CONSTROID */
331  1,
332  {
334  0,
335  0,
336  0
337  },
338  16
339  },
340  {ConversionRelationId, /* CONVOID */
342  1,
343  {
345  0,
346  0,
347  0
348  },
349  8
350  },
351  {DatabaseRelationId, /* DATABASEOID */
353  1,
354  {
356  0,
357  0,
358  0
359  },
360  4
361  },
362  {DefaultAclRelationId, /* DEFACLROLENSPOBJ */
364  3,
365  {
369  0
370  },
371  8
372  },
373  {EnumRelationId, /* ENUMOID */
375  1,
376  {
378  0,
379  0,
380  0
381  },
382  8
383  },
384  {EnumRelationId, /* ENUMTYPOIDNAME */
386  2,
387  {
390  0,
391  0
392  },
393  8
394  },
395  {EventTriggerRelationId, /* EVENTTRIGGERNAME */
397  1,
398  {
400  0,
401  0,
402  0
403  },
404  8
405  },
406  {EventTriggerRelationId, /* EVENTTRIGGEROID */
408  1,
409  {
411  0,
412  0,
413  0
414  },
415  8
416  },
417  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPERNAME */
419  1,
420  {
422  0,
423  0,
424  0
425  },
426  2
427  },
428  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPEROID */
430  1,
431  {
433  0,
434  0,
435  0
436  },
437  2
438  },
439  {ForeignServerRelationId, /* FOREIGNSERVERNAME */
441  1,
442  {
444  0,
445  0,
446  0
447  },
448  2
449  },
450  {ForeignServerRelationId, /* FOREIGNSERVEROID */
452  1,
453  {
455  0,
456  0,
457  0
458  },
459  2
460  },
461  {ForeignTableRelationId, /* FOREIGNTABLEREL */
463  1,
464  {
466  0,
467  0,
468  0
469  },
470  4
471  },
472  {IndexRelationId, /* INDEXRELID */
474  1,
475  {
477  0,
478  0,
479  0
480  },
481  64
482  },
483  {LanguageRelationId, /* LANGNAME */
485  1,
486  {
488  0,
489  0,
490  0
491  },
492  4
493  },
494  {LanguageRelationId, /* LANGOID */
496  1,
497  {
499  0,
500  0,
501  0
502  },
503  4
504  },
505  {NamespaceRelationId, /* NAMESPACENAME */
507  1,
508  {
510  0,
511  0,
512  0
513  },
514  4
515  },
516  {NamespaceRelationId, /* NAMESPACEOID */
518  1,
519  {
521  0,
522  0,
523  0
524  },
525  16
526  },
527  {OperatorRelationId, /* OPERNAMENSP */
529  4,
530  {
535  },
536  256
537  },
538  {OperatorRelationId, /* OPEROID */
540  1,
541  {
543  0,
544  0,
545  0
546  },
547  32
548  },
549  {OperatorFamilyRelationId, /* OPFAMILYAMNAMENSP */
551  3,
552  {
556  0
557  },
558  8
559  },
560  {OperatorFamilyRelationId, /* OPFAMILYOID */
562  1,
563  {
565  0,
566  0,
567  0
568  },
569  8
570  },
571  {ProcedureRelationId, /* PROCNAMEARGSNSP */
573  3,
574  {
578  0
579  },
580  128
581  },
582  {ProcedureRelationId, /* PROCOID */
584  1,
585  {
587  0,
588  0,
589  0
590  },
591  128
592  },
593  {RangeRelationId, /* RANGETYPE */
595  1,
596  {
598  0,
599  0,
600  0
601  },
602  4
603  },
604  {RelationRelationId, /* RELNAMENSP */
606  2,
607  {
610  0,
611  0
612  },
613  128
614  },
615  {RelationRelationId, /* RELOID */
617  1,
618  {
620  0,
621  0,
622  0
623  },
624  128
625  },
626  {ReplicationOriginRelationId, /* REPLORIGIDENT */
628  1,
629  {
631  0,
632  0,
633  0
634  },
635  16
636  },
637  {ReplicationOriginRelationId, /* REPLORIGNAME */
639  1,
640  {
642  0,
643  0,
644  0
645  },
646  16
647  },
648  {RewriteRelationId, /* RULERELNAME */
650  2,
651  {
654  0,
655  0
656  },
657  8
658  },
659  {StatisticRelationId, /* STATRELATTINH */
661  3,
662  {
666  0
667  },
668  128
669  },
670  {TableSpaceRelationId, /* TABLESPACEOID */
672  1,
673  {
675  0,
676  0,
677  0,
678  },
679  4
680  },
681  {TransformRelationId, /* TRFOID */
683  1,
684  {
686  0,
687  0,
688  0,
689  },
690  16
691  },
692  {TransformRelationId, /* TRFTYPELANG */
694  2,
695  {
698  0,
699  0,
700  },
701  16
702  },
703  {TSConfigMapRelationId, /* TSCONFIGMAP */
705  3,
706  {
710  0
711  },
712  2
713  },
714  {TSConfigRelationId, /* TSCONFIGNAMENSP */
716  2,
717  {
720  0,
721  0
722  },
723  2
724  },
725  {TSConfigRelationId, /* TSCONFIGOID */
727  1,
728  {
730  0,
731  0,
732  0
733  },
734  2
735  },
736  {TSDictionaryRelationId, /* TSDICTNAMENSP */
738  2,
739  {
742  0,
743  0
744  },
745  2
746  },
747  {TSDictionaryRelationId, /* TSDICTOID */
749  1,
750  {
752  0,
753  0,
754  0
755  },
756  2
757  },
758  {TSParserRelationId, /* TSPARSERNAMENSP */
760  2,
761  {
764  0,
765  0
766  },
767  2
768  },
769  {TSParserRelationId, /* TSPARSEROID */
771  1,
772  {
774  0,
775  0,
776  0
777  },
778  2
779  },
780  {TSTemplateRelationId, /* TSTEMPLATENAMENSP */
782  2,
783  {
786  0,
787  0
788  },
789  2
790  },
791  {TSTemplateRelationId, /* TSTEMPLATEOID */
793  1,
794  {
796  0,
797  0,
798  0
799  },
800  2
801  },
802  {TypeRelationId, /* TYPENAMENSP */
804  2,
805  {
808  0,
809  0
810  },
811  64
812  },
813  {TypeRelationId, /* TYPEOID */
815  1,
816  {
818  0,
819  0,
820  0
821  },
822  64
823  },
824  {UserMappingRelationId, /* USERMAPPINGOID */
826  1,
827  {
829  0,
830  0,
831  0
832  },
833  2
834  },
835  {UserMappingRelationId, /* USERMAPPINGUSERSERVER */
837  2,
838  {
841  0,
842  0
843  },
844  2
845  }
846 };
847 
848 #define SysCacheSize ((int) lengthof(cacheinfo))
849 
851 
852 static bool CacheInitialized = false;
853 
854 /* Sorted array of OIDs of tables that have caches on them */
857 
858 /* Sorted array of OIDs of tables and indexes used by caches */
861 
862 static int oid_compare(const void *a, const void *b);
863 
864 
865 /*
866  * InitCatalogCache - initialize the caches
867  *
868  * Note that no database access is done here; we only allocate memory
869  * and initialize the cache structure. Interrogation of the database
870  * to complete initialization of a cache happens upon first use
871  * of that cache.
872  */
873 void
875 {
876  int cacheId;
877  int i,
878  j;
879 
881 
883 
884  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
885  {
886  SysCache[cacheId] = InitCatCache(cacheId,
887  cacheinfo[cacheId].reloid,
888  cacheinfo[cacheId].indoid,
889  cacheinfo[cacheId].nkeys,
890  cacheinfo[cacheId].key,
891  cacheinfo[cacheId].nbuckets);
892  if (!PointerIsValid(SysCache[cacheId]))
893  elog(ERROR, "could not initialize cache %u (%d)",
894  cacheinfo[cacheId].reloid, cacheId);
895  /* Accumulate data for OID lists, too */
897  cacheinfo[cacheId].reloid;
899  cacheinfo[cacheId].reloid;
901  cacheinfo[cacheId].indoid;
902  /* see comments for RelationInvalidatesSnapshotsOnly */
903  Assert(!RelationInvalidatesSnapshotsOnly(cacheinfo[cacheId].reloid));
904  }
905 
908 
909  /* Sort and de-dup OID arrays, so we can use binary search. */
911  sizeof(Oid), oid_compare);
912  for (i = 1, j = 0; i < SysCacheRelationOidSize; i++)
913  {
916  }
917  SysCacheRelationOidSize = j + 1;
918 
920  sizeof(Oid), oid_compare);
921  for (i = 1, j = 0; i < SysCacheSupportingRelOidSize; i++)
922  {
925  }
926  SysCacheSupportingRelOidSize = j + 1;
927 
928  CacheInitialized = true;
929 }
930 
931 /*
932  * InitCatalogCachePhase2 - finish initializing the caches
933  *
934  * Finish initializing all the caches, including necessary database
935  * access.
936  *
937  * This is *not* essential; normally we allow syscaches to be initialized
938  * on first use. However, it is useful as a mechanism to preload the
939  * relcache with entries for the most-commonly-used system catalogs.
940  * Therefore, we invoke this routine when we need to write a new relcache
941  * init file.
942  */
943 void
945 {
946  int cacheId;
947 
949 
950  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
951  InitCatCachePhase2(SysCache[cacheId], true);
952 }
953 
954 
955 /*
956  * SearchSysCache
957  *
958  * A layer on top of SearchCatCache that does the initialization and
959  * key-setting for you.
960  *
961  * Returns the cache copy of the tuple if one is found, NULL if not.
962  * The tuple is the 'cache' copy and must NOT be modified!
963  *
964  * When the caller is done using the tuple, call ReleaseSysCache()
965  * to release the reference count grabbed by SearchSysCache(). If this
966  * is not done, the tuple will remain locked in cache until end of
967  * transaction, which is tolerable but not desirable.
968  *
969  * CAUTION: The tuple that is returned must NOT be freed by the caller!
970  */
971 HeapTuple
972 SearchSysCache(int cacheId,
973  Datum key1,
974  Datum key2,
975  Datum key3,
976  Datum key4)
977 {
978  if (cacheId < 0 || cacheId >= SysCacheSize ||
979  !PointerIsValid(SysCache[cacheId]))
980  elog(ERROR, "invalid cache ID: %d", cacheId);
981 
982  return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
983 }
984 
985 /*
986  * ReleaseSysCache
987  * Release previously grabbed reference count on a tuple
988  */
989 void
991 {
992  ReleaseCatCache(tuple);
993 }
994 
995 /*
996  * SearchSysCacheCopy
997  *
998  * A convenience routine that does SearchSysCache and (if successful)
999  * returns a modifiable copy of the syscache entry. The original
1000  * syscache entry is released before returning. The caller should
1001  * heap_freetuple() the result when done with it.
1002  */
1003 HeapTuple
1005  Datum key1,
1006  Datum key2,
1007  Datum key3,
1008  Datum key4)
1009 {
1010  HeapTuple tuple,
1011  newtuple;
1012 
1013  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1014  if (!HeapTupleIsValid(tuple))
1015  return tuple;
1016  newtuple = heap_copytuple(tuple);
1017  ReleaseSysCache(tuple);
1018  return newtuple;
1019 }
1020 
1021 /*
1022  * SearchSysCacheExists
1023  *
1024  * A convenience routine that just probes to see if a tuple can be found.
1025  * No lock is retained on the syscache entry.
1026  */
1027 bool
1029  Datum key1,
1030  Datum key2,
1031  Datum key3,
1032  Datum key4)
1033 {
1034  HeapTuple tuple;
1035 
1036  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1037  if (!HeapTupleIsValid(tuple))
1038  return false;
1039  ReleaseSysCache(tuple);
1040  return true;
1041 }
1042 
1043 /*
1044  * GetSysCacheOid
1045  *
1046  * A convenience routine that does SearchSysCache and returns the OID
1047  * of the found tuple, or InvalidOid if no tuple could be found.
1048  * No lock is retained on the syscache entry.
1049  */
1050 Oid
1051 GetSysCacheOid(int cacheId,
1052  Datum key1,
1053  Datum key2,
1054  Datum key3,
1055  Datum key4)
1056 {
1057  HeapTuple tuple;
1058  Oid result;
1059 
1060  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1061  if (!HeapTupleIsValid(tuple))
1062  return InvalidOid;
1063  result = HeapTupleGetOid(tuple);
1064  ReleaseSysCache(tuple);
1065  return result;
1066 }
1067 
1068 
1069 /*
1070  * SearchSysCacheAttName
1071  *
1072  * This routine is equivalent to SearchSysCache on the ATTNAME cache,
1073  * except that it will return NULL if the found attribute is marked
1074  * attisdropped. This is convenient for callers that want to act as
1075  * though dropped attributes don't exist.
1076  */
1077 HeapTuple
1078 SearchSysCacheAttName(Oid relid, const char *attname)
1079 {
1080  HeapTuple tuple;
1081 
1082  tuple = SearchSysCache2(ATTNAME,
1083  ObjectIdGetDatum(relid),
1084  CStringGetDatum(attname));
1085  if (!HeapTupleIsValid(tuple))
1086  return NULL;
1087  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
1088  {
1089  ReleaseSysCache(tuple);
1090  return NULL;
1091  }
1092  return tuple;
1093 }
1094 
1095 /*
1096  * SearchSysCacheCopyAttName
1097  *
1098  * As above, an attisdropped-aware version of SearchSysCacheCopy.
1099  */
1100 HeapTuple
1101 SearchSysCacheCopyAttName(Oid relid, const char *attname)
1102 {
1103  HeapTuple tuple,
1104  newtuple;
1105 
1106  tuple = SearchSysCacheAttName(relid, attname);
1107  if (!HeapTupleIsValid(tuple))
1108  return tuple;
1109  newtuple = heap_copytuple(tuple);
1110  ReleaseSysCache(tuple);
1111  return newtuple;
1112 }
1113 
1114 /*
1115  * SearchSysCacheExistsAttName
1116  *
1117  * As above, an attisdropped-aware version of SearchSysCacheExists.
1118  */
1119 bool
1120 SearchSysCacheExistsAttName(Oid relid, const char *attname)
1121 {
1122  HeapTuple tuple;
1123 
1124  tuple = SearchSysCacheAttName(relid, attname);
1125  if (!HeapTupleIsValid(tuple))
1126  return false;
1127  ReleaseSysCache(tuple);
1128  return true;
1129 }
1130 
1131 
1132 /*
1133  * SysCacheGetAttr
1134  *
1135  * Given a tuple previously fetched by SearchSysCache(),
1136  * extract a specific attribute.
1137  *
1138  * This is equivalent to using heap_getattr() on a tuple fetched
1139  * from a non-cached relation. Usually, this is only used for attributes
1140  * that could be NULL or variable length; the fixed-size attributes in
1141  * a system table are accessed just by mapping the tuple onto the C struct
1142  * declarations from include/catalog/.
1143  *
1144  * As with heap_getattr(), if the attribute is of a pass-by-reference type
1145  * then a pointer into the tuple data area is returned --- the caller must
1146  * not modify or pfree the datum!
1147  *
1148  * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
1149  * a different cache for the same catalog the tuple was fetched from.
1150  */
1151 Datum
1152 SysCacheGetAttr(int cacheId, HeapTuple tup,
1153  AttrNumber attributeNumber,
1154  bool *isNull)
1155 {
1156  /*
1157  * We just need to get the TupleDesc out of the cache entry, and then we
1158  * can apply heap_getattr(). Normally the cache control data is already
1159  * valid (because the caller recently fetched the tuple via this same
1160  * cache), but there are cases where we have to initialize the cache here.
1161  */
1162  if (cacheId < 0 || cacheId >= SysCacheSize ||
1163  !PointerIsValid(SysCache[cacheId]))
1164  elog(ERROR, "invalid cache ID: %d", cacheId);
1165  if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
1166  {
1167  InitCatCachePhase2(SysCache[cacheId], false);
1168  Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
1169  }
1170 
1171  return heap_getattr(tup, attributeNumber,
1172  SysCache[cacheId]->cc_tupdesc,
1173  isNull);
1174 }
1175 
1176 /*
1177  * GetSysCacheHashValue
1178  *
1179  * Get the hash value that would be used for a tuple in the specified cache
1180  * with the given search keys.
1181  *
1182  * The reason for exposing this as part of the API is that the hash value is
1183  * exposed in cache invalidation operations, so there are places outside the
1184  * catcache code that need to be able to compute the hash values.
1185  */
1186 uint32
1188  Datum key1,
1189  Datum key2,
1190  Datum key3,
1191  Datum key4)
1192 {
1193  if (cacheId < 0 || cacheId >= SysCacheSize ||
1194  !PointerIsValid(SysCache[cacheId]))
1195  elog(ERROR, "invalid cache ID: %d", cacheId);
1196 
1197  return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
1198 }
1199 
1200 /*
1201  * List-search interface
1202  */
1203 struct catclist *
1204 SearchSysCacheList(int cacheId, int nkeys,
1205  Datum key1, Datum key2, Datum key3, Datum key4)
1206 {
1207  if (cacheId < 0 || cacheId >= SysCacheSize ||
1208  !PointerIsValid(SysCache[cacheId]))
1209  elog(ERROR, "invalid cache ID: %d", cacheId);
1210 
1211  return SearchCatCacheList(SysCache[cacheId], nkeys,
1212  key1, key2, key3, key4);
1213 }
1214 
1215 /*
1216  * Certain relations that do not have system caches send snapshot invalidation
1217  * messages in lieu of catcache messages. This is for the benefit of
1218  * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
1219  * for scanning one of those catalogs, rather than taking a new one, if no
1220  * invalidation has been received.
1221  *
1222  * Relations that have syscaches need not (and must not) be listed here. The
1223  * catcache invalidation messages will also flush the snapshot. If you add a
1224  * syscache for one of these relations, remove it from this list.
1225  */
1226 bool
1228 {
1229  switch (relid)
1230  {
1232  case DependRelationId:
1234  case DescriptionRelationId:
1236  case SecLabelRelationId:
1238  return true;
1239  default:
1240  break;
1241  }
1242 
1243  return false;
1244 }
1245 
1246 /*
1247  * Test whether a relation has a system cache.
1248  */
1249 bool
1251 {
1252  int low = 0,
1253  high = SysCacheRelationOidSize - 1;
1254 
1255  while (low <= high)
1256  {
1257  int middle = low + (high - low) / 2;
1258 
1259  if (SysCacheRelationOid[middle] == relid)
1260  return true;
1261  if (SysCacheRelationOid[middle] < relid)
1262  low = middle + 1;
1263  else
1264  high = middle - 1;
1265  }
1266 
1267  return false;
1268 }
1269 
1270 /*
1271  * Test whether a relation supports a system cache, ie it is either a
1272  * cached table or the index used for a cache.
1273  */
1274 bool
1276 {
1277  int low = 0,
1278  high = SysCacheSupportingRelOidSize - 1;
1279 
1280  while (low <= high)
1281  {
1282  int middle = low + (high - low) / 2;
1283 
1284  if (SysCacheSupportingRelOid[middle] == relid)
1285  return true;
1286  if (SysCacheSupportingRelOid[middle] < relid)
1287  low = middle + 1;
1288  else
1289  high = middle - 1;
1290  }
1291 
1292  return false;
1293 }
1294 
1295 
1296 /*
1297  * OID comparator for pg_qsort
1298  */
1299 static int
1300 oid_compare(const void *a, const void *b)
1301 {
1302  Oid oa = *((const Oid *) a);
1303  Oid ob = *((const Oid *) b);
1304 
1305  if (oa == ob)
1306  return 0;
1307  return (oa > ob) ? 1 : -1;
1308 }
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:972
#define ConstraintOidIndexId
Definition: indexing.h:124
#define AttributeRelidNumIndexId
Definition: indexing.h:88
#define Anum_pg_event_trigger_evtname
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define NamespaceOidIndexId
Definition: indexing.h:182
#define ProcedureOidIndexId
Definition: indexing.h:203
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:192
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define CollationOidIndexId
Definition: indexing.h:115
#define Anum_pg_opclass_opcmethod
Definition: pg_opclass.h:75
static bool CacheInitialized
Definition: syscache.c:852
#define Anum_pg_operator_oprleft
Definition: pg_operator.h:71
bool RelationHasSysCache(Oid relid)
Definition: syscache.c:1250
#define OperatorRelationId
Definition: pg_operator.h:32
#define Anum_pg_cast_casttarget
Definition: pg_cast.h:79
#define Anum_pg_ts_config_map_mapseqno
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define IndexRelidIndexId
Definition: indexing.h:158
#define Anum_pg_opfamily_opfmethod
Definition: pg_opfamily.h:51
#define Anum_pg_replication_origin_roident
static int SysCacheSupportingRelOidSize
Definition: syscache.c:860
#define SharedDependRelationId
Definition: pg_shdepend.h:29
struct catclist * SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1204
#define TransformRelationId
Definition: pg_transform.h:25
#define Anum_pg_user_mapping_umuser
#define Anum_pg_attribute_attnum
Definition: pg_attribute.h:197
#define Anum_pg_statistic_stainherit
Definition: pg_statistic.h:137
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define Anum_pg_user_mapping_umserver
#define RewriteRelRulenameIndexId
Definition: indexing.h:210
static Oid SysCacheSupportingRelOid[SysCacheSize *2]
Definition: syscache.c:859
#define ForeignServerNameIndexId
Definition: indexing.h:278
#define Anum_pg_type_typname
Definition: pg_type.h:240
#define ProcedureRelationId
Definition: pg_proc.h:33
#define AuthMemRelationId
#define IndexRelationId
Definition: pg_index.h:29
#define DatabaseRelationId
Definition: pg_database.h:29
#define RelationRelationId
Definition: pg_class.h:29
#define Anum_pg_conversion_contoencoding
Definition: pg_conversion.h:68
#define CastSourceTargetIndexId
Definition: indexing.h:103
#define DependRelationId
Definition: pg_depend.h:29
#define Anum_pg_opfamily_opfnamespace
Definition: pg_opfamily.h:53
#define OperatorClassRelationId
Definition: pg_opclass.h:49
#define OperatorFamilyRelationId
Definition: pg_opfamily.h:29
#define Anum_pg_rewrite_ev_class
Definition: pg_rewrite.h:61
#define AttributeRelationId
Definition: pg_attribute.h:33
#define Anum_pg_default_acl_defaclrole
#define Anum_pg_statistic_staattnum
Definition: pg_statistic.h:136
#define ClassNameNspIndexId
Definition: indexing.h:108
static int SysCacheRelationOidSize
Definition: syscache.c:856
#define Anum_pg_amop_amoprighttype
Definition: pg_amop.h:86
#define AuthIdOidIndexId
Definition: indexing.h:93
#define lengthof(array)
Definition: c.h:554
#define Anum_pg_enum_enumlabel
Definition: pg_enum.h:55
unsigned int Oid
Definition: postgres_ext.h:31
#define Anum_pg_opfamily_opfname
Definition: pg_opfamily.h:52
#define EnumTypIdLabelIndexId
Definition: indexing.h:151
Oid GetSysCacheOid(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1051
#define TypeRelationId
Definition: pg_type.h:34
#define Anum_pg_ts_config_map_maptokentype
#define Anum_pg_collation_collnamespace
Definition: pg_collation.h:55
#define Anum_pg_type_typnamespace
Definition: pg_type.h:241
bool SearchSysCacheExistsAttName(Oid relid, const char *attname)
Definition: syscache.c:1120
#define OpclassAmNameNspIndexId
Definition: indexing.h:185
#define DefaultAclRelationId
#define AccessMethodOperatorIndexId
Definition: indexing.h:71
#define Anum_pg_class_relnamespace
Definition: pg_class.h:102
short nkeys
Definition: catcache.h:146
#define AggregateFnoidIndexId
Definition: indexing.h:61
#define AccessMethodOperatorRelationId
Definition: pg_amop.h:54
static const struct cachedesc cacheinfo[]
Definition: syscache.c:118
bool SearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1028
#define AggregateRelationId
Definition: pg_aggregate.h:53
#define AmNameIndexId
Definition: indexing.h:64
#define TSDictionaryOidIndexId
Definition: indexing.h:253
#define AuthIdRelationId
Definition: pg_authid.h:42
Oid reloid
Definition: syscache.c:111
#define Anum_pg_amproc_amproclefttype
Definition: pg_amproc.h:67
#define Anum_pg_foreign_server_srvname
#define Anum_pg_conversion_conforencoding
Definition: pg_conversion.h:67
#define Anum_pg_cast_castsource
Definition: pg_cast.h:78
#define Anum_pg_rewrite_rulename
Definition: pg_rewrite.h:60
#define TSConfigRelationId
Definition: pg_ts_config.h:31
#define Anum_pg_opclass_opcnamespace
Definition: pg_opclass.h:77
#define ForeignDataWrapperNameIndexId
Definition: indexing.h:273
#define LanguageNameIndexId
Definition: indexing.h:169
#define Anum_pg_replication_origin_roname
#define TSConfigMapRelationId
#define ReplicationOriginIdentIndex
Definition: indexing.h:317
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define Anum_pg_aggregate_aggfnoid
Definition: pg_aggregate.h:95
#define EnumRelationId
Definition: pg_enum.h:32
#define Anum_pg_transform_trflang
Definition: pg_transform.h:43
#define TSDictionaryRelationId
Definition: pg_ts_dict.h:31
#define Anum_pg_opclass_opcname
Definition: pg_opclass.h:76
#define Anum_pg_ts_config_map_mapcfg
HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname)
Definition: syscache.c:1101
#define Anum_pg_amproc_amprocfamily
Definition: pg_amproc.h:66
#define TablespaceOidIndexId
Definition: indexing.h:221
#define Anum_pg_ts_config_cfgnamespace
Definition: pg_ts_config.h:49
#define Anum_pg_class_relname
Definition: pg_class.h:101
#define ConversionDefaultIndexId
Definition: indexing.h:127
#define AccessMethodRelationId
Definition: pg_am.h:32
#define SysCacheSize
Definition: syscache.c:848
int nbuckets
Definition: syscache.c:115
#define CStringGetDatum(X)
Definition: postgres.h:586
#define TransformOidIndexId
Definition: indexing.h:226
#define Anum_pg_amproc_amprocnum
Definition: pg_amproc.h:69
#define DatabaseOidIndexId
Definition: indexing.h:136
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
unsigned int uint32
Definition: c.h:265
#define Anum_pg_foreign_data_wrapper_fdwname
#define OperatorNameNspIndexId
Definition: indexing.h:192
#define SharedDescriptionRelationId
#define ClassOidIndexId
Definition: indexing.h:106
#define Anum_pg_ts_template_tmplnamespace
#define Anum_pg_statistic_starelid
Definition: pg_statistic.h:135
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Definition: catcache.c:726
#define Anum_pg_amproc_amprocrighttype
Definition: pg_amproc.h:68
Oid indoid
Definition: syscache.c:112
#define Anum_pg_amop_amoplefttype
Definition: pg_amop.h:85
#define Anum_pg_collation_collname
Definition: pg_collation.h:54
#define Anum_pg_operator_oprright
Definition: pg_operator.h:72
#define Anum_pg_language_lanname
Definition: pg_language.h:58
#define TSConfigOidIndexId
Definition: indexing.h:245
#define Anum_pg_range_rngtypid
Definition: pg_range.h:56
#define AuthMemRoleMemIndexId
Definition: indexing.h:96
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define SharedSecLabelRelationId
Definition: pg_shseclabel.h:21
int nkeys
Definition: syscache.c:113
#define AccessMethodProcedureIndexId
Definition: indexing.h:76
#define Anum_pg_foreign_table_ftrelid
static CatCache * SysCache[SysCacheSize]
Definition: syscache.c:850
#define OpfamilyAmNameNspIndexId
Definition: indexing.h:195
#define OperatorOidIndexId
Definition: indexing.h:190
#define Anum_pg_auth_members_roleid
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:990
#define SecLabelRelationId
Definition: pg_seclabel.h:21
#define StatisticRelationId
Definition: pg_statistic.h:29
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1152
static Oid SysCacheRelationOid[SysCacheSize]
Definition: syscache.c:855
#define Anum_pg_amop_amoppurpose
Definition: pg_amop.h:88
#define EnumOidIndexId
Definition: indexing.h:149
#define TSParserRelationId
Definition: pg_ts_parser.h:31
#define AttributeRelidNameIndexId
Definition: indexing.h:86
#define CollationRelationId
Definition: pg_collation.h:30
#define TSDictionaryNameNspIndexId
Definition: indexing.h:251
#define TypeNameNspIndexId
Definition: indexing.h:268
#define OpclassOidIndexId
Definition: indexing.h:187
#define InvalidOid
Definition: postgres_ext.h:36
void ReleaseCatCache(HeapTuple tuple)
Definition: catcache.c:1324
#define RewriteRelationId
Definition: pg_rewrite.h:32
uint32 GetSysCacheHashValue(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1187
#define TSTemplateNameNspIndexId
Definition: indexing.h:261
#define Anum_pg_operator_oprname
Definition: pg_operator.h:65
#define ProcedureNameArgsNspIndexId
Definition: indexing.h:205
#define NamespaceNameIndexId
Definition: indexing.h:180
#define ForeignServerRelationId
#define LanguageOidIndexId
Definition: indexing.h:171
#define Anum_pg_proc_proargtypes
Definition: pg_proc.h:109
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:667
#define Anum_pg_proc_pronamespace
Definition: pg_proc.h:91
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:1227
#define ForeignDataWrapperOidIndexId
Definition: indexing.h:271
#define EventTriggerRelationId
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:218
#define AuthMemMemRoleIndexId
Definition: indexing.h:98
#define EventTriggerOidIndexId
Definition: indexing.h:240
int key[4]
Definition: syscache.c:114
#define UserMappingOidIndexId
Definition: indexing.h:281
void pg_qsort(void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
Definition: qsort.c:113
#define CastRelationId
Definition: pg_cast.h:31
#define ConversionOidIndexId
Definition: indexing.h:131
#define UserMappingUserServerIndexId
Definition: indexing.h:283
#define ForeignDataWrapperRelationId
#define Anum_pg_ts_parser_prsnamespace
Definition: pg_ts_parser.h:52
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1078
#define TSParserOidIndexId
Definition: indexing.h:258
#define Anum_pg_conversion_conname
Definition: pg_conversion.h:64
#define CollationNameEncNspIndexId
Definition: indexing.h:113
#define RangeTypidIndexId
Definition: indexing.h:308
#define EventTriggerNameIndexId
Definition: indexing.h:238
#define DescriptionRelationId
#define Anum_pg_default_acl_defaclnamespace
#define TableSpaceRelationId
Definition: pg_tablespace.h:29
#define DefaultAclRoleNspObjIndexId
Definition: indexing.h:289
#define Anum_pg_transform_trftype
Definition: pg_transform.h:42
#define Anum_pg_authid_rolname
Definition: pg_authid.h:79
#define Anum_pg_ts_dict_dictnamespace
Definition: pg_ts_dict.h:53
#define Anum_pg_operator_oprnamespace
Definition: pg_operator.h:66
HeapTuple SearchSysCacheCopy(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1004
#define Anum_pg_ts_parser_prsname
Definition: pg_ts_parser.h:51
#define Anum_pg_enum_enumtypid
Definition: pg_enum.h:53
void InitCatalogCache(void)
Definition: syscache.c:874
#define Anum_pg_default_acl_defaclobjtype
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1110
static int oid_compare(const void *a, const void *b)
Definition: syscache.c:1300
#define Anum_pg_am_amname
Definition: pg_am.h:53
#define ReplicationOriginRelationId
#define Anum_pg_amop_amopopr
Definition: pg_amop.h:89
#define UserMappingRelationId
#define DbRoleSettingRelationId
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1396
#define ForeignTableRelationId
int i
#define RangeRelationId
Definition: pg_range.h:32
#define Anum_pg_amop_amopfamily
Definition: pg_amop.h:84
#define Anum_pg_collation_collencoding
Definition: pg_collation.h:57
#define AccessMethodStrategyIndexId
Definition: indexing.h:69
#define TSConfigMapIndexId
Definition: indexing.h:248
#define ConversionNameNspIndexId
Definition: indexing.h:129
#define LanguageRelationId
Definition: pg_language.h:29
#define Anum_pg_ts_template_tmplname
#define Anum_pg_ts_dict_dictname
Definition: pg_ts_dict.h:52
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define AmOidIndexId
Definition: indexing.h:66
#define ReplicationOriginNameIndex
Definition: indexing.h:320
#define elog
Definition: elog.h:218
void InitCatCachePhase2(CatCache *cache, bool touch_index)
Definition: catcache.c:995
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
bool RelationSupportsSysCache(Oid relid)
Definition: syscache.c:1275
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1356
#define TSTemplateOidIndexId
Definition: indexing.h:263
#define Anum_pg_conversion_connamespace
Definition: pg_conversion.h:65
#define Anum_pg_ts_config_cfgname
Definition: pg_ts_config.h:48
#define AuthIdRolnameIndexId
Definition: indexing.h:91
void InitCatalogCachePhase2(void)
Definition: syscache.c:944
#define AccessMethodProcedureRelationId
Definition: pg_amproc.h:43
#define PointerIsValid(pointer)
Definition: c.h:521
#define ConversionRelationId
Definition: pg_conversion.h:38
#define ForeignTableRelidIndexId
Definition: indexing.h:286
#define TSParserNameNspIndexId
Definition: indexing.h:256
int16 AttrNumber
Definition: attnum.h:21
#define TSConfigNameNspIndexId
Definition: indexing.h:243
#define TransformTypeLangIndexId
Definition: indexing.h:228
#define Anum_pg_attribute_attname
Definition: pg_attribute.h:193
#define Anum_pg_index_indexrelid
Definition: pg_index.h:74
#define TypeOidIndexId
Definition: indexing.h:266
#define ForeignServerOidIndexId
Definition: indexing.h:276
#define Anum_pg_namespace_nspname
Definition: pg_namespace.h:59
#define Anum_pg_proc_proname
Definition: pg_proc.h:90
#define TSTemplateRelationId
#define OpfamilyOidIndexId
Definition: indexing.h:197
#define Anum_pg_amop_amopstrategy
Definition: pg_amop.h:87
#define Anum_pg_auth_members_member
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:143