LCOV - code coverage report
Current view: top level - src/backend/utils/cache - syscache.c (source / functions) Hit Total Coverage
Test: PostgreSQL 15devel Lines: 144 152 94.7 %
Date: 2021-12-09 03:08:47 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * syscache.c
       4             :  *    System cache management routines
       5             :  *
       6             :  * Portions Copyright (c) 1996-2021, 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"
      29             : #include "catalog/pg_auth_members.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"
      36             : #include "catalog/pg_db_role_setting.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"
      41             : #include "catalog/pg_event_trigger.h"
      42             : #include "catalog/pg_foreign_data_wrapper.h"
      43             : #include "catalog/pg_foreign_server.h"
      44             : #include "catalog/pg_foreign_table.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"
      50             : #include "catalog/pg_partitioned_table.h"
      51             : #include "catalog/pg_proc.h"
      52             : #include "catalog/pg_publication.h"
      53             : #include "catalog/pg_publication_namespace.h"
      54             : #include "catalog/pg_publication_rel.h"
      55             : #include "catalog/pg_range.h"
      56             : #include "catalog/pg_replication_origin.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"
      61             : #include "catalog/pg_shdescription.h"
      62             : #include "catalog/pg_shseclabel.h"
      63             : #include "catalog/pg_statistic.h"
      64             : #include "catalog/pg_statistic_ext.h"
      65             : #include "catalog/pg_statistic_ext_data.h"
      66             : #include "catalog/pg_subscription.h"
      67             : #include "catalog/pg_subscription_rel.h"
      68             : #include "catalog/pg_tablespace.h"
      69             : #include "catalog/pg_transform.h"
      70             : #include "catalog/pg_ts_config.h"
      71             : #include "catalog/pg_ts_config_map.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"
      76             : #include "catalog/pg_user_mapping.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             :         StatisticExtDataStxoidIndexId,
     767             :         1,
     768             :         {
     769             :             Anum_pg_statistic_ext_data_stxoid,
     770             :             0,
     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             : 
    1020             : static CatCache *SysCache[SysCacheSize];
    1021             : 
    1022             : static bool CacheInitialized = false;
    1023             : 
    1024             : /* Sorted array of OIDs of tables that have caches on them */
    1025             : static Oid  SysCacheRelationOid[SysCacheSize];
    1026             : static int  SysCacheRelationOidSize;
    1027             : 
    1028             : /* Sorted array of OIDs of tables and indexes used by caches */
    1029             : static Oid  SysCacheSupportingRelOid[SysCacheSize * 2];
    1030             : static int  SysCacheSupportingRelOidSize;
    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
    1044       15926 : InitCatalogCache(void)
    1045             : {
    1046             :     int         cacheId;
    1047             : 
    1048             :     StaticAssertStmt(SysCacheSize == (int) lengthof(cacheinfo),
    1049             :                      "SysCacheSize does not match syscache.c's array");
    1050             : 
    1051             :     Assert(!CacheInitialized);
    1052             : 
    1053       15926 :     SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0;
    1054             : 
    1055     1305932 :     for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
    1056             :     {
    1057     2580012 :         SysCache[cacheId] = InitCatCache(cacheId,
    1058             :                                          cacheinfo[cacheId].reloid,
    1059             :                                          cacheinfo[cacheId].indoid,
    1060             :                                          cacheinfo[cacheId].nkeys,
    1061     1290006 :                                          cacheinfo[cacheId].key,
    1062             :                                          cacheinfo[cacheId].nbuckets);
    1063     1290006 :         if (!PointerIsValid(SysCache[cacheId]))
    1064           0 :             elog(ERROR, "could not initialize cache %u (%d)",
    1065             :                  cacheinfo[cacheId].reloid, cacheId);
    1066             :         /* Accumulate data for OID lists, too */
    1067     1290006 :         SysCacheRelationOid[SysCacheRelationOidSize++] =
    1068     1290006 :             cacheinfo[cacheId].reloid;
    1069     1290006 :         SysCacheSupportingRelOid[SysCacheSupportingRelOidSize++] =
    1070     1290006 :             cacheinfo[cacheId].reloid;
    1071     1290006 :         SysCacheSupportingRelOid[SysCacheSupportingRelOidSize++] =
    1072     1290006 :             cacheinfo[cacheId].indoid;
    1073             :         /* see comments for RelationInvalidatesSnapshotsOnly */
    1074             :         Assert(!RelationInvalidatesSnapshotsOnly(cacheinfo[cacheId].reloid));
    1075             :     }
    1076             : 
    1077             :     Assert(SysCacheRelationOidSize <= lengthof(SysCacheRelationOid));
    1078             :     Assert(SysCacheSupportingRelOidSize <= lengthof(SysCacheSupportingRelOid));
    1079             : 
    1080             :     /* Sort and de-dup OID arrays, so we can use binary search. */
    1081       15926 :     pg_qsort(SysCacheRelationOid, SysCacheRelationOidSize,
    1082             :              sizeof(Oid), oid_compare);
    1083       15926 :     SysCacheRelationOidSize =
    1084       15926 :         qunique(SysCacheRelationOid, SysCacheRelationOidSize, sizeof(Oid),
    1085             :                 oid_compare);
    1086             : 
    1087       15926 :     pg_qsort(SysCacheSupportingRelOid, SysCacheSupportingRelOidSize,
    1088             :              sizeof(Oid), oid_compare);
    1089       15926 :     SysCacheSupportingRelOidSize =
    1090       15926 :         qunique(SysCacheSupportingRelOid, SysCacheSupportingRelOidSize,
    1091             :                 sizeof(Oid), oid_compare);
    1092             : 
    1093       15926 :     CacheInitialized = true;
    1094       15926 : }
    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
    1109        1854 : InitCatalogCachePhase2(void)
    1110             : {
    1111             :     int         cacheId;
    1112             : 
    1113             :     Assert(CacheInitialized);
    1114             : 
    1115      152028 :     for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
    1116      150174 :         InitCatCachePhase2(SysCache[cacheId], true);
    1117        1854 : }
    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     5931358 : 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     5931358 :     return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
    1147             : }
    1148             : 
    1149             : HeapTuple
    1150    57467614 : 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    57467614 :     return SearchCatCache1(SysCache[cacheId], key1);
    1158             : }
    1159             : 
    1160             : HeapTuple
    1161     6393214 : 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     6393214 :     return SearchCatCache2(SysCache[cacheId], key1, key2);
    1169             : }
    1170             : 
    1171             : HeapTuple
    1172     2862868 : 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     2862868 :     return SearchCatCache3(SysCache[cacheId], key1, key2, key3);
    1180             : }
    1181             : 
    1182             : HeapTuple
    1183     2543076 : 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     2543076 :     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
    1198    68354406 : ReleaseSysCache(HeapTuple tuple)
    1199             : {
    1200    68354406 :     ReleaseCatCache(tuple);
    1201    68354406 : }
    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
    1212      973516 : SearchSysCacheCopy(int cacheId,
    1213             :                    Datum key1,
    1214             :                    Datum key2,
    1215             :                    Datum key3,
    1216             :                    Datum key4)
    1217             : {
    1218             :     HeapTuple   tuple,
    1219             :                 newtuple;
    1220             : 
    1221      973516 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
    1222      973516 :     if (!HeapTupleIsValid(tuple))
    1223      253160 :         return tuple;
    1224      720356 :     newtuple = heap_copytuple(tuple);
    1225      720356 :     ReleaseSysCache(tuple);
    1226      720356 :     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
    1236      873444 : SearchSysCacheExists(int cacheId,
    1237             :                      Datum key1,
    1238             :                      Datum key2,
    1239             :                      Datum key3,
    1240             :                      Datum key4)
    1241             : {
    1242             :     HeapTuple   tuple;
    1243             : 
    1244      873444 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
    1245      873444 :     if (!HeapTupleIsValid(tuple))
    1246      205374 :         return false;
    1247      668070 :     ReleaseSysCache(tuple);
    1248      668070 :     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     4084394 : 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     4084394 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
    1271     4084394 :     if (!HeapTupleIsValid(tuple))
    1272     1562456 :         return InvalidOid;
    1273     2521938 :     result = heap_getattr(tuple, oidcol,
    1274             :                           SysCache[cacheId]->cc_tupdesc,
    1275             :                           &isNull);
    1276             :     Assert(!isNull);            /* columns used as oids should never be NULL */
    1277     2521938 :     ReleaseSysCache(tuple);
    1278     2521938 :     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      175478 : SearchSysCacheAttName(Oid relid, const char *attname)
    1292             : {
    1293             :     HeapTuple   tuple;
    1294             : 
    1295      175478 :     tuple = SearchSysCache2(ATTNAME,
    1296             :                             ObjectIdGetDatum(relid),
    1297             :                             CStringGetDatum(attname));
    1298      175478 :     if (!HeapTupleIsValid(tuple))
    1299         548 :         return NULL;
    1300      174930 :     if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
    1301             :     {
    1302          52 :         ReleaseSysCache(tuple);
    1303          52 :         return NULL;
    1304             :     }
    1305      174878 :     return tuple;
    1306             : }
    1307             : 
    1308             : /*
    1309             :  * SearchSysCacheCopyAttName
    1310             :  *
    1311             :  * As above, an attisdropped-aware version of SearchSysCacheCopy.
    1312             :  */
    1313             : HeapTuple
    1314       45232 : SearchSysCacheCopyAttName(Oid relid, const char *attname)
    1315             : {
    1316             :     HeapTuple   tuple,
    1317             :                 newtuple;
    1318             : 
    1319       45232 :     tuple = SearchSysCacheAttName(relid, attname);
    1320       45232 :     if (!HeapTupleIsValid(tuple))
    1321         448 :         return tuple;
    1322       44784 :     newtuple = heap_copytuple(tuple);
    1323       44784 :     ReleaseSysCache(tuple);
    1324       44784 :     return newtuple;
    1325             : }
    1326             : 
    1327             : /*
    1328             :  * SearchSysCacheExistsAttName
    1329             :  *
    1330             :  * As above, an attisdropped-aware version of SearchSysCacheExists.
    1331             :  */
    1332             : bool
    1333         546 : SearchSysCacheExistsAttName(Oid relid, const char *attname)
    1334             : {
    1335             :     HeapTuple   tuple;
    1336             : 
    1337         546 :     tuple = SearchSysCacheAttName(relid, attname);
    1338         546 :     if (!HeapTupleIsValid(tuple))
    1339           8 :         return false;
    1340         538 :     ReleaseSysCache(tuple);
    1341         538 :     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
    1354          64 : SearchSysCacheAttNum(Oid relid, int16 attnum)
    1355             : {
    1356             :     HeapTuple   tuple;
    1357             : 
    1358          64 :     tuple = SearchSysCache2(ATTNUM,
    1359             :                             ObjectIdGetDatum(relid),
    1360             :                             Int16GetDatum(attnum));
    1361          64 :     if (!HeapTupleIsValid(tuple))
    1362           8 :         return NULL;
    1363          56 :     if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
    1364             :     {
    1365           0 :         ReleaseSysCache(tuple);
    1366           0 :         return NULL;
    1367             :     }
    1368          56 :     return tuple;
    1369             : }
    1370             : 
    1371             : /*
    1372             :  * SearchSysCacheCopyAttNum
    1373             :  *
    1374             :  * As above, an attisdropped-aware version of SearchSysCacheCopy.
    1375             :  */
    1376             : HeapTuple
    1377          64 : SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
    1378             : {
    1379             :     HeapTuple   tuple,
    1380             :                 newtuple;
    1381             : 
    1382          64 :     tuple = SearchSysCacheAttNum(relid, attnum);
    1383          64 :     if (!HeapTupleIsValid(tuple))
    1384           8 :         return NULL;
    1385          56 :     newtuple = heap_copytuple(tuple);
    1386          56 :     ReleaseSysCache(tuple);
    1387          56 :     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     3499368 : 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     3499368 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
    1422     3499368 :         !PointerIsValid(SysCache[cacheId]))
    1423           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
    1424     3499368 :     if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
    1425             :     {
    1426       14664 :         InitCatCachePhase2(SysCache[cacheId], false);
    1427             :         Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
    1428             :     }
    1429             : 
    1430     3499368 :     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
    1446      163242 : GetSysCacheHashValue(int cacheId,
    1447             :                      Datum key1,
    1448             :                      Datum key2,
    1449             :                      Datum key3,
    1450             :                      Datum key4)
    1451             : {
    1452      163242 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
    1453      163242 :         !PointerIsValid(SysCache[cacheId]))
    1454           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
    1455             : 
    1456      163242 :     return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
    1457             : }
    1458             : 
    1459             : /*
    1460             :  * List-search interface
    1461             :  */
    1462             : struct catclist *
    1463     2149602 : SearchSysCacheList(int cacheId, int nkeys,
    1464             :                    Datum key1, Datum key2, Datum key3)
    1465             : {
    1466     2149602 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
    1467     2149602 :         !PointerIsValid(SysCache[cacheId]))
    1468           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
    1469             : 
    1470     2149602 :     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    18491962 : SysCacheInvalidate(int cacheId, uint32 hashValue)
    1484             : {
    1485    18491962 :     if (cacheId < 0 || cacheId >= SysCacheSize)
    1486           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
    1487             : 
    1488             :     /* if this cache isn't initialized yet, no need to do anything */
    1489    18491962 :     if (!PointerIsValid(SysCache[cacheId]))
    1490           0 :         return;
    1491             : 
    1492    18491962 :     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
    1507    14349238 : RelationInvalidatesSnapshotsOnly(Oid relid)
    1508             : {
    1509    14349238 :     switch (relid)
    1510             :     {
    1511     2687566 :         case DbRoleSettingRelationId:
    1512             :         case DependRelationId:
    1513             :         case SharedDependRelationId:
    1514             :         case DescriptionRelationId:
    1515             :         case SharedDescriptionRelationId:
    1516             :         case SecLabelRelationId:
    1517             :         case SharedSecLabelRelationId:
    1518     2687566 :             return true;
    1519    11661672 :         default:
    1520    11661672 :             break;
    1521             :     }
    1522             : 
    1523    11661672 :     return false;
    1524             : }
    1525             : 
    1526             : /*
    1527             :  * Test whether a relation has a system cache.
    1528             :  */
    1529             : bool
    1530     8136580 : RelationHasSysCache(Oid relid)
    1531             : {
    1532     8136580 :     int         low = 0,
    1533     8136580 :                 high = SysCacheRelationOidSize - 1;
    1534             : 
    1535    33893720 :     while (low <= high)
    1536             :     {
    1537    33651696 :         int         middle = low + (high - low) / 2;
    1538             : 
    1539    33651696 :         if (SysCacheRelationOid[middle] == relid)
    1540     7894556 :             return true;
    1541    25757140 :         if (SysCacheRelationOid[middle] < relid)
    1542     7839420 :             low = middle + 1;
    1543             :         else
    1544    17917720 :             high = middle - 1;
    1545             :     }
    1546             : 
    1547      242024 :     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
    1555     2262848 : RelationSupportsSysCache(Oid relid)
    1556             : {
    1557     2262848 :     int         low = 0,
    1558     2262848 :                 high = SysCacheSupportingRelOidSize - 1;
    1559             : 
    1560    19164130 :     while (low <= high)
    1561             :     {
    1562    17287296 :         int         middle = low + (high - low) / 2;
    1563             : 
    1564    17287296 :         if (SysCacheSupportingRelOid[middle] == relid)
    1565      386014 :             return true;
    1566    16901282 :         if (SysCacheSupportingRelOid[middle] < relid)
    1567    15631920 :             low = middle + 1;
    1568             :         else
    1569     1269362 :             high = middle - 1;
    1570             :     }
    1571             : 
    1572     1876834 :     return false;
    1573             : }
    1574             : 
    1575             : 
    1576             : /*
    1577             :  * OID comparator for pg_qsort
    1578             :  */
    1579             : static int
    1580    29924954 : oid_compare(const void *a, const void *b)
    1581             : {
    1582    29924954 :     Oid         oa = *((const Oid *) a);
    1583    29924954 :     Oid         ob = *((const Oid *) b);
    1584             : 
    1585    29924954 :     if (oa == ob)
    1586     2325196 :         return 0;
    1587    27599758 :     return (oa > ob) ? 1 : -1;
    1588             : }

Generated by: LCOV version 1.14