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-2017, 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"
52 #include "catalog/pg_proc.h"
53 #include "catalog/pg_publication.h"
55 #include "catalog/pg_range.h"
56 #include "catalog/pg_rewrite.h"
57 #include "catalog/pg_seclabel.h"
58 #include "catalog/pg_sequence.h"
59 #include "catalog/pg_shdepend.h"
61 #include "catalog/pg_shseclabel.h"
63 #include "catalog/pg_statistic.h"
65 #include "catalog/pg_tablespace.h"
66 #include "catalog/pg_transform.h"
67 #include "catalog/pg_ts_config.h"
69 #include "catalog/pg_ts_dict.h"
70 #include "catalog/pg_ts_parser.h"
71 #include "catalog/pg_ts_template.h"
72 #include "catalog/pg_type.h"
74 #include "utils/rel.h"
75 #include "utils/catcache.h"
76 #include "utils/syscache.h"
77 
78 
79 /*---------------------------------------------------------------------------
80 
81  Adding system caches:
82 
83  Add your new cache to the list in include/utils/syscache.h.
84  Keep the list sorted alphabetically.
85 
86  Add your entry to the cacheinfo[] array below. All cache lists are
87  alphabetical, so add it in the proper place. Specify the relation OID,
88  index OID, number of keys, key attribute numbers, and initial number of
89  hash buckets.
90 
91  The number of hash buckets must be a power of 2. It's reasonable to
92  set this to the number of entries that might be in the particular cache
93  in a medium-size database.
94 
95  There must be a unique index underlying each syscache (ie, an index
96  whose key is the same as that of the cache). If there is not one
97  already, add definitions for it to include/catalog/indexing.h: you need
98  to add a DECLARE_UNIQUE_INDEX macro and a #define for the index OID.
99  (Adding an index requires a catversion.h update, while simply
100  adding/deleting caches only requires a recompile.)
101 
102  Finally, any place your relation gets heap_insert() or
103  heap_update() calls, make sure there is a CatalogUpdateIndexes() or
104  similar call. The heap_* calls do not update indexes.
105 
106  bjm 1999/11/22
107 
108 *---------------------------------------------------------------------------
109 */
110 
111 /*
112  * struct cachedesc: information defining a single syscache
113  */
114 struct cachedesc
115 {
116  Oid reloid; /* OID of the relation being cached */
117  Oid indoid; /* OID of index relation for this cache */
118  int nkeys; /* # of keys needed for cache lookup */
119  int key[4]; /* attribute numbers of key attrs */
120  int nbuckets; /* number of hash buckets for this cache */
121 };
122 
123 static const struct cachedesc cacheinfo[] = {
124  {AggregateRelationId, /* AGGFNOID */
126  1,
127  {
129  0,
130  0,
131  0
132  },
133  16
134  },
135  {AccessMethodRelationId, /* AMNAME */
137  1,
138  {
140  0,
141  0,
142  0
143  },
144  4
145  },
146  {AccessMethodRelationId, /* AMOID */
147  AmOidIndexId,
148  1,
149  {
151  0,
152  0,
153  0
154  },
155  4
156  },
157  {AccessMethodOperatorRelationId, /* AMOPOPID */
159  3,
160  {
164  0
165  },
166  64
167  },
168  {AccessMethodOperatorRelationId, /* AMOPSTRATEGY */
170  4,
171  {
176  },
177  64
178  },
179  {AccessMethodProcedureRelationId, /* AMPROCNUM */
181  4,
182  {
187  },
188  16
189  },
190  {AttributeRelationId, /* ATTNAME */
192  2,
193  {
196  0,
197  0
198  },
199  32
200  },
201  {AttributeRelationId, /* ATTNUM */
203  2,
204  {
207  0,
208  0
209  },
210  128
211  },
212  {AuthMemRelationId, /* AUTHMEMMEMROLE */
214  2,
215  {
218  0,
219  0
220  },
221  8
222  },
223  {AuthMemRelationId, /* AUTHMEMROLEMEM */
225  2,
226  {
229  0,
230  0
231  },
232  8
233  },
234  {AuthIdRelationId, /* AUTHNAME */
236  1,
237  {
239  0,
240  0,
241  0
242  },
243  8
244  },
245  {AuthIdRelationId, /* AUTHOID */
247  1,
248  {
250  0,
251  0,
252  0
253  },
254  8
255  },
256  {
257  CastRelationId, /* CASTSOURCETARGET */
259  2,
260  {
263  0,
264  0
265  },
266  256
267  },
268  {OperatorClassRelationId, /* CLAAMNAMENSP */
270  3,
271  {
275  0
276  },
277  8
278  },
279  {OperatorClassRelationId, /* CLAOID */
281  1,
282  {
284  0,
285  0,
286  0
287  },
288  8
289  },
290  {CollationRelationId, /* COLLNAMEENCNSP */
292  3,
293  {
297  0
298  },
299  8
300  },
301  {CollationRelationId, /* COLLOID */
303  1,
304  {
306  0,
307  0,
308  0
309  },
310  8
311  },
312  {ConversionRelationId, /* CONDEFAULT */
314  4,
315  {
320  },
321  8
322  },
323  {ConversionRelationId, /* CONNAMENSP */
325  2,
326  {
329  0,
330  0
331  },
332  8
333  },
334  {ConstraintRelationId, /* CONSTROID */
336  1,
337  {
339  0,
340  0,
341  0
342  },
343  16
344  },
345  {ConversionRelationId, /* CONVOID */
347  1,
348  {
350  0,
351  0,
352  0
353  },
354  8
355  },
356  {DatabaseRelationId, /* DATABASEOID */
358  1,
359  {
361  0,
362  0,
363  0
364  },
365  4
366  },
367  {DefaultAclRelationId, /* DEFACLROLENSPOBJ */
369  3,
370  {
374  0
375  },
376  8
377  },
378  {EnumRelationId, /* ENUMOID */
380  1,
381  {
383  0,
384  0,
385  0
386  },
387  8
388  },
389  {EnumRelationId, /* ENUMTYPOIDNAME */
391  2,
392  {
395  0,
396  0
397  },
398  8
399  },
400  {EventTriggerRelationId, /* EVENTTRIGGERNAME */
402  1,
403  {
405  0,
406  0,
407  0
408  },
409  8
410  },
411  {EventTriggerRelationId, /* EVENTTRIGGEROID */
413  1,
414  {
416  0,
417  0,
418  0
419  },
420  8
421  },
422  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPERNAME */
424  1,
425  {
427  0,
428  0,
429  0
430  },
431  2
432  },
433  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPEROID */
435  1,
436  {
438  0,
439  0,
440  0
441  },
442  2
443  },
444  {ForeignServerRelationId, /* FOREIGNSERVERNAME */
446  1,
447  {
449  0,
450  0,
451  0
452  },
453  2
454  },
455  {ForeignServerRelationId, /* FOREIGNSERVEROID */
457  1,
458  {
460  0,
461  0,
462  0
463  },
464  2
465  },
466  {ForeignTableRelationId, /* FOREIGNTABLEREL */
468  1,
469  {
471  0,
472  0,
473  0
474  },
475  4
476  },
477  {IndexRelationId, /* INDEXRELID */
479  1,
480  {
482  0,
483  0,
484  0
485  },
486  64
487  },
488  {LanguageRelationId, /* LANGNAME */
490  1,
491  {
493  0,
494  0,
495  0
496  },
497  4
498  },
499  {LanguageRelationId, /* LANGOID */
501  1,
502  {
504  0,
505  0,
506  0
507  },
508  4
509  },
510  {NamespaceRelationId, /* NAMESPACENAME */
512  1,
513  {
515  0,
516  0,
517  0
518  },
519  4
520  },
521  {NamespaceRelationId, /* NAMESPACEOID */
523  1,
524  {
526  0,
527  0,
528  0
529  },
530  16
531  },
532  {OperatorRelationId, /* OPERNAMENSP */
534  4,
535  {
540  },
541  256
542  },
543  {OperatorRelationId, /* OPEROID */
545  1,
546  {
548  0,
549  0,
550  0
551  },
552  32
553  },
554  {OperatorFamilyRelationId, /* OPFAMILYAMNAMENSP */
556  3,
557  {
561  0
562  },
563  8
564  },
565  {OperatorFamilyRelationId, /* OPFAMILYOID */
567  1,
568  {
570  0,
571  0,
572  0
573  },
574  8
575  },
576  {PartitionedRelationId, /* PARTRELID */
578  1,
579  {
581  0,
582  0,
583  0
584  },
585  32
586  },
587  {ProcedureRelationId, /* PROCNAMEARGSNSP */
589  3,
590  {
594  0
595  },
596  128
597  },
598  {ProcedureRelationId, /* PROCOID */
600  1,
601  {
603  0,
604  0,
605  0
606  },
607  128
608  },
609  {RangeRelationId, /* RANGETYPE */
611  1,
612  {
614  0,
615  0,
616  0
617  },
618  4
619  },
620  {RelationRelationId, /* RELNAMENSP */
622  2,
623  {
626  0,
627  0
628  },
629  128
630  },
631  {RelationRelationId, /* RELOID */
633  1,
634  {
636  0,
637  0,
638  0
639  },
640  128
641  },
642  {ReplicationOriginRelationId, /* REPLORIGIDENT */
644  1,
645  {
647  0,
648  0,
649  0
650  },
651  16
652  },
653  {ReplicationOriginRelationId, /* REPLORIGNAME */
655  1,
656  {
658  0,
659  0,
660  0
661  },
662  16
663  },
664  {PublicationRelationId, /* PUBLICATIONOID */
666  1,
667  {
669  0,
670  0,
671  0
672  },
673  8
674  },
675  {PublicationRelationId, /* PUBLICATIONNAME */
677  1,
678  {
680  0,
681  0,
682  0
683  },
684  8
685  },
686  {PublicationRelRelationId, /* PUBLICATIONREL */
688  1,
689  {
691  0,
692  0,
693  0
694  },
695  64
696  },
697  {PublicationRelRelationId, /* PUBLICATIONRELMAP */
699  2,
700  {
703  0,
704  0
705  },
706  64
707  },
708  {RewriteRelationId, /* RULERELNAME */
710  2,
711  {
714  0,
715  0
716  },
717  8
718  },
719  {SequenceRelationId, /* SEQRELID */
721  1,
722  {
724  0,
725  0,
726  0
727  },
728  32
729  },
730  {StatisticRelationId, /* STATRELATTINH */
732  3,
733  {
737  0
738  },
739  128
740  },
741  {SubscriptionRelationId, /* SUBSCRIPTIONOID */
743  1,
744  {
746  0,
747  0,
748  0
749  },
750  4
751  },
752  {SubscriptionRelationId, /* SUBSCRIPTIONNAME */
754  2,
755  {
758  0,
759  0
760  },
761  4
762  },
763  {TableSpaceRelationId, /* TABLESPACEOID */
765  1,
766  {
768  0,
769  0,
770  0,
771  },
772  4
773  },
774  {TransformRelationId, /* TRFOID */
776  1,
777  {
779  0,
780  0,
781  0,
782  },
783  16
784  },
785  {TransformRelationId, /* TRFTYPELANG */
787  2,
788  {
791  0,
792  0,
793  },
794  16
795  },
796  {TSConfigMapRelationId, /* TSCONFIGMAP */
798  3,
799  {
803  0
804  },
805  2
806  },
807  {TSConfigRelationId, /* TSCONFIGNAMENSP */
809  2,
810  {
813  0,
814  0
815  },
816  2
817  },
818  {TSConfigRelationId, /* TSCONFIGOID */
820  1,
821  {
823  0,
824  0,
825  0
826  },
827  2
828  },
829  {TSDictionaryRelationId, /* TSDICTNAMENSP */
831  2,
832  {
835  0,
836  0
837  },
838  2
839  },
840  {TSDictionaryRelationId, /* TSDICTOID */
842  1,
843  {
845  0,
846  0,
847  0
848  },
849  2
850  },
851  {TSParserRelationId, /* TSPARSERNAMENSP */
853  2,
854  {
857  0,
858  0
859  },
860  2
861  },
862  {TSParserRelationId, /* TSPARSEROID */
864  1,
865  {
867  0,
868  0,
869  0
870  },
871  2
872  },
873  {TSTemplateRelationId, /* TSTEMPLATENAMENSP */
875  2,
876  {
879  0,
880  0
881  },
882  2
883  },
884  {TSTemplateRelationId, /* TSTEMPLATEOID */
886  1,
887  {
889  0,
890  0,
891  0
892  },
893  2
894  },
895  {TypeRelationId, /* TYPENAMENSP */
897  2,
898  {
901  0,
902  0
903  },
904  64
905  },
906  {TypeRelationId, /* TYPEOID */
908  1,
909  {
911  0,
912  0,
913  0
914  },
915  64
916  },
917  {UserMappingRelationId, /* USERMAPPINGOID */
919  1,
920  {
922  0,
923  0,
924  0
925  },
926  2
927  },
928  {UserMappingRelationId, /* USERMAPPINGUSERSERVER */
930  2,
931  {
934  0,
935  0
936  },
937  2
938  }
939 };
940 
941 #define SysCacheSize ((int) lengthof(cacheinfo))
942 
944 
945 static bool CacheInitialized = false;
946 
947 /* Sorted array of OIDs of tables that have caches on them */
950 
951 /* Sorted array of OIDs of tables and indexes used by caches */
954 
955 static int oid_compare(const void *a, const void *b);
956 
957 
958 /*
959  * InitCatalogCache - initialize the caches
960  *
961  * Note that no database access is done here; we only allocate memory
962  * and initialize the cache structure. Interrogation of the database
963  * to complete initialization of a cache happens upon first use
964  * of that cache.
965  */
966 void
968 {
969  int cacheId;
970  int i,
971  j;
972 
974 
976 
977  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
978  {
979  SysCache[cacheId] = InitCatCache(cacheId,
980  cacheinfo[cacheId].reloid,
981  cacheinfo[cacheId].indoid,
982  cacheinfo[cacheId].nkeys,
983  cacheinfo[cacheId].key,
984  cacheinfo[cacheId].nbuckets);
985  if (!PointerIsValid(SysCache[cacheId]))
986  elog(ERROR, "could not initialize cache %u (%d)",
987  cacheinfo[cacheId].reloid, cacheId);
988  /* Accumulate data for OID lists, too */
990  cacheinfo[cacheId].reloid;
992  cacheinfo[cacheId].reloid;
994  cacheinfo[cacheId].indoid;
995  /* see comments for RelationInvalidatesSnapshotsOnly */
996  Assert(!RelationInvalidatesSnapshotsOnly(cacheinfo[cacheId].reloid));
997  }
998 
1001 
1002  /* Sort and de-dup OID arrays, so we can use binary search. */
1004  sizeof(Oid), oid_compare);
1005  for (i = 1, j = 0; i < SysCacheRelationOidSize; i++)
1006  {
1009  }
1010  SysCacheRelationOidSize = j + 1;
1011 
1013  sizeof(Oid), oid_compare);
1014  for (i = 1, j = 0; i < SysCacheSupportingRelOidSize; i++)
1015  {
1018  }
1019  SysCacheSupportingRelOidSize = j + 1;
1020 
1021  CacheInitialized = true;
1022 }
1023 
1024 /*
1025  * InitCatalogCachePhase2 - finish initializing the caches
1026  *
1027  * Finish initializing all the caches, including necessary database
1028  * access.
1029  *
1030  * This is *not* essential; normally we allow syscaches to be initialized
1031  * on first use. However, it is useful as a mechanism to preload the
1032  * relcache with entries for the most-commonly-used system catalogs.
1033  * Therefore, we invoke this routine when we need to write a new relcache
1034  * init file.
1035  */
1036 void
1038 {
1039  int cacheId;
1040 
1042 
1043  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
1044  InitCatCachePhase2(SysCache[cacheId], true);
1045 }
1046 
1047 
1048 /*
1049  * SearchSysCache
1050  *
1051  * A layer on top of SearchCatCache that does the initialization and
1052  * key-setting for you.
1053  *
1054  * Returns the cache copy of the tuple if one is found, NULL if not.
1055  * The tuple is the 'cache' copy and must NOT be modified!
1056  *
1057  * When the caller is done using the tuple, call ReleaseSysCache()
1058  * to release the reference count grabbed by SearchSysCache(). If this
1059  * is not done, the tuple will remain locked in cache until end of
1060  * transaction, which is tolerable but not desirable.
1061  *
1062  * CAUTION: The tuple that is returned must NOT be freed by the caller!
1063  */
1064 HeapTuple
1065 SearchSysCache(int cacheId,
1066  Datum key1,
1067  Datum key2,
1068  Datum key3,
1069  Datum key4)
1070 {
1071  if (cacheId < 0 || cacheId >= SysCacheSize ||
1072  !PointerIsValid(SysCache[cacheId]))
1073  elog(ERROR, "invalid cache ID: %d", cacheId);
1074 
1075  return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
1076 }
1077 
1078 /*
1079  * ReleaseSysCache
1080  * Release previously grabbed reference count on a tuple
1081  */
1082 void
1084 {
1085  ReleaseCatCache(tuple);
1086 }
1087 
1088 /*
1089  * SearchSysCacheCopy
1090  *
1091  * A convenience routine that does SearchSysCache and (if successful)
1092  * returns a modifiable copy of the syscache entry. The original
1093  * syscache entry is released before returning. The caller should
1094  * heap_freetuple() the result when done with it.
1095  */
1096 HeapTuple
1098  Datum key1,
1099  Datum key2,
1100  Datum key3,
1101  Datum key4)
1102 {
1103  HeapTuple tuple,
1104  newtuple;
1105 
1106  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1107  if (!HeapTupleIsValid(tuple))
1108  return tuple;
1109  newtuple = heap_copytuple(tuple);
1110  ReleaseSysCache(tuple);
1111  return newtuple;
1112 }
1113 
1114 /*
1115  * SearchSysCacheExists
1116  *
1117  * A convenience routine that just probes to see if a tuple can be found.
1118  * No lock is retained on the syscache entry.
1119  */
1120 bool
1122  Datum key1,
1123  Datum key2,
1124  Datum key3,
1125  Datum key4)
1126 {
1127  HeapTuple tuple;
1128 
1129  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1130  if (!HeapTupleIsValid(tuple))
1131  return false;
1132  ReleaseSysCache(tuple);
1133  return true;
1134 }
1135 
1136 /*
1137  * GetSysCacheOid
1138  *
1139  * A convenience routine that does SearchSysCache and returns the OID
1140  * of the found tuple, or InvalidOid if no tuple could be found.
1141  * No lock is retained on the syscache entry.
1142  */
1143 Oid
1144 GetSysCacheOid(int cacheId,
1145  Datum key1,
1146  Datum key2,
1147  Datum key3,
1148  Datum key4)
1149 {
1150  HeapTuple tuple;
1151  Oid result;
1152 
1153  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1154  if (!HeapTupleIsValid(tuple))
1155  return InvalidOid;
1156  result = HeapTupleGetOid(tuple);
1157  ReleaseSysCache(tuple);
1158  return result;
1159 }
1160 
1161 
1162 /*
1163  * SearchSysCacheAttName
1164  *
1165  * This routine is equivalent to SearchSysCache on the ATTNAME cache,
1166  * except that it will return NULL if the found attribute is marked
1167  * attisdropped. This is convenient for callers that want to act as
1168  * though dropped attributes don't exist.
1169  */
1170 HeapTuple
1171 SearchSysCacheAttName(Oid relid, const char *attname)
1172 {
1173  HeapTuple tuple;
1174 
1175  tuple = SearchSysCache2(ATTNAME,
1176  ObjectIdGetDatum(relid),
1177  CStringGetDatum(attname));
1178  if (!HeapTupleIsValid(tuple))
1179  return NULL;
1180  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
1181  {
1182  ReleaseSysCache(tuple);
1183  return NULL;
1184  }
1185  return tuple;
1186 }
1187 
1188 /*
1189  * SearchSysCacheCopyAttName
1190  *
1191  * As above, an attisdropped-aware version of SearchSysCacheCopy.
1192  */
1193 HeapTuple
1194 SearchSysCacheCopyAttName(Oid relid, const char *attname)
1195 {
1196  HeapTuple tuple,
1197  newtuple;
1198 
1199  tuple = SearchSysCacheAttName(relid, attname);
1200  if (!HeapTupleIsValid(tuple))
1201  return tuple;
1202  newtuple = heap_copytuple(tuple);
1203  ReleaseSysCache(tuple);
1204  return newtuple;
1205 }
1206 
1207 /*
1208  * SearchSysCacheExistsAttName
1209  *
1210  * As above, an attisdropped-aware version of SearchSysCacheExists.
1211  */
1212 bool
1213 SearchSysCacheExistsAttName(Oid relid, const char *attname)
1214 {
1215  HeapTuple tuple;
1216 
1217  tuple = SearchSysCacheAttName(relid, attname);
1218  if (!HeapTupleIsValid(tuple))
1219  return false;
1220  ReleaseSysCache(tuple);
1221  return true;
1222 }
1223 
1224 
1225 /*
1226  * SysCacheGetAttr
1227  *
1228  * Given a tuple previously fetched by SearchSysCache(),
1229  * extract a specific attribute.
1230  *
1231  * This is equivalent to using heap_getattr() on a tuple fetched
1232  * from a non-cached relation. Usually, this is only used for attributes
1233  * that could be NULL or variable length; the fixed-size attributes in
1234  * a system table are accessed just by mapping the tuple onto the C struct
1235  * declarations from include/catalog/.
1236  *
1237  * As with heap_getattr(), if the attribute is of a pass-by-reference type
1238  * then a pointer into the tuple data area is returned --- the caller must
1239  * not modify or pfree the datum!
1240  *
1241  * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
1242  * a different cache for the same catalog the tuple was fetched from.
1243  */
1244 Datum
1245 SysCacheGetAttr(int cacheId, HeapTuple tup,
1246  AttrNumber attributeNumber,
1247  bool *isNull)
1248 {
1249  /*
1250  * We just need to get the TupleDesc out of the cache entry, and then we
1251  * can apply heap_getattr(). Normally the cache control data is already
1252  * valid (because the caller recently fetched the tuple via this same
1253  * cache), but there are cases where we have to initialize the cache here.
1254  */
1255  if (cacheId < 0 || cacheId >= SysCacheSize ||
1256  !PointerIsValid(SysCache[cacheId]))
1257  elog(ERROR, "invalid cache ID: %d", cacheId);
1258  if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
1259  {
1260  InitCatCachePhase2(SysCache[cacheId], false);
1261  Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
1262  }
1263 
1264  return heap_getattr(tup, attributeNumber,
1265  SysCache[cacheId]->cc_tupdesc,
1266  isNull);
1267 }
1268 
1269 /*
1270  * GetSysCacheHashValue
1271  *
1272  * Get the hash value that would be used for a tuple in the specified cache
1273  * with the given search keys.
1274  *
1275  * The reason for exposing this as part of the API is that the hash value is
1276  * exposed in cache invalidation operations, so there are places outside the
1277  * catcache code that need to be able to compute the hash values.
1278  */
1279 uint32
1281  Datum key1,
1282  Datum key2,
1283  Datum key3,
1284  Datum key4)
1285 {
1286  if (cacheId < 0 || cacheId >= SysCacheSize ||
1287  !PointerIsValid(SysCache[cacheId]))
1288  elog(ERROR, "invalid cache ID: %d", cacheId);
1289 
1290  return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
1291 }
1292 
1293 /*
1294  * List-search interface
1295  */
1296 struct catclist *
1297 SearchSysCacheList(int cacheId, int nkeys,
1298  Datum key1, Datum key2, Datum key3, Datum key4)
1299 {
1300  if (cacheId < 0 || cacheId >= SysCacheSize ||
1301  !PointerIsValid(SysCache[cacheId]))
1302  elog(ERROR, "invalid cache ID: %d", cacheId);
1303 
1304  return SearchCatCacheList(SysCache[cacheId], nkeys,
1305  key1, key2, key3, key4);
1306 }
1307 
1308 /*
1309  * Certain relations that do not have system caches send snapshot invalidation
1310  * messages in lieu of catcache messages. This is for the benefit of
1311  * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
1312  * for scanning one of those catalogs, rather than taking a new one, if no
1313  * invalidation has been received.
1314  *
1315  * Relations that have syscaches need not (and must not) be listed here. The
1316  * catcache invalidation messages will also flush the snapshot. If you add a
1317  * syscache for one of these relations, remove it from this list.
1318  */
1319 bool
1321 {
1322  switch (relid)
1323  {
1325  case DependRelationId:
1327  case DescriptionRelationId:
1329  case SecLabelRelationId:
1331  return true;
1332  default:
1333  break;
1334  }
1335 
1336  return false;
1337 }
1338 
1339 /*
1340  * Test whether a relation has a system cache.
1341  */
1342 bool
1344 {
1345  int low = 0,
1346  high = SysCacheRelationOidSize - 1;
1347 
1348  while (low <= high)
1349  {
1350  int middle = low + (high - low) / 2;
1351 
1352  if (SysCacheRelationOid[middle] == relid)
1353  return true;
1354  if (SysCacheRelationOid[middle] < relid)
1355  low = middle + 1;
1356  else
1357  high = middle - 1;
1358  }
1359 
1360  return false;
1361 }
1362 
1363 /*
1364  * Test whether a relation supports a system cache, ie it is either a
1365  * cached table or the index used for a cache.
1366  */
1367 bool
1369 {
1370  int low = 0,
1371  high = SysCacheSupportingRelOidSize - 1;
1372 
1373  while (low <= high)
1374  {
1375  int middle = low + (high - low) / 2;
1376 
1377  if (SysCacheSupportingRelOid[middle] == relid)
1378  return true;
1379  if (SysCacheSupportingRelOid[middle] < relid)
1380  low = middle + 1;
1381  else
1382  high = middle - 1;
1383  }
1384 
1385  return false;
1386 }
1387 
1388 
1389 /*
1390  * OID comparator for pg_qsort
1391  */
1392 static int
1393 oid_compare(const void *a, const void *b)
1394 {
1395  Oid oa = *((const Oid *) a);
1396  Oid ob = *((const Oid *) b);
1397 
1398  if (oa == ob)
1399  return 0;
1400  return (oa > ob) ? 1 : -1;
1401 }
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1065
#define ConstraintOidIndexId
Definition: indexing.h:130
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_event_trigger_evtname
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define NamespaceOidIndexId
Definition: indexing.h:188
#define ProcedureOidIndexId
Definition: indexing.h:209
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:192
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define CollationOidIndexId
Definition: indexing.h:121
#define Anum_pg_opclass_opcmethod
Definition: pg_opclass.h:75
static bool CacheInitialized
Definition: syscache.c:945
#define Anum_pg_operator_oprleft
Definition: pg_operator.h:71
bool RelationHasSysCache(Oid relid)
Definition: syscache.c:1343
#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:164
#define Anum_pg_opfamily_opfmethod
Definition: pg_opfamily.h:51
#define Anum_pg_replication_origin_roident
static int SysCacheSupportingRelOidSize
Definition: syscache.c:953
#define PublicationRelMapIndexId
Definition: indexing.h:344
#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:1297
#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:138
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define Anum_pg_user_mapping_umserver
#define RewriteRelRulenameIndexId
Definition: indexing.h:216
static Oid SysCacheSupportingRelOid[SysCacheSize *2]
Definition: syscache.c:952
#define ForeignServerNameIndexId
Definition: indexing.h:287
#define Anum_pg_type_typname
Definition: pg_type.h:240
#define ProcedureRelationId
Definition: pg_proc.h:33
#define PublicationNameIndexId
Definition: indexing.h:338
#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:109
#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 SequenceRelationId
Definition: pg_sequence.h:6
#define Anum_pg_statistic_staattnum
Definition: pg_statistic.h:137
#define PublicationRelationId
#define ClassNameNspIndexId
Definition: indexing.h:114
static int SysCacheRelationOidSize
Definition: syscache.c:949
#define Anum_pg_amop_amoprighttype
Definition: pg_amop.h:86
#define AuthIdOidIndexId
Definition: indexing.h:99
#define lengthof(array)
Definition: c.h:558
#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:157
Oid GetSysCacheOid(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1144
#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:1213
#define OpclassAmNameNspIndexId
Definition: indexing.h:191
#define DefaultAclRelationId
#define AccessMethodOperatorIndexId
Definition: indexing.h:77
#define Anum_pg_class_relnamespace
Definition: pg_class.h:104
short nkeys
Definition: catcache.h:151
#define AggregateFnoidIndexId
Definition: indexing.h:67
#define AccessMethodOperatorRelationId
Definition: pg_amop.h:54
#define Anum_pg_partitioned_table_partrelid
static const struct cachedesc cacheinfo[]
Definition: syscache.c:123
bool SearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1121
#define AggregateRelationId
Definition: pg_aggregate.h:53
#define AmNameIndexId
Definition: indexing.h:70
#define TSDictionaryOidIndexId
Definition: indexing.h:262
#define PublicationRelRelationId
#define AuthIdRelationId
Definition: pg_authid.h:42
Oid reloid
Definition: syscache.c:116
#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:282
#define LanguageNameIndexId
Definition: indexing.h:175
#define Anum_pg_replication_origin_roname
#define TSConfigMapRelationId
#define ReplicationOriginIdentIndex
Definition: indexing.h:326
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define PublicationObjectIndexId
Definition: indexing.h:335
#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
#define Anum_pg_subscription_subname
#define SequenceRelidIndexId
Definition: indexing.h:219
HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname)
Definition: syscache.c:1194
#define Anum_pg_amproc_amprocfamily
Definition: pg_amproc.h:66
#define TablespaceOidIndexId
Definition: indexing.h:230
#define SubscriptionRelationId
#define PartitionedRelidIndexId
Definition: indexing.h:332
#define Anum_pg_ts_config_cfgnamespace
Definition: pg_ts_config.h:49
#define Anum_pg_class_relname
Definition: pg_class.h:103
#define ConversionDefaultIndexId
Definition: indexing.h:133
#define AccessMethodRelationId
Definition: pg_am.h:32
#define SysCacheSize
Definition: syscache.c:941
#define PartitionedRelationId
#define Anum_pg_publication_rel_prpubid
#define Anum_pg_publication_rel_prrelid
int nbuckets
Definition: syscache.c:120
#define CStringGetDatum(X)
Definition: postgres.h:586
#define TransformOidIndexId
Definition: indexing.h:235
#define Anum_pg_amproc_amprocnum
Definition: pg_amproc.h:69
#define DatabaseOidIndexId
Definition: indexing.h:142
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:198
#define SharedDescriptionRelationId
#define ClassOidIndexId
Definition: indexing.h:112
#define Anum_pg_ts_template_tmplnamespace
#define Anum_pg_statistic_starelid
Definition: pg_statistic.h:136
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Definition: catcache.c:719
#define Anum_pg_amproc_amprocrighttype
Definition: pg_amproc.h:68
Oid indoid
Definition: syscache.c:117
#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:254
#define Anum_pg_range_rngtypid
Definition: pg_range.h:56
#define AuthMemRoleMemIndexId
Definition: indexing.h:102
#define Anum_pg_subscription_subdbid
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define SharedSecLabelRelationId
Definition: pg_shseclabel.h:21
int nkeys
Definition: syscache.c:118
#define AccessMethodProcedureIndexId
Definition: indexing.h:82
#define Anum_pg_foreign_table_ftrelid
static CatCache * SysCache[SysCacheSize]
Definition: syscache.c:943
#define OpfamilyAmNameNspIndexId
Definition: indexing.h:201
#define OperatorOidIndexId
Definition: indexing.h:196
#define Anum_pg_auth_members_roleid
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#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:1245
static Oid SysCacheRelationOid[SysCacheSize]
Definition: syscache.c:948
#define Anum_pg_amop_amoppurpose
Definition: pg_amop.h:88
#define EnumOidIndexId
Definition: indexing.h:155
#define TSParserRelationId
Definition: pg_ts_parser.h:31
#define AttributeRelidNameIndexId
Definition: indexing.h:92
#define CollationRelationId
Definition: pg_collation.h:30
#define TSDictionaryNameNspIndexId
Definition: indexing.h:260
#define TypeNameNspIndexId
Definition: indexing.h:277
#define OpclassOidIndexId
Definition: indexing.h:193
#define InvalidOid
Definition: postgres_ext.h:36
void ReleaseCatCache(HeapTuple tuple)
Definition: catcache.c:1317
#define RewriteRelationId
Definition: pg_rewrite.h:32
uint32 GetSysCacheHashValue(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1280
#define TSTemplateNameNspIndexId
Definition: indexing.h:270
#define Anum_pg_operator_oprname
Definition: pg_operator.h:65
#define ProcedureNameArgsNspIndexId
Definition: indexing.h:211
#define NamespaceNameIndexId
Definition: indexing.h:186
#define ForeignServerRelationId
#define LanguageOidIndexId
Definition: indexing.h:177
#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:671
#define Anum_pg_proc_pronamespace
Definition: pg_proc.h:91
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:1320
#define ForeignDataWrapperOidIndexId
Definition: indexing.h:280
#define EventTriggerRelationId
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:227
#define AuthMemMemRoleIndexId
Definition: indexing.h:104
#define EventTriggerOidIndexId
Definition: indexing.h:249
int key[4]
Definition: syscache.c:119
#define UserMappingOidIndexId
Definition: indexing.h:290
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:137
#define UserMappingUserServerIndexId
Definition: indexing.h:292
#define ForeignDataWrapperRelationId
#define Anum_pg_ts_parser_prsnamespace
Definition: pg_ts_parser.h:52
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1171
#define TSParserOidIndexId
Definition: indexing.h:267
#define Anum_pg_conversion_conname
Definition: pg_conversion.h:64
#define CollationNameEncNspIndexId
Definition: indexing.h:119
#define RangeTypidIndexId
Definition: indexing.h:317
#define EventTriggerNameIndexId
Definition: indexing.h:247
#define DescriptionRelationId
#define Anum_pg_default_acl_defaclnamespace
#define TableSpaceRelationId
Definition: pg_tablespace.h:29
#define DefaultAclRoleNspObjIndexId
Definition: indexing.h:298
#define Anum_pg_transform_trftype
Definition: pg_transform.h:42
#define PublicationRelObjectIndexId
Definition: indexing.h:341
#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:1097
#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:967
#define Anum_pg_default_acl_defaclobjtype
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1103
#define SubscriptionNameIndexId
Definition: indexing.h:350
static int oid_compare(const void *a, const void *b)
Definition: syscache.c:1393
#define Anum_pg_am_amname
Definition: pg_am.h:53
#define ReplicationOriginRelationId
#define Anum_pg_amop_amopopr
Definition: pg_amop.h:89
#define Anum_pg_sequence_seqrelid
Definition: pg_sequence.h:23
#define UserMappingRelationId
#define DbRoleSettingRelationId
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1389
#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:75
#define TSConfigMapIndexId
Definition: indexing.h:257
#define ConversionNameNspIndexId
Definition: indexing.h:135
#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:72
#define ReplicationOriginNameIndex
Definition: indexing.h:329
#define elog
Definition: elog.h:219
void InitCatCachePhase2(CatCache *cache, bool touch_index)
Definition: catcache.c:988
#define Anum_pg_publication_pubname
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
bool RelationSupportsSysCache(Oid relid)
Definition: syscache.c:1368
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1349
#define TSTemplateOidIndexId
Definition: indexing.h:272
#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:97
void InitCatalogCachePhase2(void)
Definition: syscache.c:1037
#define AccessMethodProcedureRelationId
Definition: pg_amproc.h:43
#define PointerIsValid(pointer)
Definition: c.h:522
#define ConversionRelationId
Definition: pg_conversion.h:38
#define ForeignTableRelidIndexId
Definition: indexing.h:295
#define TSParserNameNspIndexId
Definition: indexing.h:265
int16 AttrNumber
Definition: attnum.h:21
#define TSConfigNameNspIndexId
Definition: indexing.h:252
#define TransformTypeLangIndexId
Definition: indexing.h:237
#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:275
#define ForeignServerOidIndexId
Definition: indexing.h:285
#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:203
#define Anum_pg_amop_amopstrategy
Definition: pg_amop.h:87
#define SubscriptionObjectIndexId
Definition: indexing.h:347
#define Anum_pg_auth_members_member
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151