LCOV - differential code coverage report
Current view: top level - src/backend/utils/cache - syscache.c (source / functions) Coverage Total Hit UNC UIC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 95.0 % 180 171 1 8 3 150 5 13 4 70 2 88
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 25 25 24 1 12 13
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 80.0 % 5 4 1 4
Legend: Lines: hit not hit (60,120] days: 100.0 % 1 1 1
(240..) days: 95.4 % 174 166 8 3 150 13 4 70
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(240..) days: 66.7 % 36 24 24 12

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * syscache.c
                                  4                 :  *    System cache management routines
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, 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_parameter_acl.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_namespace.h"
                                 55                 : #include "catalog/pg_publication_rel.h"
                                 56                 : #include "catalog/pg_range.h"
                                 57                 : #include "catalog/pg_replication_origin.h"
                                 58                 : #include "catalog/pg_rewrite.h"
                                 59                 : #include "catalog/pg_seclabel.h"
                                 60                 : #include "catalog/pg_sequence.h"
                                 61                 : #include "catalog/pg_shdepend.h"
                                 62                 : #include "catalog/pg_shdescription.h"
                                 63                 : #include "catalog/pg_shseclabel.h"
                                 64                 : #include "catalog/pg_statistic.h"
                                 65                 : #include "catalog/pg_statistic_ext.h"
                                 66                 : #include "catalog/pg_statistic_ext_data.h"
                                 67                 : #include "catalog/pg_subscription.h"
                                 68                 : #include "catalog/pg_subscription_rel.h"
                                 69                 : #include "catalog/pg_tablespace.h"
                                 70                 : #include "catalog/pg_transform.h"
                                 71                 : #include "catalog/pg_ts_config.h"
                                 72                 : #include "catalog/pg_ts_config_map.h"
                                 73                 : #include "catalog/pg_ts_dict.h"
                                 74                 : #include "catalog/pg_ts_parser.h"
                                 75                 : #include "catalog/pg_ts_template.h"
                                 76                 : #include "catalog/pg_type.h"
                                 77                 : #include "catalog/pg_user_mapping.h"
                                 78                 : #include "lib/qunique.h"
                                 79                 : #include "utils/catcache.h"
                                 80                 : #include "utils/lsyscache.h"
                                 81                 : #include "utils/rel.h"
                                 82                 : #include "utils/syscache.h"
                                 83                 : 
                                 84                 : /*---------------------------------------------------------------------------
                                 85                 : 
                                 86                 :     Adding system caches:
                                 87                 : 
                                 88                 :     Add your new cache to the list in include/utils/syscache.h.
                                 89                 :     Keep the list sorted alphabetically.
                                 90                 : 
                                 91                 :     Add your entry to the cacheinfo[] array below. All cache lists are
                                 92                 :     alphabetical, so add it in the proper place.  Specify the relation OID,
                                 93                 :     index OID, number of keys, key attribute numbers, and initial number of
                                 94                 :     hash buckets.
                                 95                 : 
                                 96                 :     The number of hash buckets must be a power of 2.  It's reasonable to
                                 97                 :     set this to the number of entries that might be in the particular cache
                                 98                 :     in a medium-size database.
                                 99                 : 
                                100                 :     There must be a unique index underlying each syscache (ie, an index
                                101                 :     whose key is the same as that of the cache).  If there is not one
                                102                 :     already, add the definition for it to include/catalog/pg_*.h using
                                103                 :     DECLARE_UNIQUE_INDEX.
                                104                 :     (Adding an index requires a catversion.h update, while simply
                                105                 :     adding/deleting caches only requires a recompile.)
                                106                 : 
                                107                 :     Finally, any place your relation gets heap_insert() or
                                108                 :     heap_update() calls, use CatalogTupleInsert() or CatalogTupleUpdate()
                                109                 :     instead, which also update indexes.  The heap_* calls do not do that.
                                110                 : 
                                111                 : *---------------------------------------------------------------------------
                                112                 : */
                                113                 : 
                                114                 : /*
                                115                 :  *      struct cachedesc: information defining a single syscache
                                116                 :  */
                                117                 : struct cachedesc
                                118                 : {
                                119                 :     Oid         reloid;         /* OID of the relation being cached */
                                120                 :     Oid         indoid;         /* OID of index relation for this cache */
                                121                 :     int         nkeys;          /* # of keys needed for cache lookup */
                                122                 :     int         key[4];         /* attribute numbers of key attrs */
                                123                 :     int         nbuckets;       /* number of hash buckets for this cache */
                                124                 : };
                                125                 : 
                                126                 : /* Macro to provide nkeys and key array with convenient syntax. */
                                127                 : #define KEY(...) VA_ARGS_NARGS(__VA_ARGS__), { __VA_ARGS__ }
                                128                 : 
                                129                 : static const struct cachedesc cacheinfo[] = {
                                130                 :     [AGGFNOID] = {
                                131                 :         AggregateRelationId,
                                132                 :         AggregateFnoidIndexId,
                                133                 :         KEY(Anum_pg_aggregate_aggfnoid),
                                134                 :         16
                                135                 :     },
                                136                 :     [AMNAME] = {
                                137                 :         AccessMethodRelationId,
                                138                 :         AmNameIndexId,
                                139                 :         KEY(Anum_pg_am_amname),
                                140                 :         4
                                141                 :     },
                                142                 :     [AMOID] = {
                                143                 :         AccessMethodRelationId,
                                144                 :         AmOidIndexId,
                                145                 :         KEY(Anum_pg_am_oid),
                                146                 :         4
                                147                 :     },
                                148                 :     [AMOPOPID] = {
                                149                 :         AccessMethodOperatorRelationId,
                                150                 :         AccessMethodOperatorIndexId,
                                151                 :         KEY(Anum_pg_amop_amopopr,
                                152                 :             Anum_pg_amop_amoppurpose,
                                153                 :             Anum_pg_amop_amopfamily),
                                154                 :         64
                                155                 :     },
                                156                 :     [AMOPSTRATEGY] = {
                                157                 :         AccessMethodOperatorRelationId,
                                158                 :         AccessMethodStrategyIndexId,
                                159                 :         KEY(Anum_pg_amop_amopfamily,
                                160                 :             Anum_pg_amop_amoplefttype,
                                161                 :             Anum_pg_amop_amoprighttype,
                                162                 :             Anum_pg_amop_amopstrategy),
                                163                 :         64
                                164                 :     },
                                165                 :     [AMPROCNUM] = {
                                166                 :         AccessMethodProcedureRelationId,
                                167                 :         AccessMethodProcedureIndexId,
                                168                 :         KEY(Anum_pg_amproc_amprocfamily,
                                169                 :             Anum_pg_amproc_amproclefttype,
                                170                 :             Anum_pg_amproc_amprocrighttype,
                                171                 :             Anum_pg_amproc_amprocnum),
                                172                 :         16
                                173                 :     },
                                174                 :     [ATTNAME] = {
                                175                 :         AttributeRelationId,
                                176                 :         AttributeRelidNameIndexId,
                                177                 :         KEY(Anum_pg_attribute_attrelid,
                                178                 :             Anum_pg_attribute_attname),
                                179                 :         32
                                180                 :     },
                                181                 :     [ATTNUM] = {
                                182                 :         AttributeRelationId,
                                183                 :         AttributeRelidNumIndexId,
                                184                 :         KEY(Anum_pg_attribute_attrelid,
                                185                 :             Anum_pg_attribute_attnum),
                                186                 :         128
                                187                 :     },
                                188                 :     [AUTHMEMMEMROLE] = {
                                189                 :         AuthMemRelationId,
                                190                 :         AuthMemMemRoleIndexId,
                                191                 :         KEY(Anum_pg_auth_members_member,
                                192                 :             Anum_pg_auth_members_roleid,
                                193                 :             Anum_pg_auth_members_grantor),
                                194                 :         8
                                195                 :     },
                                196                 :     [AUTHMEMROLEMEM] = {
                                197                 :         AuthMemRelationId,
                                198                 :         AuthMemRoleMemIndexId,
                                199                 :         KEY(Anum_pg_auth_members_roleid,
                                200                 :             Anum_pg_auth_members_member,
                                201                 :             Anum_pg_auth_members_grantor),
                                202                 :         8
                                203                 :     },
                                204                 :     [AUTHNAME] = {
                                205                 :         AuthIdRelationId,
                                206                 :         AuthIdRolnameIndexId,
                                207                 :         KEY(Anum_pg_authid_rolname),
                                208                 :         8
                                209                 :     },
                                210                 :     [AUTHOID] = {
                                211                 :         AuthIdRelationId,
                                212                 :         AuthIdOidIndexId,
                                213                 :         KEY(Anum_pg_authid_oid),
                                214                 :         8
                                215                 :     },
                                216                 :     [CASTSOURCETARGET] = {
                                217                 :         CastRelationId,
                                218                 :         CastSourceTargetIndexId,
                                219                 :         KEY(Anum_pg_cast_castsource,
                                220                 :             Anum_pg_cast_casttarget),
                                221                 :         256
                                222                 :     },
                                223                 :     [CLAAMNAMENSP] = {
                                224                 :         OperatorClassRelationId,
                                225                 :         OpclassAmNameNspIndexId,
                                226                 :         KEY(Anum_pg_opclass_opcmethod,
                                227                 :             Anum_pg_opclass_opcname,
                                228                 :             Anum_pg_opclass_opcnamespace),
                                229                 :         8
                                230                 :     },
                                231                 :     [CLAOID] = {
                                232                 :         OperatorClassRelationId,
                                233                 :         OpclassOidIndexId,
                                234                 :         KEY(Anum_pg_opclass_oid),
                                235                 :         8
                                236                 :     },
                                237                 :     [COLLNAMEENCNSP] = {
                                238                 :         CollationRelationId,
                                239                 :         CollationNameEncNspIndexId,
                                240                 :         KEY(Anum_pg_collation_collname,
                                241                 :             Anum_pg_collation_collencoding,
                                242                 :             Anum_pg_collation_collnamespace),
                                243                 :         8
                                244                 :     },
                                245                 :     [COLLOID] = {
                                246                 :         CollationRelationId,
                                247                 :         CollationOidIndexId,
                                248                 :         KEY(Anum_pg_collation_oid),
                                249                 :         8
                                250                 :     },
                                251                 :     [CONDEFAULT] = {
                                252                 :         ConversionRelationId,
                                253                 :         ConversionDefaultIndexId,
                                254                 :         KEY(Anum_pg_conversion_connamespace,
                                255                 :             Anum_pg_conversion_conforencoding,
                                256                 :             Anum_pg_conversion_contoencoding,
                                257                 :             Anum_pg_conversion_oid),
                                258                 :         8
                                259                 :     },
                                260                 :     [CONNAMENSP] = {
                                261                 :         ConversionRelationId,
                                262                 :         ConversionNameNspIndexId,
                                263                 :         KEY(Anum_pg_conversion_conname,
                                264                 :             Anum_pg_conversion_connamespace),
                                265                 :         8
                                266                 :     },
                                267                 :     [CONSTROID] = {
                                268                 :         ConstraintRelationId,
                                269                 :         ConstraintOidIndexId,
                                270                 :         KEY(Anum_pg_constraint_oid),
                                271                 :         16
                                272                 :     },
                                273                 :     [CONVOID] = {
                                274                 :         ConversionRelationId,
                                275                 :         ConversionOidIndexId,
                                276                 :         KEY(Anum_pg_conversion_oid),
                                277                 :         8
                                278                 :     },
                                279                 :     [DATABASEOID] = {
                                280                 :         DatabaseRelationId,
                                281                 :         DatabaseOidIndexId,
                                282                 :         KEY(Anum_pg_database_oid),
                                283                 :         4
                                284                 :     },
                                285                 :     [DEFACLROLENSPOBJ] = {
                                286                 :         DefaultAclRelationId,
                                287                 :         DefaultAclRoleNspObjIndexId,
                                288                 :         KEY(Anum_pg_default_acl_defaclrole,
                                289                 :             Anum_pg_default_acl_defaclnamespace,
                                290                 :             Anum_pg_default_acl_defaclobjtype),
                                291                 :         8
                                292                 :     },
                                293                 :     [ENUMOID] = {
                                294                 :         EnumRelationId,
                                295                 :         EnumOidIndexId,
                                296                 :         KEY(Anum_pg_enum_oid),
                                297                 :         8
                                298                 :     },
                                299                 :     [ENUMTYPOIDNAME] = {
                                300                 :         EnumRelationId,
                                301                 :         EnumTypIdLabelIndexId,
                                302                 :         KEY(Anum_pg_enum_enumtypid,
                                303                 :             Anum_pg_enum_enumlabel),
                                304                 :         8
                                305                 :     },
                                306                 :     [EVENTTRIGGERNAME] = {
                                307                 :         EventTriggerRelationId,
                                308                 :         EventTriggerNameIndexId,
                                309                 :         KEY(Anum_pg_event_trigger_evtname),
                                310                 :         8
                                311                 :     },
                                312                 :     [EVENTTRIGGEROID] = {
                                313                 :         EventTriggerRelationId,
                                314                 :         EventTriggerOidIndexId,
                                315                 :         KEY(Anum_pg_event_trigger_oid),
                                316                 :         8
                                317                 :     },
                                318                 :     [FOREIGNDATAWRAPPERNAME] = {
                                319                 :         ForeignDataWrapperRelationId,
                                320                 :         ForeignDataWrapperNameIndexId,
                                321                 :         KEY(Anum_pg_foreign_data_wrapper_fdwname),
                                322                 :         2
                                323                 :     },
                                324                 :     [FOREIGNDATAWRAPPEROID] = {
                                325                 :         ForeignDataWrapperRelationId,
                                326                 :         ForeignDataWrapperOidIndexId,
                                327                 :         KEY(Anum_pg_foreign_data_wrapper_oid),
                                328                 :         2
                                329                 :     },
                                330                 :     [FOREIGNSERVERNAME] = {
                                331                 :         ForeignServerRelationId,
                                332                 :         ForeignServerNameIndexId,
                                333                 :         KEY(Anum_pg_foreign_server_srvname),
                                334                 :         2
                                335                 :     },
                                336                 :     [FOREIGNSERVEROID] = {
                                337                 :         ForeignServerRelationId,
                                338                 :         ForeignServerOidIndexId,
                                339                 :         KEY(Anum_pg_foreign_server_oid),
                                340                 :         2
                                341                 :     },
                                342                 :     [FOREIGNTABLEREL] = {
                                343                 :         ForeignTableRelationId,
                                344                 :         ForeignTableRelidIndexId,
                                345                 :         KEY(Anum_pg_foreign_table_ftrelid),
                                346                 :         4
                                347                 :     },
                                348                 :     [INDEXRELID] = {
                                349                 :         IndexRelationId,
                                350                 :         IndexRelidIndexId,
                                351                 :         KEY(Anum_pg_index_indexrelid),
                                352                 :         64
                                353                 :     },
                                354                 :     [LANGNAME] = {
                                355                 :         LanguageRelationId,
                                356                 :         LanguageNameIndexId,
                                357                 :         KEY(Anum_pg_language_lanname),
                                358                 :         4
                                359                 :     },
                                360                 :     [LANGOID] = {
                                361                 :         LanguageRelationId,
                                362                 :         LanguageOidIndexId,
                                363                 :         KEY(Anum_pg_language_oid),
                                364                 :         4
                                365                 :     },
                                366                 :     [NAMESPACENAME] = {
                                367                 :         NamespaceRelationId,
                                368                 :         NamespaceNameIndexId,
                                369                 :         KEY(Anum_pg_namespace_nspname),
                                370                 :         4
                                371                 :     },
                                372                 :     [NAMESPACEOID] = {
                                373                 :         NamespaceRelationId,
                                374                 :         NamespaceOidIndexId,
                                375                 :         KEY(Anum_pg_namespace_oid),
                                376                 :         16
                                377                 :     },
                                378                 :     [OPERNAMENSP] = {
                                379                 :         OperatorRelationId,
                                380                 :         OperatorNameNspIndexId,
                                381                 :         KEY(Anum_pg_operator_oprname,
                                382                 :             Anum_pg_operator_oprleft,
                                383                 :             Anum_pg_operator_oprright,
                                384                 :             Anum_pg_operator_oprnamespace),
                                385                 :         256
                                386                 :     },
                                387                 :     [OPEROID] = {
                                388                 :         OperatorRelationId,
                                389                 :         OperatorOidIndexId,
                                390                 :         KEY(Anum_pg_operator_oid),
                                391                 :         32
                                392                 :     },
                                393                 :     [OPFAMILYAMNAMENSP] = {
                                394                 :         OperatorFamilyRelationId,
                                395                 :         OpfamilyAmNameNspIndexId,
                                396                 :         KEY(Anum_pg_opfamily_opfmethod,
                                397                 :             Anum_pg_opfamily_opfname,
                                398                 :             Anum_pg_opfamily_opfnamespace),
                                399                 :         8
                                400                 :     },
                                401                 :     [OPFAMILYOID] = {
                                402                 :         OperatorFamilyRelationId,
                                403                 :         OpfamilyOidIndexId,
                                404                 :         KEY(Anum_pg_opfamily_oid),
                                405                 :         8
                                406                 :     },
                                407                 :     [PARAMETERACLNAME] = {
                                408                 :         ParameterAclRelationId,
                                409                 :         ParameterAclParnameIndexId,
                                410                 :         KEY(Anum_pg_parameter_acl_parname),
                                411                 :         4
                                412                 :     },
                                413                 :     [PARAMETERACLOID] = {
                                414                 :         ParameterAclRelationId,
                                415                 :         ParameterAclOidIndexId,
                                416                 :         KEY(Anum_pg_parameter_acl_oid),
                                417                 :         4
                                418                 :     },
                                419                 :     [PARTRELID] = {
                                420                 :         PartitionedRelationId,
                                421                 :         PartitionedRelidIndexId,
                                422                 :         KEY(Anum_pg_partitioned_table_partrelid),
                                423                 :         32
                                424                 :     },
                                425                 :     [PROCNAMEARGSNSP] = {
                                426                 :         ProcedureRelationId,
                                427                 :         ProcedureNameArgsNspIndexId,
                                428                 :         KEY(Anum_pg_proc_proname,
                                429                 :             Anum_pg_proc_proargtypes,
                                430                 :             Anum_pg_proc_pronamespace),
                                431                 :         128
                                432                 :     },
                                433                 :     [PROCOID] = {
                                434                 :         ProcedureRelationId,
                                435                 :         ProcedureOidIndexId,
                                436                 :         KEY(Anum_pg_proc_oid),
                                437                 :         128
                                438                 :     },
                                439                 :     [PUBLICATIONNAME] = {
                                440                 :         PublicationRelationId,
                                441                 :         PublicationNameIndexId,
                                442                 :         KEY(Anum_pg_publication_pubname),
                                443                 :         8
                                444                 :     },
                                445                 :     [PUBLICATIONNAMESPACE] = {
                                446                 :         PublicationNamespaceRelationId,
                                447                 :         PublicationNamespaceObjectIndexId,
                                448                 :         KEY(Anum_pg_publication_namespace_oid),
                                449                 :         64
                                450                 :     },
                                451                 :     [PUBLICATIONNAMESPACEMAP] = {
                                452                 :         PublicationNamespaceRelationId,
                                453                 :         PublicationNamespacePnnspidPnpubidIndexId,
                                454                 :         KEY(Anum_pg_publication_namespace_pnnspid,
                                455                 :             Anum_pg_publication_namespace_pnpubid),
                                456                 :         64
                                457                 :     },
                                458                 :     [PUBLICATIONOID] = {
                                459                 :         PublicationRelationId,
                                460                 :         PublicationObjectIndexId,
                                461                 :         KEY(Anum_pg_publication_oid),
                                462                 :         8
                                463                 :     },
                                464                 :     [PUBLICATIONREL] = {
                                465                 :         PublicationRelRelationId,
                                466                 :         PublicationRelObjectIndexId,
                                467                 :         KEY(Anum_pg_publication_rel_oid),
                                468                 :         64
                                469                 :     },
                                470                 :     [PUBLICATIONRELMAP] = {
                                471                 :         PublicationRelRelationId,
                                472                 :         PublicationRelPrrelidPrpubidIndexId,
                                473                 :         KEY(Anum_pg_publication_rel_prrelid,
                                474                 :             Anum_pg_publication_rel_prpubid),
                                475                 :         64
                                476                 :     },
                                477                 :     [RANGEMULTIRANGE] = {
                                478                 :         RangeRelationId,
                                479                 :         RangeMultirangeTypidIndexId,
                                480                 :         KEY(Anum_pg_range_rngmultitypid),
                                481                 :         4
  840 akorotkov                 482 ECB             :     },
                                483                 :     [RANGETYPE] = {
                                484                 :         RangeRelationId,
                                485                 :         RangeTypidIndexId,
                                486                 :         KEY(Anum_pg_range_rngtypid),
                                487                 :         4
                                488                 :     },
                                489                 :     [RELNAMENSP] = {
                                490                 :         RelationRelationId,
 2140 tgl                       491                 :         ClassNameNspIndexId,
                                492                 :         KEY(Anum_pg_class_relname,
                                493                 :             Anum_pg_class_relnamespace),
                                494                 :         128
 2271 peter_e                   495 EUB             :     },
                                496                 :     [RELOID] = {
                                497                 :         RelationRelationId,
                                498                 :         ClassOidIndexId,
                                499                 :         KEY(Anum_pg_class_oid),
 2140 tgl                       500 ECB             :         128
                                501                 :     },
                                502                 :     [REPLORIGIDENT] = {
                                503                 :         ReplicationOriginRelationId,
                                504                 :         ReplicationOriginIdentIndex,
                                505                 :         KEY(Anum_pg_replication_origin_roident),
                                506                 :         16
                                507                 :     },
                                508                 :     [REPLORIGNAME] = {
                                509                 :         ReplicationOriginRelationId,
                                510                 :         ReplicationOriginNameIndex,
                                511                 :         KEY(Anum_pg_replication_origin_roname),
                                512                 :         16
                                513                 :     },
                                514                 :     [RULERELNAME] = {
                                515                 :         RewriteRelationId,
                                516                 :         RewriteRelRulenameIndexId,
                                517                 :         KEY(Anum_pg_rewrite_ev_class,
                                518                 :             Anum_pg_rewrite_rulename),
                                519                 :         8
                                520                 :     },
                                521                 :     [SEQRELID] = {
                                522                 :         SequenceRelationId,
                                523                 :         SequenceRelidIndexId,
                                524                 :         KEY(Anum_pg_sequence_seqrelid),
                                525                 :         32
                                526                 :     },
                                527                 :     [STATEXTDATASTXOID] = {
                                528                 :         StatisticExtDataRelationId,
                                529                 :         StatisticExtDataStxoidInhIndexId,
                                530                 :         KEY(Anum_pg_statistic_ext_data_stxoid,
                                531                 :             Anum_pg_statistic_ext_data_stxdinherit),
                                532                 :         4
                                533                 :     },
                                534                 :     [STATEXTNAMENSP] = {
                                535                 :         StatisticExtRelationId,
                                536                 :         StatisticExtNameIndexId,
                                537                 :         KEY(Anum_pg_statistic_ext_stxname,
                                538                 :             Anum_pg_statistic_ext_stxnamespace),
                                539                 :         4
                                540                 :     },
                                541                 :     [STATEXTOID] = {
                                542                 :         StatisticExtRelationId,
 2207 alvherre                  543                 :         StatisticExtOidIndexId,
                                544                 :         KEY(Anum_pg_statistic_ext_oid),
                                545                 :         4
                                546                 :     },
                                547                 :     [STATRELATTINH] = {
                                548                 :         StatisticRelationId,
                                549                 :         StatisticRelidAttnumInhIndexId,
                                550                 :         KEY(Anum_pg_statistic_starelid,
                                551                 :             Anum_pg_statistic_staattnum,
                                552                 :             Anum_pg_statistic_stainherit),
                                553                 :         128
                                554                 :     },
                                555                 :     [SUBSCRIPTIONNAME] = {
                                556                 :         SubscriptionRelationId,
                                557                 :         SubscriptionNameIndexId,
                                558                 :         KEY(Anum_pg_subscription_subdbid,
                                559                 :             Anum_pg_subscription_subname),
                                560                 :         4
                                561                 :     },
                                562                 :     [SUBSCRIPTIONOID] = {
                                563                 :         SubscriptionRelationId,
                                564                 :         SubscriptionObjectIndexId,
                                565                 :         KEY(Anum_pg_subscription_oid),
                                566                 :         4
                                567                 :     },
                                568                 :     [SUBSCRIPTIONRELMAP] = {
                                569                 :         SubscriptionRelRelationId,
                                570                 :         SubscriptionRelSrrelidSrsubidIndexId,
                                571                 :         KEY(Anum_pg_subscription_rel_srrelid,
                                572                 :             Anum_pg_subscription_rel_srsubid),
                                573                 :         64
                                574                 :     },
                                575                 :     [TABLESPACEOID] = {
                                576                 :         TableSpaceRelationId,
 4842 rhaas                     577                 :         TablespaceOidIndexId,
                                578                 :         KEY(Anum_pg_tablespace_oid),
                                579                 :         4
                                580                 :     },
                                581                 :     [TRFOID] = {
                                582                 :         TransformRelationId,
                                583                 :         TransformOidIndexId,
                                584                 :         KEY(Anum_pg_transform_oid),
                                585                 :         16
                                586                 :     },
                                587                 :     [TRFTYPELANG] = {
                                588                 :         TransformRelationId,
                                589                 :         TransformTypeLangIndexId,
                                590                 :         KEY(Anum_pg_transform_trftype,
                                591                 :             Anum_pg_transform_trflang),
                                592                 :         16
                                593                 :     },
                                594                 :     [TSCONFIGMAP] = {
                                595                 :         TSConfigMapRelationId,
                                596                 :         TSConfigMapIndexId,
                                597                 :         KEY(Anum_pg_ts_config_map_mapcfg,
                                598                 :             Anum_pg_ts_config_map_maptokentype,
                                599                 :             Anum_pg_ts_config_map_mapseqno),
                                600                 :         2
                                601                 :     },
                                602                 :     [TSCONFIGNAMENSP] = {
                                603                 :         TSConfigRelationId,
                                604                 :         TSConfigNameNspIndexId,
                                605                 :         KEY(Anum_pg_ts_config_cfgname,
                                606                 :             Anum_pg_ts_config_cfgnamespace),
                                607                 :         2
                                608                 :     },
                                609                 :     [TSCONFIGOID] = {
                                610                 :         TSConfigRelationId,
                                611                 :         TSConfigOidIndexId,
                                612                 :         KEY(Anum_pg_ts_config_oid),
                                613                 :         2
                                614                 :     },
                                615                 :     [TSDICTNAMENSP] = {
                                616                 :         TSDictionaryRelationId,
                                617                 :         TSDictionaryNameNspIndexId,
                                618                 :         KEY(Anum_pg_ts_dict_dictname,
                                619                 :             Anum_pg_ts_dict_dictnamespace),
 3503 heikki.linnakangas        620                 :         2
 5710 tgl                       621                 :     },
                                622                 :     [TSDICTOID] = {
                                623                 :         TSDictionaryRelationId,
                                624                 :         TSDictionaryOidIndexId,
                                625                 :         KEY(Anum_pg_ts_dict_oid),
                                626                 :         2
                                627                 :     },
                                628                 :     [TSPARSERNAMENSP] = {
                                629                 :         TSParserRelationId,
                                630                 :         TSParserNameNspIndexId,
                                631                 :         KEY(Anum_pg_ts_parser_prsname,
                                632                 :             Anum_pg_ts_parser_prsnamespace),
                                633                 :         2
                                634                 :     },
                                635                 :     [TSPARSEROID] = {
                                636                 :         TSParserRelationId,
                                637                 :         TSParserOidIndexId,
                                638                 :         KEY(Anum_pg_ts_parser_oid),
 3503 heikki.linnakangas        639                 :         2
                                640                 :     },
                                641                 :     [TSTEMPLATENAMENSP] = {
                                642                 :         TSTemplateRelationId,
                                643                 :         TSTemplateNameNspIndexId,
                                644                 :         KEY(Anum_pg_ts_template_tmplname,
                                645                 :             Anum_pg_ts_template_tmplnamespace),
                                646                 :         2
                                647                 :     },
                                648                 :     [TSTEMPLATEOID] = {
                                649                 :         TSTemplateRelationId,
 5710 tgl                       650                 :         TSTemplateOidIndexId,
                                651                 :         KEY(Anum_pg_ts_template_oid),
                                652                 :         2
                                653                 :     },
                                654                 :     [TYPENAMENSP] = {
                                655                 :         TypeRelationId,
                                656                 :         TypeNameNspIndexId,
                                657                 :         KEY(Anum_pg_type_typname,
                                658                 :             Anum_pg_type_typnamespace),
 3503 heikki.linnakangas        659                 :         64
 6142 tgl                       660                 :     },
                                661                 :     [TYPEOID] = {
                                662                 :         TypeRelationId,
 6569                           663                 :         TypeOidIndexId,
                                664                 :         KEY(Anum_pg_type_oid),
                                665                 :         64
                                666                 :     },
                                667                 :     [USERMAPPINGOID] = {
                                668                 :         UserMappingRelationId,
                                669                 :         UserMappingOidIndexId,
                                670                 :         KEY(Anum_pg_user_mapping_oid),
                                671                 :         2
 5224 peter_e                   672                 :     },
                                673                 :     [USERMAPPINGUSERSERVER] = {
                                674                 :         UserMappingRelationId,
                                675                 :         UserMappingUserServerIndexId,
                                676                 :         KEY(Anum_pg_user_mapping_umuser,
                                677                 :             Anum_pg_user_mapping_umserver),
                                678                 :         2
                                679                 :     }
                                680                 : };
                                681                 : 
                                682                 : StaticAssertDecl(lengthof(cacheinfo) == SysCacheSize,
                                683                 :                  "SysCacheSize does not match syscache.c's array");
                                684                 : 
                                685                 : static CatCache *SysCache[SysCacheSize];
                                686                 : 
 8397 bruce                     687                 : static bool CacheInitialized = false;
                                688                 : 
                                689                 : /* Sorted array of OIDs of tables that have caches on them */
                                690                 : static Oid  SysCacheRelationOid[SysCacheSize];
                                691                 : static int  SysCacheRelationOidSize;
 3568 rhaas                     692                 : 
 2863 tgl                       693                 : /* Sorted array of OIDs of tables and indexes used by caches */
                                694                 : static Oid  SysCacheSupportingRelOid[SysCacheSize * 2];
                                695                 : static int  SysCacheSupportingRelOidSize;
                                696                 : 
 3260 bruce                     697                 : static int  oid_compare(const void *a, const void *b);
                                698                 : 
                                699                 : 
                                700                 : /*
                                701                 :  * InitCatalogCache - initialize the caches
                                702                 :  *
                                703                 :  * Note that no database access is done here; we only allocate memory
                                704                 :  * and initialize the cache structure.  Interrogation of the database
                                705                 :  * to complete initialization of a cache happens upon first use
                                706                 :  * of that cache.
                                707                 :  */
                                708                 : void
 8179 tgl                       709 GIC       11570 : InitCatalogCache(void)
                                710                 : {
                                711                 :     int         cacheId;
                                712                 : 
                                713           11570 :     Assert(!CacheInitialized);
                                714                 : 
 2863                           715           11570 :     SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0;
                                716                 : 
 8179                           717          971880 :     for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
 9345 bruce                     718 ECB             :     {
                                719                 :         /*
                                720                 :          * Assert that every enumeration value defined in syscache.h has been
                                721                 :          * populated in the cacheinfo array.
                                722                 :          */
  107 tmunro                    723 GNC      960310 :         Assert(cacheinfo[cacheId].reloid != 0);
                                724                 : 
 8179 tgl                       725 GIC     1920620 :         SysCache[cacheId] = InitCatCache(cacheId,
 6569                           726          960310 :                                          cacheinfo[cacheId].reloid,
                                727          960310 :                                          cacheinfo[cacheId].indoid,
 8179                           728          960310 :                                          cacheinfo[cacheId].nkeys,
 6142                           729          960310 :                                          cacheinfo[cacheId].key,
                                730          960310 :                                          cacheinfo[cacheId].nbuckets);
 8179                           731          960310 :         if (!PointerIsValid(SysCache[cacheId]))
 6569 tgl                       732 UIC           0 :             elog(ERROR, "could not initialize cache %u (%d)",
                                733                 :                  cacheinfo[cacheId].reloid, cacheId);
 2863 tgl                       734 ECB             :         /* Accumulate data for OID lists, too */
 3568 rhaas                     735 CBC      960310 :         SysCacheRelationOid[SysCacheRelationOidSize++] =
 3568 rhaas                     736 GBC      960310 :             cacheinfo[cacheId].reloid;
 2863 tgl                       737 CBC      960310 :         SysCacheSupportingRelOid[SysCacheSupportingRelOidSize++] =
 2863 tgl                       738 GIC      960310 :             cacheinfo[cacheId].reloid;
 2863 tgl                       739 CBC      960310 :         SysCacheSupportingRelOid[SysCacheSupportingRelOidSize++] =
                                740          960310 :             cacheinfo[cacheId].indoid;
                                741                 :         /* see comments for RelationInvalidatesSnapshotsOnly */
 3568 rhaas                     742 GIC      960310 :         Assert(!RelationInvalidatesSnapshotsOnly(cacheinfo[cacheId].reloid));
 9770 scrappy                   743 ECB             :     }
 3568 rhaas                     744                 : 
 2863 tgl                       745 GIC       11570 :     Assert(SysCacheRelationOidSize <= lengthof(SysCacheRelationOid));
                                746           11570 :     Assert(SysCacheSupportingRelOidSize <= lengthof(SysCacheSupportingRelOid));
                                747                 : 
                                748                 :     /* Sort and de-dup OID arrays, so we can use binary search. */
 3568 rhaas                     749           11570 :     pg_qsort(SysCacheRelationOid, SysCacheRelationOidSize,
                                750                 :              sizeof(Oid), oid_compare);
 1249 tmunro                    751           11570 :     SysCacheRelationOidSize =
                                752           11570 :         qunique(SysCacheRelationOid, SysCacheRelationOidSize, sizeof(Oid),
                                753                 :                 oid_compare);
                                754                 : 
 2863 tgl                       755 CBC       11570 :     pg_qsort(SysCacheSupportingRelOid, SysCacheSupportingRelOidSize,
                                756                 :              sizeof(Oid), oid_compare);
 1249 tmunro                    757 GIC       11570 :     SysCacheSupportingRelOidSize =
                                758           11570 :         qunique(SysCacheSupportingRelOid, SysCacheSupportingRelOidSize,
                                759                 :                 sizeof(Oid), oid_compare);
                                760                 : 
 8451 inoue                     761 CBC       11570 :     CacheInitialized = true;
 9770 scrappy                   762 GIC       11570 : }
 8986 bruce                     763 ECB             : 
                                764                 : /*
 7719 tgl                       765 EUB             :  * InitCatalogCachePhase2 - finish initializing the caches
                                766                 :  *
                                767                 :  * Finish initializing all the caches, including necessary database
                                768                 :  * access.
                                769                 :  *
                                770                 :  * This is *not* essential; normally we allow syscaches to be initialized
 7719 tgl                       771 ECB             :  * on first use.  However, it is useful as a mechanism to preload the
                                772                 :  * relcache with entries for the most-commonly-used system catalogs.
                                773                 :  * Therefore, we invoke this routine when we need to write a new relcache
                                774                 :  * init file.
                                775                 :  */
                                776                 : void
 7719 tgl                       777 GIC        1227 : InitCatalogCachePhase2(void)
                                778                 : {
                                779                 :     int         cacheId;
                                780                 : 
                                781            1227 :     Assert(CacheInitialized);
                                782                 : 
                                783          103030 :     for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
 6029                           784          101805 :         InitCatCachePhase2(SysCache[cacheId], true);
 7719 tgl                       785 CBC        1225 : }
                                786                 : 
                                787                 : 
                                788                 : /*
                                789                 :  * SearchSysCache
                                790                 :  *
 8179 tgl                       791 ECB             :  *  A layer on top of SearchCatCache that does the initialization and
 8999 bruce                     792                 :  *  key-setting for you.
 9770 scrappy                   793 EUB             :  *
                                794                 :  *  Returns the cache copy of the tuple if one is found, NULL if not.
 8179 tgl                       795 ECB             :  *  The tuple is the 'cache' copy and must NOT be modified!
                                796                 :  *
                                797                 :  *  When the caller is done using the tuple, call ReleaseSysCache()
                                798                 :  *  to release the reference count grabbed by SearchSysCache().  If this
                                799                 :  *  is not done, the tuple will remain locked in cache until end of
                                800                 :  *  transaction, which is tolerable but not desirable.
                                801                 :  *
                                802                 :  *  CAUTION: The tuple that is returned must NOT be freed by the caller!
                                803                 :  */
                                804                 : HeapTuple
 8179 tgl                       805 CBC     4845939 : SearchSysCache(int cacheId,
 8179 tgl                       806 ECB             :                Datum key1,
 8179 tgl                       807 EUB             :                Datum key2,
                                808                 :                Datum key3,
 8179 tgl                       809 ECB             :                Datum key4)
                                810                 : {
 2004 andres                    811 GIC     4845939 :     Assert(cacheId >= 0 && cacheId < SysCacheSize &&
                                812                 :            PointerIsValid(SysCache[cacheId]));
                                813                 : 
 8179 tgl                       814         4845939 :     return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
                                815                 : }
                                816                 : 
                                817                 : HeapTuple
 2004 andres                    818        40450452 : SearchSysCache1(int cacheId,
                                819                 :                 Datum key1)
                                820                 : {
                                821        40450452 :     Assert(cacheId >= 0 && cacheId < SysCacheSize &&
 2004 andres                    822 ECB             :            PointerIsValid(SysCache[cacheId]));
 2004 andres                    823 GIC    40450452 :     Assert(SysCache[cacheId]->cc_nkeys == 1);
 2004 andres                    824 ECB             : 
 2004 andres                    825 GBC    40450452 :     return SearchCatCache1(SysCache[cacheId], key1);
                                826                 : }
                                827                 : 
 2004 andres                    828 ECB             : HeapTuple
 2004 andres                    829 GBC     4345637 : SearchSysCache2(int cacheId,
                                830                 :                 Datum key1, Datum key2)
 2004 andres                    831 ECB             : {
 2004 andres                    832 GIC     4345637 :     Assert(cacheId >= 0 && cacheId < SysCacheSize &&
                                833                 :            PointerIsValid(SysCache[cacheId]));
                                834         4345637 :     Assert(SysCache[cacheId]->cc_nkeys == 2);
                                835                 : 
                                836         4345637 :     return SearchCatCache2(SysCache[cacheId], key1, key2);
                                837                 : }
                                838                 : 
                                839                 : HeapTuple
                                840         2148760 : SearchSysCache3(int cacheId,
                                841                 :                 Datum key1, Datum key2, Datum key3)
                                842                 : {
                                843         2148760 :     Assert(cacheId >= 0 && cacheId < SysCacheSize &&
                                844                 :            PointerIsValid(SysCache[cacheId]));
                                845         2148760 :     Assert(SysCache[cacheId]->cc_nkeys == 3);
 2004 andres                    846 ECB             : 
 2004 andres                    847 GIC     2148760 :     return SearchCatCache3(SysCache[cacheId], key1, key2, key3);
 2004 andres                    848 ECB             : }
                                849                 : 
                                850                 : HeapTuple
 2004 andres                    851 GIC     1886317 : SearchSysCache4(int cacheId,
                                852                 :                 Datum key1, Datum key2, Datum key3, Datum key4)
                                853                 : {
                                854         1886317 :     Assert(cacheId >= 0 && cacheId < SysCacheSize &&
                                855                 :            PointerIsValid(SysCache[cacheId]));
                                856         1886317 :     Assert(SysCache[cacheId]->cc_nkeys == 4);
 2004 andres                    857 ECB             : 
 2004 andres                    858 CBC     1886317 :     return SearchCatCache4(SysCache[cacheId], key1, key2, key3, key4);
 2004 andres                    859 ECB             : }
                                860                 : 
                                861                 : /*
 8179 tgl                       862                 :  * ReleaseSysCache
                                863                 :  *      Release previously grabbed reference count on a tuple
                                864                 :  */
                                865                 : void
 8179 tgl                       866 GIC    48077091 : ReleaseSysCache(HeapTuple tuple)
                                867                 : {
                                868        48077091 :     ReleaseCatCache(tuple);
 8179 tgl                       869 CBC    48077091 : }
                                870                 : 
 8331 tgl                       871 ECB             : /*
 8179                           872                 :  * SearchSysCacheCopy
                                873                 :  *
                                874                 :  * A convenience routine that does SearchSysCache and (if successful)
                                875                 :  * returns a modifiable copy of the syscache entry.  The original
                                876                 :  * syscache entry is released before returning.  The caller should
                                877                 :  * heap_freetuple() the result when done with it.
 8331                           878                 :  */
                                879                 : HeapTuple
 8179 tgl                       880 CBC      633804 : SearchSysCacheCopy(int cacheId,
 8179 tgl                       881 ECB             :                    Datum key1,
                                882                 :                    Datum key2,
                                883                 :                    Datum key3,
                                884                 :                    Datum key4)
                                885                 : {
                                886                 :     HeapTuple   tuple,
                                887                 :                 newtuple;
                                888                 : 
 8179 tgl                       889 GIC      633804 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
                                890          633804 :     if (!HeapTupleIsValid(tuple))
                                891          166941 :         return tuple;
                                892          466863 :     newtuple = heap_copytuple(tuple);
                                893          466863 :     ReleaseSysCache(tuple);
 8179 tgl                       894 CBC      466863 :     return newtuple;
                                895                 : }
 8331 tgl                       896 ECB             : 
 7912                           897                 : /*
                                898                 :  * SearchSysCacheExists
                                899                 :  *
                                900                 :  * A convenience routine that just probes to see if a tuple can be found.
                                901                 :  * No lock is retained on the syscache entry.
                                902                 :  */
                                903                 : bool
 7912 tgl                       904 CBC      612586 : SearchSysCacheExists(int cacheId,
 7912 tgl                       905 ECB             :                      Datum key1,
                                906                 :                      Datum key2,
                                907                 :                      Datum key3,
                                908                 :                      Datum key4)
                                909                 : {
                                910                 :     HeapTuple   tuple;
                                911                 : 
 7912 tgl                       912 GIC      612586 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
                                913          612586 :     if (!HeapTupleIsValid(tuple))
                                914          144909 :         return false;
                                915          467677 :     ReleaseSysCache(tuple);
                                916          467677 :     return true;
                                917                 : }
                                918                 : 
 8179 tgl                       919 ECB             : /*
                                920                 :  * GetSysCacheOid
                                921                 :  *
 1601 andres                    922                 :  * A convenience routine that does SearchSysCache and returns the OID in the
                                923                 :  * oidcol column of the found tuple, or InvalidOid if no tuple could be found.
 8179 tgl                       924                 :  * No lock is retained on the syscache entry.
                                925                 :  */
                                926                 : Oid
 8179 tgl                       927 GIC     3599549 : GetSysCacheOid(int cacheId,
                                928                 :                AttrNumber oidcol,
                                929                 :                Datum key1,
                                930                 :                Datum key2,
                                931                 :                Datum key3,
                                932                 :                Datum key4)
                                933                 : {
                                934                 :     HeapTuple   tuple;
                                935                 :     bool        isNull;
                                936                 :     Oid         result;
                                937                 : 
                                938         3599549 :     tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
                                939         3599549 :     if (!HeapTupleIsValid(tuple))
                                940         1949762 :         return InvalidOid;
 1601 andres                    941         3299574 :     result = heap_getattr(tuple, oidcol,
                                942         1649787 :                           SysCache[cacheId]->cc_tupdesc,
                                943                 :                           &isNull);
 1418 tgl                       944         1649787 :     Assert(!isNull);            /* columns used as oids should never be NULL */
 8179                           945         1649787 :     ReleaseSysCache(tuple);
                                946         1649787 :     return result;
                                947                 : }
                                948                 : 
                                949                 : 
                                950                 : /*
                                951                 :  * SearchSysCacheAttName
                                952                 :  *
                                953                 :  * This routine is equivalent to SearchSysCache on the ATTNAME cache,
                                954                 :  * except that it will return NULL if the found attribute is marked
                                955                 :  * attisdropped.  This is convenient for callers that want to act as
                                956                 :  * though dropped attributes don't exist.
                                957                 :  */
                                958                 : HeapTuple
 7555                           959          125667 : SearchSysCacheAttName(Oid relid, const char *attname)
                                960                 : {
                                961                 :     HeapTuple   tuple;
                                962                 : 
 4802 rhaas                     963          125667 :     tuple = SearchSysCache2(ATTNAME,
                                964                 :                             ObjectIdGetDatum(relid),
                                965                 :                             CStringGetDatum(attname));
 7555 tgl                       966          125667 :     if (!HeapTupleIsValid(tuple))
                                967             413 :         return NULL;
                                968          125254 :     if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
                                969                 :     {
                                970              39 :         ReleaseSysCache(tuple);
                                971              39 :         return NULL;
                                972                 :     }
                                973          125215 :     return tuple;
                                974                 : }
                                975                 : 
                                976                 : /*
                                977                 :  * SearchSysCacheCopyAttName
                                978                 :  *
                                979                 :  * As above, an attisdropped-aware version of SearchSysCacheCopy.
                                980                 :  */
                                981                 : HeapTuple
                                982            4056 : SearchSysCacheCopyAttName(Oid relid, const char *attname)
                                983                 : {
                                984                 :     HeapTuple   tuple,
                                985                 :                 newtuple;
                                986                 : 
                                987            4056 :     tuple = SearchSysCacheAttName(relid, attname);
                                988            4056 :     if (!HeapTupleIsValid(tuple))
                                989             318 :         return tuple;
                                990            3738 :     newtuple = heap_copytuple(tuple);
                                991            3738 :     ReleaseSysCache(tuple);
                                992            3738 :     return newtuple;
                                993                 : }
                                994                 : 
                                995                 : /*
                                996                 :  * SearchSysCacheExistsAttName
                                997                 :  *
                                998                 :  * As above, an attisdropped-aware version of SearchSysCacheExists.
                                999                 :  */
                               1000                 : bool
                               1001             399 : SearchSysCacheExistsAttName(Oid relid, const char *attname)
                               1002                 : {
                               1003                 :     HeapTuple   tuple;
                               1004                 : 
                               1005             399 :     tuple = SearchSysCacheAttName(relid, attname);
                               1006             399 :     if (!HeapTupleIsValid(tuple))
                               1007               6 :         return false;
                               1008             393 :     ReleaseSysCache(tuple);
                               1009             393 :     return true;
                               1010                 : }
                               1011                 : 
                               1012                 : 
                               1013                 : /*
                               1014                 :  * SearchSysCacheAttNum
                               1015                 :  *
                               1016                 :  * This routine is equivalent to SearchSysCache on the ATTNUM cache,
                               1017                 :  * except that it will return NULL if the found attribute is marked
                               1018                 :  * attisdropped.  This is convenient for callers that want to act as
                               1019                 :  * though dropped attributes don't exist.
                               1020                 :  */
                               1021                 : HeapTuple
 2041 simon                    1022           32403 : SearchSysCacheAttNum(Oid relid, int16 attnum)
                               1023                 : {
                               1024                 :     HeapTuple   tuple;
                               1025                 : 
                               1026           32403 :     tuple = SearchSysCache2(ATTNUM,
                               1027                 :                             ObjectIdGetDatum(relid),
                               1028                 :                             Int16GetDatum(attnum));
                               1029           32403 :     if (!HeapTupleIsValid(tuple))
                               1030               6 :         return NULL;
                               1031           32397 :     if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
                               1032                 :     {
 2041 simon                    1033 UIC           0 :         ReleaseSysCache(tuple);
                               1034               0 :         return NULL;
                               1035                 :     }
 2041 simon                    1036 GIC       32397 :     return tuple;
                               1037                 : }
                               1038                 : 
                               1039                 : /*
                               1040                 :  * SearchSysCacheCopyAttNum
                               1041                 :  *
                               1042                 :  * As above, an attisdropped-aware version of SearchSysCacheCopy.
                               1043                 :  */
                               1044                 : HeapTuple
                               1045           32403 : SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
                               1046                 : {
                               1047                 :     HeapTuple   tuple,
                               1048                 :                 newtuple;
                               1049                 : 
                               1050           32403 :     tuple = SearchSysCacheAttNum(relid, attnum);
                               1051           32403 :     if (!HeapTupleIsValid(tuple))
                               1052               6 :         return NULL;
                               1053           32397 :     newtuple = heap_copytuple(tuple);
                               1054           32397 :     ReleaseSysCache(tuple);
                               1055           32397 :     return newtuple;
                               1056                 : }
                               1057                 : 
                               1058                 : 
                               1059                 : /*
                               1060                 :  * SysCacheGetAttr
                               1061                 :  *
                               1062                 :  *      Given a tuple previously fetched by SearchSysCache(),
                               1063                 :  *      extract a specific attribute.
                               1064                 :  *
                               1065                 :  * This is equivalent to using heap_getattr() on a tuple fetched
                               1066                 :  * from a non-cached relation.  Usually, this is only used for attributes
                               1067                 :  * that could be NULL or variable length; the fixed-size attributes in
                               1068                 :  * a system table are accessed just by mapping the tuple onto the C struct
                               1069                 :  * declarations from include/catalog/.
                               1070                 :  *
                               1071                 :  * As with heap_getattr(), if the attribute is of a pass-by-reference type
                               1072                 :  * then a pointer into the tuple data area is returned --- the caller must
                               1073                 :  * not modify or pfree the datum!
                               1074                 :  *
                               1075                 :  * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing
                               1076                 :  * a different cache for the same catalog the tuple was fetched from.
                               1077                 :  */
                               1078                 : Datum
 8477 tgl                      1079         2805963 : SysCacheGetAttr(int cacheId, HeapTuple tup,
                               1080                 :                 AttrNumber attributeNumber,
                               1081                 :                 bool *isNull)
                               1082                 : {
                               1083                 :     /*
                               1084                 :      * We just need to get the TupleDesc out of the cache entry, and then we
                               1085                 :      * can apply heap_getattr().  Normally the cache control data is already
                               1086                 :      * valid (because the caller recently fetched the tuple via this same
                               1087                 :      * cache), but there are cases where we have to initialize the cache here.
                               1088                 :      */
 6029                          1089         2805963 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
                               1090         2805963 :         !PointerIsValid(SysCache[cacheId]))
 4312 peter_e                  1091 UIC           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
 6029 tgl                      1092 GIC     2805963 :     if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc))
                               1093                 :     {
                               1094           10693 :         InitCatCachePhase2(SysCache[cacheId], false);
                               1095           10693 :         Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc));
                               1096                 :     }
                               1097                 : 
 8477                          1098         5611926 :     return heap_getattr(tup, attributeNumber,
                               1099         2805963 :                         SysCache[cacheId]->cc_tupdesc,
                               1100                 :                         isNull);
                               1101                 : }
                               1102                 : 
                               1103                 : /*
                               1104                 :  * SysCacheGetAttrNotNull
                               1105                 :  *
                               1106                 :  * As above, a version of SysCacheGetAttr which knows that the attr cannot
                               1107                 :  * be NULL.
                               1108                 :  */
                               1109                 : Datum
   15 dgustafsson              1110 GNC     1490587 : SysCacheGetAttrNotNull(int cacheId, HeapTuple tup,
                               1111                 :                        AttrNumber attributeNumber)
                               1112                 : {
                               1113                 :     bool        isnull;
                               1114                 :     Datum       attr;
                               1115                 : 
                               1116         1490587 :     attr = SysCacheGetAttr(cacheId, tup, attributeNumber, &isnull);
                               1117                 : 
                               1118         1490587 :     if (isnull)
                               1119                 :     {
   15 dgustafsson              1120 UNC           0 :         elog(ERROR,
                               1121                 :              "unexpected null value in cached tuple for catalog %s column %s",
                               1122                 :              get_rel_name(cacheinfo[cacheId].reloid),
                               1123                 :              NameStr(TupleDescAttr(SysCache[cacheId]->cc_tupdesc, attributeNumber - 1)->attname));
                               1124                 :     }
                               1125                 : 
   15 dgustafsson              1126 GNC     1490587 :     return attr;
                               1127                 : }
                               1128                 : 
                               1129                 : /*
                               1130                 :  * GetSysCacheHashValue
                               1131                 :  *
                               1132                 :  * Get the hash value that would be used for a tuple in the specified cache
                               1133                 :  * with the given search keys.
                               1134                 :  *
                               1135                 :  * The reason for exposing this as part of the API is that the hash value is
                               1136                 :  * exposed in cache invalidation operations, so there are places outside the
                               1137                 :  * catcache code that need to be able to compute the hash values.
                               1138                 :  */
                               1139                 : uint32
 4050 tgl                      1140 GIC      107685 : GetSysCacheHashValue(int cacheId,
                               1141                 :                      Datum key1,
                               1142                 :                      Datum key2,
                               1143                 :                      Datum key3,
                               1144                 :                      Datum key4)
                               1145                 : {
                               1146          107685 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
                               1147          107685 :         !PointerIsValid(SysCache[cacheId]))
 4050 tgl                      1148 UIC           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
                               1149                 : 
 4050 tgl                      1150 GIC      107685 :     return GetCatCacheHashValue(SysCache[cacheId], key1, key2, key3, key4);
                               1151                 : }
                               1152                 : 
                               1153                 : /*
                               1154                 :  * List-search interface
                               1155                 :  */
                               1156                 : struct catclist *
 7673                          1157         1597361 : SearchSysCacheList(int cacheId, int nkeys,
                               1158                 :                    Datum key1, Datum key2, Datum key3)
                               1159                 : {
                               1160         1597361 :     if (cacheId < 0 || cacheId >= SysCacheSize ||
 7522 bruce                    1161         1597361 :         !PointerIsValid(SysCache[cacheId]))
 4312 peter_e                  1162 UIC           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
                               1163                 : 
 7673 tgl                      1164 GIC     1597361 :     return SearchCatCacheList(SysCache[cacheId], nkeys,
                               1165                 :                               key1, key2, key3);
                               1166                 : }
                               1167                 : 
                               1168                 : /*
                               1169                 :  * SysCacheInvalidate
                               1170                 :  *
                               1171                 :  *  Invalidate entries in the specified cache, given a hash value.
                               1172                 :  *  See CatCacheInvalidate() for more info.
                               1173                 :  *
                               1174                 :  *  This routine is only quasi-public: it should only be used by inval.c.
                               1175                 :  */
                               1176                 : void
 2158                          1177        14189254 : SysCacheInvalidate(int cacheId, uint32 hashValue)
                               1178                 : {
                               1179        14189254 :     if (cacheId < 0 || cacheId >= SysCacheSize)
 2158 tgl                      1180 UIC           0 :         elog(ERROR, "invalid cache ID: %d", cacheId);
                               1181                 : 
                               1182                 :     /* if this cache isn't initialized yet, no need to do anything */
 2158 tgl                      1183 GIC    14189254 :     if (!PointerIsValid(SysCache[cacheId]))
 2158 tgl                      1184 UIC           0 :         return;
                               1185                 : 
 2158 tgl                      1186 GIC    14189254 :     CatCacheInvalidate(SysCache[cacheId], hashValue);
                               1187                 : }
                               1188                 : 
                               1189                 : /*
                               1190                 :  * Certain relations that do not have system caches send snapshot invalidation
                               1191                 :  * messages in lieu of catcache messages.  This is for the benefit of
                               1192                 :  * GetCatalogSnapshot(), which can then reuse its existing MVCC snapshot
                               1193                 :  * for scanning one of those catalogs, rather than taking a new one, if no
                               1194                 :  * invalidation has been received.
                               1195                 :  *
                               1196                 :  * Relations that have syscaches need not (and must not) be listed here.  The
                               1197                 :  * catcache invalidation messages will also flush the snapshot.  If you add a
                               1198                 :  * syscache for one of these relations, remove it from this list.
                               1199                 :  */
                               1200                 : bool
 3568 rhaas                    1201        12013240 : RelationInvalidatesSnapshotsOnly(Oid relid)
                               1202                 : {
                               1203        12013240 :     switch (relid)
                               1204                 :     {
                               1205         2049989 :         case DbRoleSettingRelationId:
                               1206                 :         case DependRelationId:
                               1207                 :         case SharedDependRelationId:
                               1208                 :         case DescriptionRelationId:
                               1209                 :         case SharedDescriptionRelationId:
                               1210                 :         case SecLabelRelationId:
                               1211                 :         case SharedSecLabelRelationId:
                               1212         2049989 :             return true;
                               1213         9963251 :         default:
                               1214         9963251 :             break;
                               1215                 :     }
                               1216                 : 
                               1217         9963251 :     return false;
                               1218                 : }
                               1219                 : 
                               1220                 : /*
                               1221                 :  * Test whether a relation has a system cache.
                               1222                 :  */
                               1223                 : bool
                               1224         6267904 : RelationHasSysCache(Oid relid)
                               1225                 : {
 3260 bruce                    1226         6267904 :     int         low = 0,
                               1227         6267904 :                 high = SysCacheRelationOidSize - 1;
                               1228                 : 
 3568 rhaas                    1229        28147230 :     while (low <= high)
                               1230                 :     {
 3260 bruce                    1231        27957782 :         int         middle = low + (high - low) / 2;
                               1232                 : 
 3568 rhaas                    1233        27957782 :         if (SysCacheRelationOid[middle] == relid)
                               1234         6078456 :             return true;
                               1235        21879326 :         if (SysCacheRelationOid[middle] < relid)
                               1236         8052803 :             low = middle + 1;
                               1237                 :         else
                               1238        13826523 :             high = middle - 1;
                               1239                 :     }
                               1240                 : 
                               1241          189448 :     return false;
                               1242                 : }
                               1243                 : 
                               1244                 : /*
                               1245                 :  * Test whether a relation supports a system cache, ie it is either a
                               1246                 :  * cached table or the index used for a cache.
                               1247                 :  */
                               1248                 : bool
 2863 tgl                      1249         1566112 : RelationSupportsSysCache(Oid relid)
                               1250                 : {
                               1251         1566112 :     int         low = 0,
                               1252         1566112 :                 high = SysCacheSupportingRelOidSize - 1;
                               1253                 : 
                               1254        13257348 :     while (low <= high)
                               1255                 :     {
                               1256        11957482 :         int         middle = low + (high - low) / 2;
                               1257                 : 
                               1258        11957482 :         if (SysCacheSupportingRelOid[middle] == relid)
                               1259          266246 :             return true;
                               1260        11691236 :         if (SysCacheSupportingRelOid[middle] < relid)
                               1261        10786852 :             low = middle + 1;
                               1262                 :         else
                               1263          904384 :             high = middle - 1;
                               1264                 :     }
                               1265                 : 
                               1266         1299866 :     return false;
                               1267                 : }
                               1268                 : 
                               1269                 : 
                               1270                 : /*
                               1271                 :  * OID comparator for pg_qsort
                               1272                 :  */
                               1273                 : static int
 3568 rhaas                    1274        21959860 : oid_compare(const void *a, const void *b)
                               1275                 : {
 2863 tgl                      1276        21959860 :     Oid         oa = *((const Oid *) a);
                               1277        21959860 :     Oid         ob = *((const Oid *) b);
                               1278                 : 
 3568 rhaas                    1279        21959860 :     if (oa == ob)
                               1280         1862770 :         return 0;
                               1281        20097090 :     return (oa > ob) ? 1 : -1;
                               1282                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a