PostgreSQL Source Code  git master
syscache.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * syscache.c
4  * System cache management routines
5  *
6  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/utils/cache/syscache.c
12  *
13  * NOTES
14  * These routines allow the parser/planner/executor to perform
15  * rapid lookups on the contents of the system catalogs.
16  *
17  * see utils/syscache.h for a list of the cache IDs
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include "access/htup_details.h"
24 #include "access/sysattr.h"
25 #include "catalog/pg_aggregate.h"
26 #include "catalog/pg_am.h"
27 #include "catalog/pg_amop.h"
28 #include "catalog/pg_amproc.h"
30 #include "catalog/pg_authid.h"
31 #include "catalog/pg_cast.h"
32 #include "catalog/pg_collation.h"
33 #include "catalog/pg_constraint.h"
34 #include "catalog/pg_conversion.h"
35 #include "catalog/pg_database.h"
37 #include "catalog/pg_default_acl.h"
38 #include "catalog/pg_depend.h"
39 #include "catalog/pg_description.h"
40 #include "catalog/pg_enum.h"
45 #include "catalog/pg_language.h"
46 #include "catalog/pg_namespace.h"
47 #include "catalog/pg_opclass.h"
48 #include "catalog/pg_operator.h"
49 #include "catalog/pg_opfamily.h"
51 #include "catalog/pg_proc.h"
52 #include "catalog/pg_publication.h"
55 #include "catalog/pg_range.h"
57 #include "catalog/pg_rewrite.h"
58 #include "catalog/pg_seclabel.h"
59 #include "catalog/pg_sequence.h"
60 #include "catalog/pg_shdepend.h"
62 #include "catalog/pg_shseclabel.h"
63 #include "catalog/pg_statistic.h"
68 #include "catalog/pg_tablespace.h"
69 #include "catalog/pg_transform.h"
70 #include "catalog/pg_ts_config.h"
72 #include "catalog/pg_ts_dict.h"
73 #include "catalog/pg_ts_parser.h"
74 #include "catalog/pg_ts_template.h"
75 #include "catalog/pg_type.h"
77 #include "lib/qunique.h"
78 #include "utils/catcache.h"
79 #include "utils/rel.h"
80 #include "utils/syscache.h"
81 
82 /*---------------------------------------------------------------------------
83 
84  Adding system caches:
85 
86  Add your new cache to the list in include/utils/syscache.h.
87  Keep the list sorted alphabetically.
88 
89  Add your entry to the cacheinfo[] array below. All cache lists are
90  alphabetical, so add it in the proper place. Specify the relation OID,
91  index OID, number of keys, key attribute numbers, and initial number of
92  hash buckets.
93 
94  The number of hash buckets must be a power of 2. It's reasonable to
95  set this to the number of entries that might be in the particular cache
96  in a medium-size database.
97 
98  There must be a unique index underlying each syscache (ie, an index
99  whose key is the same as that of the cache). If there is not one
100  already, add the definition for it to include/catalog/pg_*.h using
101  DECLARE_UNIQUE_INDEX.
102  (Adding an index requires a catversion.h update, while simply
103  adding/deleting caches only requires a recompile.)
104 
105  Finally, any place your relation gets heap_insert() or
106  heap_update() calls, use CatalogTupleInsert() or CatalogTupleUpdate()
107  instead, which also update indexes. The heap_* calls do not do that.
108 
109 *---------------------------------------------------------------------------
110 */
111 
112 /*
113  * struct cachedesc: information defining a single syscache
114  */
115 struct cachedesc
116 {
117  Oid reloid; /* OID of the relation being cached */
118  Oid indoid; /* OID of index relation for this cache */
119  int nkeys; /* # of keys needed for cache lookup */
120  int key[4]; /* attribute numbers of key attrs */
121  int nbuckets; /* number of hash buckets for this cache */
122 };
123 
124 static const struct cachedesc cacheinfo[] = {
125  {AggregateRelationId, /* AGGFNOID */
126  AggregateFnoidIndexId,
127  1,
128  {
129  Anum_pg_aggregate_aggfnoid,
130  0,
131  0,
132  0
133  },
134  16
135  },
136  {AccessMethodRelationId, /* AMNAME */
137  AmNameIndexId,
138  1,
139  {
140  Anum_pg_am_amname,
141  0,
142  0,
143  0
144  },
145  4
146  },
147  {AccessMethodRelationId, /* AMOID */
148  AmOidIndexId,
149  1,
150  {
151  Anum_pg_am_oid,
152  0,
153  0,
154  0
155  },
156  4
157  },
158  {AccessMethodOperatorRelationId, /* AMOPOPID */
159  AccessMethodOperatorIndexId,
160  3,
161  {
162  Anum_pg_amop_amopopr,
163  Anum_pg_amop_amoppurpose,
164  Anum_pg_amop_amopfamily,
165  0
166  },
167  64
168  },
169  {AccessMethodOperatorRelationId, /* AMOPSTRATEGY */
170  AccessMethodStrategyIndexId,
171  4,
172  {
173  Anum_pg_amop_amopfamily,
174  Anum_pg_amop_amoplefttype,
175  Anum_pg_amop_amoprighttype,
176  Anum_pg_amop_amopstrategy
177  },
178  64
179  },
180  {AccessMethodProcedureRelationId, /* AMPROCNUM */
181  AccessMethodProcedureIndexId,
182  4,
183  {
184  Anum_pg_amproc_amprocfamily,
185  Anum_pg_amproc_amproclefttype,
186  Anum_pg_amproc_amprocrighttype,
187  Anum_pg_amproc_amprocnum
188  },
189  16
190  },
191  {AttributeRelationId, /* ATTNAME */
192  AttributeRelidNameIndexId,
193  2,
194  {
195  Anum_pg_attribute_attrelid,
196  Anum_pg_attribute_attname,
197  0,
198  0
199  },
200  32
201  },
202  {AttributeRelationId, /* ATTNUM */
203  AttributeRelidNumIndexId,
204  2,
205  {
206  Anum_pg_attribute_attrelid,
207  Anum_pg_attribute_attnum,
208  0,
209  0
210  },
211  128
212  },
213  {AuthMemRelationId, /* AUTHMEMMEMROLE */
214  AuthMemMemRoleIndexId,
215  2,
216  {
217  Anum_pg_auth_members_member,
218  Anum_pg_auth_members_roleid,
219  0,
220  0
221  },
222  8
223  },
224  {AuthMemRelationId, /* AUTHMEMROLEMEM */
225  AuthMemRoleMemIndexId,
226  2,
227  {
228  Anum_pg_auth_members_roleid,
229  Anum_pg_auth_members_member,
230  0,
231  0
232  },
233  8
234  },
235  {AuthIdRelationId, /* AUTHNAME */
236  AuthIdRolnameIndexId,
237  1,
238  {
239  Anum_pg_authid_rolname,
240  0,
241  0,
242  0
243  },
244  8
245  },
246  {AuthIdRelationId, /* AUTHOID */
247  AuthIdOidIndexId,
248  1,
249  {
250  Anum_pg_authid_oid,
251  0,
252  0,
253  0
254  },
255  8
256  },
257  {
258  CastRelationId, /* CASTSOURCETARGET */
259  CastSourceTargetIndexId,
260  2,
261  {
262  Anum_pg_cast_castsource,
263  Anum_pg_cast_casttarget,
264  0,
265  0
266  },
267  256
268  },
269  {OperatorClassRelationId, /* CLAAMNAMENSP */
270  OpclassAmNameNspIndexId,
271  3,
272  {
273  Anum_pg_opclass_opcmethod,
274  Anum_pg_opclass_opcname,
275  Anum_pg_opclass_opcnamespace,
276  0
277  },
278  8
279  },
280  {OperatorClassRelationId, /* CLAOID */
281  OpclassOidIndexId,
282  1,
283  {
284  Anum_pg_opclass_oid,
285  0,
286  0,
287  0
288  },
289  8
290  },
291  {CollationRelationId, /* COLLNAMEENCNSP */
292  CollationNameEncNspIndexId,
293  3,
294  {
295  Anum_pg_collation_collname,
296  Anum_pg_collation_collencoding,
297  Anum_pg_collation_collnamespace,
298  0
299  },
300  8
301  },
302  {CollationRelationId, /* COLLOID */
303  CollationOidIndexId,
304  1,
305  {
306  Anum_pg_collation_oid,
307  0,
308  0,
309  0
310  },
311  8
312  },
313  {ConversionRelationId, /* CONDEFAULT */
314  ConversionDefaultIndexId,
315  4,
316  {
317  Anum_pg_conversion_connamespace,
318  Anum_pg_conversion_conforencoding,
319  Anum_pg_conversion_contoencoding,
320  Anum_pg_conversion_oid
321  },
322  8
323  },
324  {ConversionRelationId, /* CONNAMENSP */
325  ConversionNameNspIndexId,
326  2,
327  {
328  Anum_pg_conversion_conname,
329  Anum_pg_conversion_connamespace,
330  0,
331  0
332  },
333  8
334  },
335  {ConstraintRelationId, /* CONSTROID */
336  ConstraintOidIndexId,
337  1,
338  {
339  Anum_pg_constraint_oid,
340  0,
341  0,
342  0
343  },
344  16
345  },
346  {ConversionRelationId, /* CONVOID */
347  ConversionOidIndexId,
348  1,
349  {
350  Anum_pg_conversion_oid,
351  0,
352  0,
353  0
354  },
355  8
356  },
357  {DatabaseRelationId, /* DATABASEOID */
358  DatabaseOidIndexId,
359  1,
360  {
361  Anum_pg_database_oid,
362  0,
363  0,
364  0
365  },
366  4
367  },
368  {DefaultAclRelationId, /* DEFACLROLENSPOBJ */
369  DefaultAclRoleNspObjIndexId,
370  3,
371  {
372  Anum_pg_default_acl_defaclrole,
373  Anum_pg_default_acl_defaclnamespace,
374  Anum_pg_default_acl_defaclobjtype,
375  0
376  },
377  8
378  },
379  {EnumRelationId, /* ENUMOID */
380  EnumOidIndexId,
381  1,
382  {
383  Anum_pg_enum_oid,
384  0,
385  0,
386  0
387  },
388  8
389  },
390  {EnumRelationId, /* ENUMTYPOIDNAME */
391  EnumTypIdLabelIndexId,
392  2,
393  {
394  Anum_pg_enum_enumtypid,
395  Anum_pg_enum_enumlabel,
396  0,
397  0
398  },
399  8
400  },
401  {EventTriggerRelationId, /* EVENTTRIGGERNAME */
402  EventTriggerNameIndexId,
403  1,
404  {
405  Anum_pg_event_trigger_evtname,
406  0,
407  0,
408  0
409  },
410  8
411  },
412  {EventTriggerRelationId, /* EVENTTRIGGEROID */
413  EventTriggerOidIndexId,
414  1,
415  {
416  Anum_pg_event_trigger_oid,
417  0,
418  0,
419  0
420  },
421  8
422  },
423  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPERNAME */
424  ForeignDataWrapperNameIndexId,
425  1,
426  {
427  Anum_pg_foreign_data_wrapper_fdwname,
428  0,
429  0,
430  0
431  },
432  2
433  },
434  {ForeignDataWrapperRelationId, /* FOREIGNDATAWRAPPEROID */
435  ForeignDataWrapperOidIndexId,
436  1,
437  {
438  Anum_pg_foreign_data_wrapper_oid,
439  0,
440  0,
441  0
442  },
443  2
444  },
445  {ForeignServerRelationId, /* FOREIGNSERVERNAME */
446  ForeignServerNameIndexId,
447  1,
448  {
449  Anum_pg_foreign_server_srvname,
450  0,
451  0,
452  0
453  },
454  2
455  },
456  {ForeignServerRelationId, /* FOREIGNSERVEROID */
457  ForeignServerOidIndexId,
458  1,
459  {
460  Anum_pg_foreign_server_oid,
461  0,
462  0,
463  0
464  },
465  2
466  },
467  {ForeignTableRelationId, /* FOREIGNTABLEREL */
468  ForeignTableRelidIndexId,
469  1,
470  {
471  Anum_pg_foreign_table_ftrelid,
472  0,
473  0,
474  0
475  },
476  4
477  },
478  {IndexRelationId, /* INDEXRELID */
479  IndexRelidIndexId,
480  1,
481  {
482  Anum_pg_index_indexrelid,
483  0,
484  0,
485  0
486  },
487  64
488  },
489  {LanguageRelationId, /* LANGNAME */
490  LanguageNameIndexId,
491  1,
492  {
493  Anum_pg_language_lanname,
494  0,
495  0,
496  0
497  },
498  4
499  },
500  {LanguageRelationId, /* LANGOID */
501  LanguageOidIndexId,
502  1,
503  {
504  Anum_pg_language_oid,
505  0,
506  0,
507  0
508  },
509  4
510  },
511  {NamespaceRelationId, /* NAMESPACENAME */
512  NamespaceNameIndexId,
513  1,
514  {
515  Anum_pg_namespace_nspname,
516  0,
517  0,
518  0
519  },
520  4
521  },
522  {NamespaceRelationId, /* NAMESPACEOID */
523  NamespaceOidIndexId,
524  1,
525  {
526  Anum_pg_namespace_oid,
527  0,
528  0,
529  0
530  },
531  16
532  },
533  {OperatorRelationId, /* OPERNAMENSP */
534  OperatorNameNspIndexId,
535  4,
536  {
537  Anum_pg_operator_oprname,
538  Anum_pg_operator_oprleft,
539  Anum_pg_operator_oprright,
540  Anum_pg_operator_oprnamespace
541  },
542  256
543  },
544  {OperatorRelationId, /* OPEROID */
545  OperatorOidIndexId,
546  1,
547  {
548  Anum_pg_operator_oid,
549  0,
550  0,
551  0
552  },
553  32
554  },
555  {OperatorFamilyRelationId, /* OPFAMILYAMNAMENSP */
556  OpfamilyAmNameNspIndexId,
557  3,
558  {
559  Anum_pg_opfamily_opfmethod,
560  Anum_pg_opfamily_opfname,
561  Anum_pg_opfamily_opfnamespace,
562  0
563  },
564  8
565  },
566  {OperatorFamilyRelationId, /* OPFAMILYOID */
567  OpfamilyOidIndexId,
568  1,
569  {
570  Anum_pg_opfamily_oid,
571  0,
572  0,
573  0
574  },
575  8
576  },
577  {PartitionedRelationId, /* PARTRELID */
578  PartitionedRelidIndexId,
579  1,
580  {
581  Anum_pg_partitioned_table_partrelid,
582  0,
583  0,
584  0
585  },
586  32
587  },
588  {ProcedureRelationId, /* PROCNAMEARGSNSP */
589  ProcedureNameArgsNspIndexId,
590  3,
591  {
592  Anum_pg_proc_proname,
593  Anum_pg_proc_proargtypes,
594  Anum_pg_proc_pronamespace,
595  0
596  },
597  128
598  },
599  {ProcedureRelationId, /* PROCOID */
600  ProcedureOidIndexId,
601  1,
602  {
603  Anum_pg_proc_oid,
604  0,
605  0,
606  0
607  },
608  128
609  },
610  {PublicationRelationId, /* PUBLICATIONNAME */
611  PublicationNameIndexId,
612  1,
613  {
614  Anum_pg_publication_pubname,
615  0,
616  0,
617  0
618  },
619  8
620  },
621  {PublicationNamespaceRelationId, /* PUBLICATIONNAMESPACE */
622  PublicationNamespaceObjectIndexId,
623  1,
624  {
625  Anum_pg_publication_namespace_oid,
626  0,
627  0,
628  0
629  },
630  64
631  },
632  {PublicationNamespaceRelationId, /* PUBLICATIONNAMESPACEMAP */
633  PublicationNamespacePnnspidPnpubidIndexId,
634  2,
635  {
636  Anum_pg_publication_namespace_pnnspid,
637  Anum_pg_publication_namespace_pnpubid,
638  0,
639  0
640  },
641  64
642  },
643  {PublicationRelationId, /* PUBLICATIONOID */
644  PublicationObjectIndexId,
645  1,
646  {
647  Anum_pg_publication_oid,
648  0,
649  0,
650  0
651  },
652  8
653  },
654  {PublicationRelRelationId, /* PUBLICATIONREL */
655  PublicationRelObjectIndexId,
656  1,
657  {
658  Anum_pg_publication_rel_oid,
659  0,
660  0,
661  0
662  },
663  64
664  },
665  {PublicationRelRelationId, /* PUBLICATIONRELMAP */
666  PublicationRelPrrelidPrpubidIndexId,
667  2,
668  {
669  Anum_pg_publication_rel_prrelid,
670  Anum_pg_publication_rel_prpubid,
671  0,
672  0
673  },
674  64
675  },
676  {RangeRelationId, /* RANGEMULTIRANGE */
677  RangeMultirangeTypidIndexId,
678  1,
679  {
680  Anum_pg_range_rngmultitypid,
681  0,
682  0,
683  0
684  },
685  4
686  },
687 
688  {RangeRelationId, /* RANGETYPE */
689  RangeTypidIndexId,
690  1,
691  {
692  Anum_pg_range_rngtypid,
693  0,
694  0,
695  0
696  },
697  4
698  },
699  {RelationRelationId, /* RELNAMENSP */
700  ClassNameNspIndexId,
701  2,
702  {
703  Anum_pg_class_relname,
704  Anum_pg_class_relnamespace,
705  0,
706  0
707  },
708  128
709  },
710  {RelationRelationId, /* RELOID */
711  ClassOidIndexId,
712  1,
713  {
714  Anum_pg_class_oid,
715  0,
716  0,
717  0
718  },
719  128
720  },
721  {ReplicationOriginRelationId, /* REPLORIGIDENT */
722  ReplicationOriginIdentIndex,
723  1,
724  {
725  Anum_pg_replication_origin_roident,
726  0,
727  0,
728  0
729  },
730  16
731  },
732  {ReplicationOriginRelationId, /* REPLORIGNAME */
733  ReplicationOriginNameIndex,
734  1,
735  {
736  Anum_pg_replication_origin_roname,
737  0,
738  0,
739  0
740  },
741  16
742  },
743  {RewriteRelationId, /* RULERELNAME */
744  RewriteRelRulenameIndexId,
745  2,
746  {
747  Anum_pg_rewrite_ev_class,
748  Anum_pg_rewrite_rulename,
749  0,
750  0
751  },
752  8
753  },
754  {SequenceRelationId, /* SEQRELID */
755  SequenceRelidIndexId,
756  1,
757  {
758  Anum_pg_sequence_seqrelid,
759  0,
760  0,
761  0
762  },
763  32
764  },
765  {StatisticExtDataRelationId, /* STATEXTDATASTXOID */
766  StatisticExtDataStxoidInhIndexId,
767  2,
768  {
769  Anum_pg_statistic_ext_data_stxoid,
770  Anum_pg_statistic_ext_data_stxdinherit,
771  0,
772  0
773  },
774  4
775  },
776  {StatisticExtRelationId, /* STATEXTNAMENSP */
777  StatisticExtNameIndexId,
778  2,
779  {
780  Anum_pg_statistic_ext_stxname,
781  Anum_pg_statistic_ext_stxnamespace,
782  0,
783  0
784  },
785  4
786  },
787  {StatisticExtRelationId, /* STATEXTOID */
788  StatisticExtOidIndexId,
789  1,
790  {
791  Anum_pg_statistic_ext_oid,
792  0,
793  0,
794  0
795  },
796  4
797  },
798  {StatisticRelationId, /* STATRELATTINH */
799  StatisticRelidAttnumInhIndexId,
800  3,
801  {
802  Anum_pg_statistic_starelid,
803  Anum_pg_statistic_staattnum,
804  Anum_pg_statistic_stainherit,
805  0
806  },
807  128
808  },
809  {SubscriptionRelationId, /* SUBSCRIPTIONNAME */
810  SubscriptionNameIndexId,
811  2,
812  {
813  Anum_pg_subscription_subdbid,
814  Anum_pg_subscription_subname,
815  0,
816  0
817  },
818  4
819  },
820  {SubscriptionRelationId, /* SUBSCRIPTIONOID */
821  SubscriptionObjectIndexId,
822  1,
823  {
824  Anum_pg_subscription_oid,
825  0,
826  0,
827  0
828  },
829  4
830  },
831  {SubscriptionRelRelationId, /* SUBSCRIPTIONRELMAP */
832  SubscriptionRelSrrelidSrsubidIndexId,
833  2,
834  {
835  Anum_pg_subscription_rel_srrelid,
836  Anum_pg_subscription_rel_srsubid,
837  0,
838  0
839  },
840  64
841  },
842  {TableSpaceRelationId, /* TABLESPACEOID */
843  TablespaceOidIndexId,
844  1,
845  {
846  Anum_pg_tablespace_oid,
847  0,
848  0,
849  0,
850  },
851  4
852  },
853  {TransformRelationId, /* TRFOID */
854  TransformOidIndexId,
855  1,
856  {
857  Anum_pg_transform_oid,
858  0,
859  0,
860  0,
861  },
862  16
863  },
864  {TransformRelationId, /* TRFTYPELANG */
865  TransformTypeLangIndexId,
866  2,
867  {
868  Anum_pg_transform_trftype,
869  Anum_pg_transform_trflang,
870  0,
871  0,
872  },
873  16
874  },
875  {TSConfigMapRelationId, /* TSCONFIGMAP */
876  TSConfigMapIndexId,
877  3,
878  {
879  Anum_pg_ts_config_map_mapcfg,
880  Anum_pg_ts_config_map_maptokentype,
881  Anum_pg_ts_config_map_mapseqno,
882  0
883  },
884  2
885  },
886  {TSConfigRelationId, /* TSCONFIGNAMENSP */
887  TSConfigNameNspIndexId,
888  2,
889  {
890  Anum_pg_ts_config_cfgname,
891  Anum_pg_ts_config_cfgnamespace,
892  0,
893  0
894  },
895  2
896  },
897  {TSConfigRelationId, /* TSCONFIGOID */
898  TSConfigOidIndexId,
899  1,
900  {
901  Anum_pg_ts_config_oid,
902  0,
903  0,
904  0
905  },
906  2
907  },
908  {TSDictionaryRelationId, /* TSDICTNAMENSP */
909  TSDictionaryNameNspIndexId,
910  2,
911  {
912  Anum_pg_ts_dict_dictname,
913  Anum_pg_ts_dict_dictnamespace,
914  0,
915  0
916  },
917  2
918  },
919  {TSDictionaryRelationId, /* TSDICTOID */
920  TSDictionaryOidIndexId,
921  1,
922  {
923  Anum_pg_ts_dict_oid,
924  0,
925  0,
926  0
927  },
928  2
929  },
930  {TSParserRelationId, /* TSPARSERNAMENSP */
931  TSParserNameNspIndexId,
932  2,
933  {
934  Anum_pg_ts_parser_prsname,
935  Anum_pg_ts_parser_prsnamespace,
936  0,
937  0
938  },
939  2
940  },
941  {TSParserRelationId, /* TSPARSEROID */
942  TSParserOidIndexId,
943  1,
944  {
945  Anum_pg_ts_parser_oid,
946  0,
947  0,
948  0
949  },
950  2
951  },
952  {TSTemplateRelationId, /* TSTEMPLATENAMENSP */
953  TSTemplateNameNspIndexId,
954  2,
955  {
956  Anum_pg_ts_template_tmplname,
957  Anum_pg_ts_template_tmplnamespace,
958  0,
959  0
960  },
961  2
962  },
963  {TSTemplateRelationId, /* TSTEMPLATEOID */
964  TSTemplateOidIndexId,
965  1,
966  {
967  Anum_pg_ts_template_oid,
968  0,
969  0,
970  0
971  },
972  2
973  },
974  {TypeRelationId, /* TYPENAMENSP */
975  TypeNameNspIndexId,
976  2,
977  {
978  Anum_pg_type_typname,
979  Anum_pg_type_typnamespace,
980  0,
981  0
982  },
983  64
984  },
985  {TypeRelationId, /* TYPEOID */
986  TypeOidIndexId,
987  1,
988  {
989  Anum_pg_type_oid,
990  0,
991  0,
992  0
993  },
994  64
995  },
996  {UserMappingRelationId, /* USERMAPPINGOID */
997  UserMappingOidIndexId,
998  1,
999  {
1000  Anum_pg_user_mapping_oid,
1001  0,
1002  0,
1003  0
1004  },
1005  2
1006  },
1007  {UserMappingRelationId, /* USERMAPPINGUSERSERVER */
1008  UserMappingUserServerIndexId,
1009  2,
1010  {
1011  Anum_pg_user_mapping_umuser,
1012  Anum_pg_user_mapping_umserver,
1013  0,
1014  0
1015  },
1016  2
1017  }
1018 };
1019 
1021 
1022 static bool CacheInitialized = false;
1023 
1024 /* Sorted array of OIDs of tables that have caches on them */
1027 
1028 /* Sorted array of OIDs of tables and indexes used by caches */
1031 
1032 static int oid_compare(const void *a, const void *b);
1033 
1034 
1035 /*
1036  * InitCatalogCache - initialize the caches
1037  *
1038  * Note that no database access is done here; we only allocate memory
1039  * and initialize the cache structure. Interrogation of the database
1040  * to complete initialization of a cache happens upon first use
1041  * of that cache.
1042  */
1043 void
1045 {
1046  int cacheId;
1047 
1049  "SysCacheSize does not match syscache.c's array");
1050 
1052 
1054 
1055  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
1056  {
1057  SysCache[cacheId] = InitCatCache(cacheId,
1058  cacheinfo[cacheId].reloid,
1059  cacheinfo[cacheId].indoid,
1060  cacheinfo[cacheId].nkeys,
1061  cacheinfo[cacheId].key,
1062  cacheinfo[cacheId].nbuckets);
1063  if (!PointerIsValid(SysCache[cacheId]))
1064  elog(ERROR, "could not initialize cache %u (%d)",
1065  cacheinfo[cacheId].reloid, cacheId);
1066  /* Accumulate data for OID lists, too */
1068  cacheinfo[cacheId].reloid;
1070  cacheinfo[cacheId].reloid;
1072  cacheinfo[cacheId].indoid;
1073  /* see comments for RelationInvalidatesSnapshotsOnly */
1075  }
1076 
1079 
1080  /* Sort and de-dup OID arrays, so we can use binary search. */
1082  sizeof(Oid), oid_compare);
1085  oid_compare);
1086 
1088  sizeof(Oid), oid_compare);
1091  sizeof(Oid), oid_compare);
1092 
1093  CacheInitialized = true;
1094 }
1095 
1096 /*
1097  * InitCatalogCachePhase2 - finish initializing the caches
1098  *
1099  * Finish initializing all the caches, including necessary database
1100  * access.
1101  *
1102  * This is *not* essential; normally we allow syscaches to be initialized
1103  * on first use. However, it is useful as a mechanism to preload the
1104  * relcache with entries for the most-commonly-used system catalogs.
1105  * Therefore, we invoke this routine when we need to write a new relcache
1106  * init file.
1107  */
1108 void
1110 {
1111  int cacheId;
1112 
1114 
1115  for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
1116  InitCatCachePhase2(SysCache[cacheId], true);
1117 }
1118 
1119 
1120 /*
1121  * SearchSysCache
1122  *
1123  * A layer on top of SearchCatCache that does the initialization and
1124  * key-setting for you.
1125  *
1126  * Returns the cache copy of the tuple if one is found, NULL if not.
1127  * The tuple is the 'cache' copy and must NOT be modified!
1128  *
1129  * When the caller is done using the tuple, call ReleaseSysCache()
1130  * to release the reference count grabbed by SearchSysCache(). If this
1131  * is not done, the tuple will remain locked in cache until end of
1132  * transaction, which is tolerable but not desirable.
1133  *
1134  * CAUTION: The tuple that is returned must NOT be freed by the caller!
1135  */
1136 HeapTuple
1137 SearchSysCache(int cacheId,
1138  Datum key1,
1139  Datum key2,
1140  Datum key3,
1141  Datum key4)
1142 {
1143  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
1144  PointerIsValid(SysCache[cacheId]));
1145 
1146  return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
1147 }
1148 
1149 HeapTuple
1150 SearchSysCache1(int cacheId,
1151  Datum key1)
1152 {
1153  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
1154  PointerIsValid(SysCache[cacheId]));
1155  Assert(SysCache[cacheId]->cc_nkeys == 1);
1156 
1157  return SearchCatCache1(SysCache[cacheId], key1);
1158 }
1159 
1160 HeapTuple
1161 SearchSysCache2(int cacheId,
1162  Datum key1, Datum key2)
1163 {
1164  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
1165  PointerIsValid(SysCache[cacheId]));
1166  Assert(SysCache[cacheId]->cc_nkeys == 2);
1167 
1168  return SearchCatCache2(SysCache[cacheId], key1, key2);
1169 }
1170 
1171 HeapTuple
1172 SearchSysCache3(int cacheId,
1173  Datum key1, Datum key2, Datum key3)
1174 {
1175  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
1176  PointerIsValid(SysCache[cacheId]));
1177  Assert(SysCache[cacheId]->cc_nkeys == 3);
1178 
1179  return SearchCatCache3(SysCache[cacheId], key1, key2, key3);
1180 }
1181 
1182 HeapTuple
1183 SearchSysCache4(int cacheId,
1184  Datum key1, Datum key2, Datum key3, Datum key4)
1185 {
1186  Assert(cacheId >= 0 && cacheId < SysCacheSize &&
1187  PointerIsValid(SysCache[cacheId]));
1188  Assert(SysCache[cacheId]->cc_nkeys == 4);
1189 
1190  return SearchCatCache4(SysCache[cacheId], key1, key2, key3, key4);
1191 }
1192 
1193 /*
1194  * ReleaseSysCache
1195  * Release previously grabbed reference count on a tuple
1196  */
1197 void
1199 {
1200  ReleaseCatCache(tuple);
1201 }
1202 
1203 /*
1204  * SearchSysCacheCopy
1205  *
1206  * A convenience routine that does SearchSysCache and (if successful)
1207  * returns a modifiable copy of the syscache entry. The original
1208  * syscache entry is released before returning. The caller should
1209  * heap_freetuple() the result when done with it.
1210  */
1211 HeapTuple
1213  Datum key1,
1214  Datum key2,
1215  Datum key3,
1216  Datum key4)
1217 {
1218  HeapTuple tuple,
1219  newtuple;
1220 
1221  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1222  if (!HeapTupleIsValid(tuple))
1223  return tuple;
1224  newtuple = heap_copytuple(tuple);
1225  ReleaseSysCache(tuple);
1226  return newtuple;
1227 }
1228 
1229 /*
1230  * SearchSysCacheExists
1231  *
1232  * A convenience routine that just probes to see if a tuple can be found.
1233  * No lock is retained on the syscache entry.
1234  */
1235 bool
1237  Datum key1,
1238  Datum key2,
1239  Datum key3,
1240  Datum key4)
1241 {
1242  HeapTuple tuple;
1243 
1244  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1245  if (!HeapTupleIsValid(tuple))
1246  return false;
1247  ReleaseSysCache(tuple);
1248  return true;
1249 }
1250 
1251 /*
1252  * GetSysCacheOid
1253  *
1254  * A convenience routine that does SearchSysCache and returns the OID in the
1255  * oidcol column of the found tuple, or InvalidOid if no tuple could be found.
1256  * No lock is retained on the syscache entry.
1257  */
1258 Oid
1259 GetSysCacheOid(int cacheId,
1260  AttrNumber oidcol,
1261  Datum key1,
1262  Datum key2,
1263  Datum key3,
1264  Datum key4)
1265 {
1266  HeapTuple tuple;
1267  bool isNull;
1268  Oid result;
1269 
1270  tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
1271  if (!HeapTupleIsValid(tuple))
1272  return InvalidOid;
1273  result = heap_getattr(tuple, oidcol,
1274  SysCache[cacheId]->cc_tupdesc,
1275  &isNull);
1276  Assert(!isNull); /* columns used as oids should never be NULL */
1277  ReleaseSysCache(tuple);
1278  return result;
1279 }
1280 
1281 
1282 /*
1283  * SearchSysCacheAttName
1284  *
1285  * This routine is equivalent to SearchSysCache on the ATTNAME cache,
1286  * except that it will return NULL if the found attribute is marked
1287  * attisdropped. This is convenient for callers that want to act as
1288  * though dropped attributes don't exist.
1289  */
1290 HeapTuple
1291 SearchSysCacheAttName(Oid relid, const char *attname)
1292 {
1293  HeapTuple tuple;
1294 
1295  tuple = SearchSysCache2(ATTNAME,
1296  ObjectIdGetDatum(relid),
1298  if (!HeapTupleIsValid(tuple))
1299  return NULL;
1300  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
1301  {
1302  ReleaseSysCache(tuple);
1303  return NULL;
1304  }
1305  return tuple;
1306 }
1307 
1308 /*
1309  * SearchSysCacheCopyAttName
1310  *
1311  * As above, an attisdropped-aware version of SearchSysCacheCopy.
1312  */
1313 HeapTuple
1315 {
1316  HeapTuple tuple,
1317  newtuple;
1318 
1319  tuple = SearchSysCacheAttName(relid, attname);
1320  if (!HeapTupleIsValid(tuple))
1321  return tuple;
1322  newtuple = heap_copytuple(tuple);
1323  ReleaseSysCache(tuple);
1324  return newtuple;
1325 }
1326 
1327 /*
1328  * SearchSysCacheExistsAttName
1329  *
1330  * As above, an attisdropped-aware version of SearchSysCacheExists.
1331  */
1332 bool
1334 {
1335  HeapTuple tuple;
1336 
1337  tuple = SearchSysCacheAttName(relid, attname);
1338  if (!HeapTupleIsValid(tuple))
1339  return false;
1340  ReleaseSysCache(tuple);
1341  return true;
1342 }
1343 
1344 
1345 /*
1346  * SearchSysCacheAttNum
1347  *
1348  * This routine is equivalent to SearchSysCache on the ATTNUM cache,
1349  * except that it will return NULL if the found attribute is marked
1350  * attisdropped. This is convenient for callers that want to act as
1351  * though dropped attributes don't exist.
1352  */
1353 HeapTuple
1355 {
1356  HeapTuple tuple;
1357 
1358  tuple = SearchSysCache2(ATTNUM,
1359  ObjectIdGetDatum(relid),
1361  if (!HeapTupleIsValid(tuple))
1362  return NULL;
1363  if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
1364  {
1365  ReleaseSysCache(tuple);
1366  return NULL;
1367  }
1368  return tuple;
1369 }
1370 
1371 /*
1372  * SearchSysCacheCopyAttNum
1373  *
1374  * As above, an attisdropped-aware version of SearchSysCacheCopy.
1375  */
1376 HeapTuple
1378 {
1379  HeapTuple tuple,
1380  newtuple;
1381 
1382  tuple = SearchSysCacheAttNum(relid, attnum);
1383  if (!HeapTupleIsValid(tuple))
1384  return NULL;
1385  newtuple = heap_copytuple(tuple);
1386  ReleaseSysCache(tuple);
1387  return newtuple;
1388 }
1389 
1390 
1391 /*
1392  * SysCacheGetAttr
1393  *
1394  * Given a tuple previously fetched by SearchSysCache(),
1395  * extract a specific attribute.
1396  *
1397  * This is equivalent to using heap_getattr() on a tuple fetched
1398  * from a non-cached relation. Usually, this is only used for attributes
1399  * that could be NULL or variable length; the fixed-size attributes in
1400  * a system table are accessed just by mapping the tuple onto the C struct
1401  * declarations from include/catalog/.
1402  *
1403  * As with heap_getattr(), if the attribute is of a pass-by-reference type
1404  * then a pointer into the tuple data area is returned --- the caller must
1405  * not modify or pfree the datum!
1406  *
1407  * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
1408  * a different cache for the same catalog the tuple was fetched from.
1409  */
1410 Datum
1411 SysCacheGetAttr(int cacheId, HeapTuple tup,
1412  AttrNumber attributeNumber,
1413  bool *isNull)
1414 {
1415  /*
1416  * We just need to get the TupleDesc out of the cache entry, and then we
1417  * can apply heap_getattr(). Normally the cache control data is already
1418  * valid (because the caller recently fetched the tuple via this same
1419  * cache), but there are cases where we have to initialize the cache here.
1420  */
1421  if (cacheId < 0 || cacheId >= SysCacheSize ||
1422  !PointerIsValid(SysCache[cacheId]))
1423  elog(ERROR, "invalid cache ID: %d", cacheId);
1424  if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
1425  {
1426  InitCatCachePhase2(SysCache[cacheId], false);
1427  Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
1428  }
1429 
1430  return heap_getattr(tup, attributeNumber,
1431  SysCache[cacheId]->cc_tupdesc,
1432  isNull);
1433 }
1434 
1435 /*
1436  * GetSysCacheHashValue
1437  *
1438  * Get the hash value that would be used for a tuple in the specified cache
1439  * with the given search keys.
1440  *
1441  * The reason for exposing this as part of the API is that the hash value is
1442  * exposed in cache invalidation operations, so there are places outside the
1443  * catcache code that need to be able to compute the hash values.
1444  */
1445 uint32
1447  Datum key1,
1448  Datum key2,
1449  Datum key3,
1450  Datum key4)
1451 {
1452  if (cacheId < 0 || cacheId >= SysCacheSize ||
1453  !PointerIsValid(SysCache[cacheId]))
1454  elog(ERROR, "invalid cache ID: %d", cacheId);
1455 
1456  return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
1457 }
1458 
1459 /*
1460  * List-search interface
1461  */
1462 struct catclist *
1463 SearchSysCacheList(int cacheId, int nkeys,
1464  Datum key1, Datum key2, Datum key3)
1465 {
1466  if (cacheId < 0 || cacheId >= SysCacheSize ||
1467  !PointerIsValid(SysCache[cacheId]))
1468  elog(ERROR, "invalid cache ID: %d", cacheId);
1469 
1470  return SearchCatCacheList(SysCache[cacheId], nkeys,
1471  key1, key2, key3);
1472 }
1473 
1474 /*
1475  * SysCacheInvalidate
1476  *
1477  * Invalidate entries in the specified cache, given a hash value.
1478  * See CatCacheInvalidate() for more info.
1479  *
1480  * This routine is only quasi-public: it should only be used by inval.c.
1481  */
1482 void
1483 SysCacheInvalidate(int cacheId, uint32 hashValue)
1484 {
1485  if (cacheId < 0 || cacheId >= SysCacheSize)
1486  elog(ERROR, "invalid cache ID: %d", cacheId);
1487 
1488  /* if this cache isn't initialized yet, no need to do anything */
1489  if (!PointerIsValid(SysCache[cacheId]))
1490  return;
1491 
1492  CatCacheInvalidate(SysCache[cacheId], hashValue);
1493 }
1494 
1495 /*
1496  * Certain relations that do not have system caches send snapshot invalidation
1497  * messages in lieu of catcache messages. This is for the benefit of
1498  * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
1499  * for scanning one of those catalogs, rather than taking a new one, if no
1500  * invalidation has been received.
1501  *
1502  * Relations that have syscaches need not (and must not) be listed here. The
1503  * catcache invalidation messages will also flush the snapshot. If you add a
1504  * syscache for one of these relations, remove it from this list.
1505  */
1506 bool
1508 {
1509  switch (relid)
1510  {
1511  case DbRoleSettingRelationId:
1512  case DependRelationId:
1513  case SharedDependRelationId:
1514  case DescriptionRelationId:
1515  case SharedDescriptionRelationId:
1516  case SecLabelRelationId:
1517  case SharedSecLabelRelationId:
1518  return true;
1519  default:
1520  break;
1521  }
1522 
1523  return false;
1524 }
1525 
1526 /*
1527  * Test whether a relation has a system cache.
1528  */
1529 bool
1531 {
1532  int low = 0,
1533  high = SysCacheRelationOidSize - 1;
1534 
1535  while (low <= high)
1536  {
1537  int middle = low + (high - low) / 2;
1538 
1539  if (SysCacheRelationOid[middle] == relid)
1540  return true;
1541  if (SysCacheRelationOid[middle] < relid)
1542  low = middle + 1;
1543  else
1544  high = middle - 1;
1545  }
1546 
1547  return false;
1548 }
1549 
1550 /*
1551  * Test whether a relation supports a system cache, ie it is either a
1552  * cached table or the index used for a cache.
1553  */
1554 bool
1556 {
1557  int low = 0,
1558  high = SysCacheSupportingRelOidSize - 1;
1559 
1560  while (low <= high)
1561  {
1562  int middle = low + (high - low) / 2;
1563 
1564  if (SysCacheSupportingRelOid[middle] == relid)
1565  return true;
1566  if (SysCacheSupportingRelOid[middle] < relid)
1567  low = middle + 1;
1568  else
1569  high = middle - 1;
1570  }
1571 
1572  return false;
1573 }
1574 
1575 
1576 /*
1577  * OID comparator for pg_qsort
1578  */
1579 static int
1580 oid_compare(const void *a, const void *b)
1581 {
1582  Oid oa = *((const Oid *) a);
1583  Oid ob = *((const Oid *) b);
1584 
1585  if (oa == ob)
1586  return 0;
1587  return (oa > ob) ? 1 : -1;
1588 }
int16 AttrNumber
Definition: attnum.h:21
unsigned int uint32
Definition: c.h:441
signed short int16
Definition: c.h:428
#define PointerIsValid(pointer)
Definition: c.h:698
#define lengthof(array)
Definition: c.h:734
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
Definition: catcache.c:1174
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
Definition: catcache.c:1182
void InitCatCachePhase2(CatCache *cache, bool touch_index)
Definition: catcache.c:1032
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1474
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1190
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Definition: catcache.c:763
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
Definition: catcache.c:1508
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
Definition: catcache.c:552
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
Definition: catcache.c:1166
void ReleaseCatCache(HeapTuple tuple)
Definition: catcache.c:1442
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
Definition: catcache.c:1149
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:756
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
int b
Definition: isn.c:70
int a
Definition: isn.c:69
Assert(fmt[strlen(fmt) - 1] !='\n')
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:83
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
void pg_qsort(void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
#define CStringGetDatum(X)
Definition: postgres.h:622
uintptr_t Datum
Definition: postgres.h:411
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define Int16GetDatum(X)
Definition: postgres.h:495
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
int key[4]
Definition: syscache.c:120
int nkeys
Definition: syscache.c:119
int nbuckets
Definition: syscache.c:121
Oid indoid
Definition: syscache.c:118
Oid reloid
Definition: syscache.c:117
short nkeys
Definition: catcache.h:175
HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname)
Definition: syscache.c:1314
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:1483
bool RelationHasSysCache(Oid relid)
Definition: syscache.c:1530
HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
Definition: syscache.c:1377
void InitCatalogCache(void)
Definition: syscache.c:1044
static const struct cachedesc cacheinfo[]
Definition: syscache.c:124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1198
static bool CacheInitialized
Definition: syscache.c:1022
static int oid_compare(const void *a, const void *b)
Definition: syscache.c:1580
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1137
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1150
uint32 GetSysCacheHashValue(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1446
struct catclist * SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1463
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1172
static int SysCacheSupportingRelOidSize
Definition: syscache.c:1030
HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum)
Definition: syscache.c:1354
bool RelationSupportsSysCache(Oid relid)
Definition: syscache.c:1555
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1411
bool SearchSysCacheExistsAttName(Oid relid, const char *attname)
Definition: syscache.c:1333
void InitCatalogCachePhase2(void)
Definition: syscache.c:1109
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1161
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1291
bool SearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1236
HeapTuple SearchSysCacheCopy(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1212
static Oid SysCacheRelationOid[SysCacheSize]
Definition: syscache.c:1025
static CatCache * SysCache[SysCacheSize]
Definition: syscache.c:1020
static Oid SysCacheSupportingRelOid[SysCacheSize *2]
Definition: syscache.c:1029
static int SysCacheRelationOidSize
Definition: syscache.c:1026
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:1507
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1183
Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1259
@ ATTNAME
Definition: syscache.h:40
@ ATTNUM
Definition: syscache.h:41
#define SysCacheSize
Definition: syscache.h:116