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

Generated by: LCOV version 1.11