LCOV - differential code coverage report
Current view: top level - src/backend/catalog - objectaddress.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 89.1 % 2403 2142 19 79 142 21 77 1089 64 912 150 1084 13 67
Current Date: 2023-04-08 15:15:32 Functions: 96.1 % 51 49 2 49 1 48 1 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * objectaddress.c
       4                 :  *    functions for working with ObjectAddresses
       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/catalog/objectaddress.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : 
      16                 : #include "postgres.h"
      17                 : 
      18                 : #include "access/genam.h"
      19                 : #include "access/htup_details.h"
      20                 : #include "access/relation.h"
      21                 : #include "access/sysattr.h"
      22                 : #include "access/table.h"
      23                 : #include "catalog/catalog.h"
      24                 : #include "catalog/objectaddress.h"
      25                 : #include "catalog/pg_am.h"
      26                 : #include "catalog/pg_amop.h"
      27                 : #include "catalog/pg_amproc.h"
      28                 : #include "catalog/pg_attrdef.h"
      29                 : #include "catalog/pg_authid.h"
      30                 : #include "catalog/pg_auth_members.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_default_acl.h"
      37                 : #include "catalog/pg_enum.h"
      38                 : #include "catalog/pg_event_trigger.h"
      39                 : #include "catalog/pg_extension.h"
      40                 : #include "catalog/pg_foreign_data_wrapper.h"
      41                 : #include "catalog/pg_foreign_server.h"
      42                 : #include "catalog/pg_language.h"
      43                 : #include "catalog/pg_largeobject.h"
      44                 : #include "catalog/pg_largeobject_metadata.h"
      45                 : #include "catalog/pg_namespace.h"
      46                 : #include "catalog/pg_opclass.h"
      47                 : #include "catalog/pg_operator.h"
      48                 : #include "catalog/pg_opfamily.h"
      49                 : #include "catalog/pg_parameter_acl.h"
      50                 : #include "catalog/pg_policy.h"
      51                 : #include "catalog/pg_proc.h"
      52                 : #include "catalog/pg_publication.h"
      53                 : #include "catalog/pg_publication_namespace.h"
      54                 : #include "catalog/pg_publication_rel.h"
      55                 : #include "catalog/pg_rewrite.h"
      56                 : #include "catalog/pg_statistic_ext.h"
      57                 : #include "catalog/pg_subscription.h"
      58                 : #include "catalog/pg_tablespace.h"
      59                 : #include "catalog/pg_transform.h"
      60                 : #include "catalog/pg_trigger.h"
      61                 : #include "catalog/pg_ts_config.h"
      62                 : #include "catalog/pg_ts_dict.h"
      63                 : #include "catalog/pg_ts_parser.h"
      64                 : #include "catalog/pg_ts_template.h"
      65                 : #include "catalog/pg_type.h"
      66                 : #include "catalog/pg_user_mapping.h"
      67                 : #include "commands/dbcommands.h"
      68                 : #include "commands/defrem.h"
      69                 : #include "commands/event_trigger.h"
      70                 : #include "commands/extension.h"
      71                 : #include "commands/policy.h"
      72                 : #include "commands/proclang.h"
      73                 : #include "commands/tablespace.h"
      74                 : #include "commands/trigger.h"
      75                 : #include "foreign/foreign.h"
      76                 : #include "funcapi.h"
      77                 : #include "miscadmin.h"
      78                 : #include "nodes/makefuncs.h"
      79                 : #include "parser/parse_func.h"
      80                 : #include "parser/parse_oper.h"
      81                 : #include "parser/parse_type.h"
      82                 : #include "rewrite/rewriteSupport.h"
      83                 : #include "storage/large_object.h"
      84                 : #include "storage/lmgr.h"
      85                 : #include "storage/sinval.h"
      86                 : #include "utils/acl.h"
      87                 : #include "utils/builtins.h"
      88                 : #include "utils/fmgroids.h"
      89                 : #include "utils/lsyscache.h"
      90                 : #include "utils/memutils.h"
      91                 : #include "utils/regproc.h"
      92                 : #include "utils/syscache.h"
      93                 : 
      94                 : /*
      95                 :  * ObjectProperty
      96                 :  *
      97                 :  * This array provides a common part of system object structure; to help
      98                 :  * consolidate routines to handle various kind of object classes.
      99                 :  */
     100                 : typedef struct
     101                 : {
     102                 :     const char *class_descr;    /* string describing the catalog, for internal
     103                 :                                  * error messages */
     104                 :     Oid         class_oid;      /* oid of catalog */
     105                 :     Oid         oid_index_oid;  /* oid of index on system oid column */
     106                 :     int         oid_catcache_id;    /* id of catcache on system oid column  */
     107                 :     int         name_catcache_id;   /* id of catcache on (name,namespace), or
     108                 :                                      * (name) if the object does not live in a
     109                 :                                      * namespace */
     110                 :     AttrNumber  attnum_oid;     /* attribute number of oid column */
     111                 :     AttrNumber  attnum_name;    /* attnum of name field */
     112                 :     AttrNumber  attnum_namespace;   /* attnum of namespace field */
     113                 :     AttrNumber  attnum_owner;   /* attnum of owner field */
     114                 :     AttrNumber  attnum_acl;     /* attnum of acl field */
     115                 :     ObjectType  objtype;        /* OBJECT_* of this object type */
     116                 :     bool        is_nsp_name_unique; /* can the nsp/name combination (or name
     117                 :                                      * alone, if there's no namespace) be
     118                 :                                      * considered a unique identifier for an
     119                 :                                      * object of this class? */
     120                 : } ObjectPropertyType;
     121                 : 
     122                 : static const ObjectPropertyType ObjectProperty[] =
     123                 : {
     124                 :     {
     125                 :         "access method",
     126                 :         AccessMethodRelationId,
     127                 :         AmOidIndexId,
     128                 :         AMOID,
     129                 :         AMNAME,
     130                 :         Anum_pg_am_oid,
     131                 :         Anum_pg_am_amname,
     132                 :         InvalidAttrNumber,
     133                 :         InvalidAttrNumber,
     134                 :         InvalidAttrNumber,
     135                 :         -1,
     136                 :         true
     137                 :     },
     138                 :     {
     139                 :         "access method operator",
     140                 :         AccessMethodOperatorRelationId,
     141                 :         AccessMethodOperatorOidIndexId,
     142                 :         -1,
     143                 :         -1,
     144                 :         Anum_pg_amop_oid,
     145                 :         InvalidAttrNumber,
     146                 :         InvalidAttrNumber,
     147                 :         InvalidAttrNumber,
     148                 :         InvalidAttrNumber,
     149                 :         OBJECT_AMOP,
     150                 :         false
     151                 :     },
     152                 :     {
     153                 :         "access method procedure",
     154                 :         AccessMethodProcedureRelationId,
     155                 :         AccessMethodProcedureOidIndexId,
     156                 :         -1,
     157                 :         -1,
     158                 :         Anum_pg_amproc_oid,
     159                 :         InvalidAttrNumber,
     160                 :         InvalidAttrNumber,
     161                 :         InvalidAttrNumber,
     162                 :         InvalidAttrNumber,
     163                 :         OBJECT_AMPROC,
     164                 :         false
     165                 :     },
     166                 :     {
     167                 :         "cast",
     168                 :         CastRelationId,
     169                 :         CastOidIndexId,
     170                 :         -1,
     171                 :         -1,
     172                 :         Anum_pg_cast_oid,
     173                 :         InvalidAttrNumber,
     174                 :         InvalidAttrNumber,
     175                 :         InvalidAttrNumber,
     176                 :         InvalidAttrNumber,
     177                 :         -1,
     178                 :         false
     179                 :     },
     180                 :     {
     181                 :         "collation",
     182                 :         CollationRelationId,
     183                 :         CollationOidIndexId,
     184                 :         COLLOID,
     185                 :         -1,                     /* COLLNAMEENCNSP also takes encoding */
     186                 :         Anum_pg_collation_oid,
     187                 :         Anum_pg_collation_collname,
     188                 :         Anum_pg_collation_collnamespace,
     189                 :         Anum_pg_collation_collowner,
     190                 :         InvalidAttrNumber,
     191                 :         OBJECT_COLLATION,
     192                 :         true
     193                 :     },
     194                 :     {
     195                 :         "constraint",
     196                 :         ConstraintRelationId,
     197                 :         ConstraintOidIndexId,
     198                 :         CONSTROID,
     199                 :         -1,
     200                 :         Anum_pg_constraint_oid,
     201                 :         Anum_pg_constraint_conname,
     202                 :         Anum_pg_constraint_connamespace,
     203                 :         InvalidAttrNumber,
     204                 :         InvalidAttrNumber,
     205                 :         -1,
     206                 :         false
     207                 :     },
     208                 :     {
     209                 :         "conversion",
     210                 :         ConversionRelationId,
     211                 :         ConversionOidIndexId,
     212                 :         CONVOID,
     213                 :         CONNAMENSP,
     214                 :         Anum_pg_conversion_oid,
     215                 :         Anum_pg_conversion_conname,
     216                 :         Anum_pg_conversion_connamespace,
     217                 :         Anum_pg_conversion_conowner,
     218                 :         InvalidAttrNumber,
     219                 :         OBJECT_CONVERSION,
     220                 :         true
     221                 :     },
     222                 :     {
     223                 :         "database",
     224                 :         DatabaseRelationId,
     225                 :         DatabaseOidIndexId,
     226                 :         DATABASEOID,
     227                 :         -1,
     228                 :         Anum_pg_database_oid,
     229                 :         Anum_pg_database_datname,
     230                 :         InvalidAttrNumber,
     231                 :         Anum_pg_database_datdba,
     232                 :         Anum_pg_database_datacl,
     233                 :         OBJECT_DATABASE,
     234                 :         true
     235                 :     },
     236                 :     {
     237                 :         "default ACL",
     238                 :         DefaultAclRelationId,
     239                 :         DefaultAclOidIndexId,
     240                 :         -1,
     241                 :         -1,
     242                 :         Anum_pg_default_acl_oid,
     243                 :         InvalidAttrNumber,
     244                 :         InvalidAttrNumber,
     245                 :         InvalidAttrNumber,
     246                 :         InvalidAttrNumber,
     247                 :         OBJECT_DEFACL,
     248                 :         false
     249                 :     },
     250                 :     {
     251                 :         "extension",
     252                 :         ExtensionRelationId,
     253                 :         ExtensionOidIndexId,
     254                 :         -1,
     255                 :         -1,
     256                 :         Anum_pg_extension_oid,
     257                 :         Anum_pg_extension_extname,
     258                 :         InvalidAttrNumber,      /* extension doesn't belong to extnamespace */
     259                 :         Anum_pg_extension_extowner,
     260                 :         InvalidAttrNumber,
     261                 :         OBJECT_EXTENSION,
     262                 :         true
     263                 :     },
     264                 :     {
     265                 :         "foreign-data wrapper",
     266                 :         ForeignDataWrapperRelationId,
     267                 :         ForeignDataWrapperOidIndexId,
     268                 :         FOREIGNDATAWRAPPEROID,
     269                 :         FOREIGNDATAWRAPPERNAME,
     270                 :         Anum_pg_foreign_data_wrapper_oid,
     271                 :         Anum_pg_foreign_data_wrapper_fdwname,
     272                 :         InvalidAttrNumber,
     273                 :         Anum_pg_foreign_data_wrapper_fdwowner,
     274                 :         Anum_pg_foreign_data_wrapper_fdwacl,
     275                 :         OBJECT_FDW,
     276                 :         true
     277                 :     },
     278                 :     {
     279                 :         "foreign server",
     280                 :         ForeignServerRelationId,
     281                 :         ForeignServerOidIndexId,
     282                 :         FOREIGNSERVEROID,
     283                 :         FOREIGNSERVERNAME,
     284                 :         Anum_pg_foreign_server_oid,
     285                 :         Anum_pg_foreign_server_srvname,
     286                 :         InvalidAttrNumber,
     287                 :         Anum_pg_foreign_server_srvowner,
     288                 :         Anum_pg_foreign_server_srvacl,
     289                 :         OBJECT_FOREIGN_SERVER,
     290                 :         true
     291                 :     },
     292                 :     {
     293                 :         "function",
     294                 :         ProcedureRelationId,
     295                 :         ProcedureOidIndexId,
     296                 :         PROCOID,
     297                 :         -1,                     /* PROCNAMEARGSNSP also takes argument types */
     298                 :         Anum_pg_proc_oid,
     299                 :         Anum_pg_proc_proname,
     300                 :         Anum_pg_proc_pronamespace,
     301                 :         Anum_pg_proc_proowner,
     302                 :         Anum_pg_proc_proacl,
     303                 :         OBJECT_FUNCTION,
     304                 :         false
     305                 :     },
     306                 :     {
     307                 :         "language",
     308                 :         LanguageRelationId,
     309                 :         LanguageOidIndexId,
     310                 :         LANGOID,
     311                 :         LANGNAME,
     312                 :         Anum_pg_language_oid,
     313                 :         Anum_pg_language_lanname,
     314                 :         InvalidAttrNumber,
     315                 :         Anum_pg_language_lanowner,
     316                 :         Anum_pg_language_lanacl,
     317                 :         OBJECT_LANGUAGE,
     318                 :         true
     319                 :     },
     320                 :     {
     321                 :         "large object metadata",
     322                 :         LargeObjectMetadataRelationId,
     323                 :         LargeObjectMetadataOidIndexId,
     324                 :         -1,
     325                 :         -1,
     326                 :         Anum_pg_largeobject_metadata_oid,
     327                 :         InvalidAttrNumber,
     328                 :         InvalidAttrNumber,
     329                 :         Anum_pg_largeobject_metadata_lomowner,
     330                 :         Anum_pg_largeobject_metadata_lomacl,
     331                 :         OBJECT_LARGEOBJECT,
     332                 :         false
     333                 :     },
     334                 :     {
     335                 :         "operator class",
     336                 :         OperatorClassRelationId,
     337                 :         OpclassOidIndexId,
     338                 :         CLAOID,
     339                 :         -1,                     /* CLAAMNAMENSP also takes opcmethod */
     340                 :         Anum_pg_opclass_oid,
     341                 :         Anum_pg_opclass_opcname,
     342                 :         Anum_pg_opclass_opcnamespace,
     343                 :         Anum_pg_opclass_opcowner,
     344                 :         InvalidAttrNumber,
     345                 :         OBJECT_OPCLASS,
     346                 :         true
     347                 :     },
     348                 :     {
     349                 :         "operator",
     350                 :         OperatorRelationId,
     351                 :         OperatorOidIndexId,
     352                 :         OPEROID,
     353                 :         -1,                     /* OPERNAMENSP also takes left and right type */
     354                 :         Anum_pg_operator_oid,
     355                 :         Anum_pg_operator_oprname,
     356                 :         Anum_pg_operator_oprnamespace,
     357                 :         Anum_pg_operator_oprowner,
     358                 :         InvalidAttrNumber,
     359                 :         OBJECT_OPERATOR,
     360                 :         false
     361                 :     },
     362                 :     {
     363                 :         "operator family",
     364                 :         OperatorFamilyRelationId,
     365                 :         OpfamilyOidIndexId,
     366                 :         OPFAMILYOID,
     367                 :         -1,                     /* OPFAMILYAMNAMENSP also takes opfmethod */
     368                 :         Anum_pg_opfamily_oid,
     369                 :         Anum_pg_opfamily_opfname,
     370                 :         Anum_pg_opfamily_opfnamespace,
     371                 :         Anum_pg_opfamily_opfowner,
     372                 :         InvalidAttrNumber,
     373                 :         OBJECT_OPFAMILY,
     374                 :         true
     375                 :     },
     376                 :     {
     377                 :         "role",
     378                 :         AuthIdRelationId,
     379                 :         AuthIdOidIndexId,
     380                 :         AUTHOID,
     381                 :         AUTHNAME,
     382                 :         Anum_pg_authid_oid,
     383                 :         Anum_pg_authid_rolname,
     384                 :         InvalidAttrNumber,
     385                 :         InvalidAttrNumber,
     386                 :         InvalidAttrNumber,
     387                 :         -1,
     388                 :         true
     389                 :     },
     390                 :     {
     391                 :         "role membership",
     392                 :         AuthMemRelationId,
     393                 :         AuthMemOidIndexId,
     394                 :         -1,
     395                 :         -1,
     396                 :         Anum_pg_auth_members_oid,
     397                 :         InvalidAttrNumber,
     398                 :         InvalidAttrNumber,
     399                 :         Anum_pg_auth_members_grantor,
     400                 :         InvalidAttrNumber,
     401                 :         -1,
     402                 :         true
     403                 :     },
     404                 :     {
     405                 :         "rule",
     406                 :         RewriteRelationId,
     407                 :         RewriteOidIndexId,
     408                 :         -1,
     409                 :         -1,
     410                 :         Anum_pg_rewrite_oid,
     411                 :         Anum_pg_rewrite_rulename,
     412                 :         InvalidAttrNumber,
     413                 :         InvalidAttrNumber,
     414                 :         InvalidAttrNumber,
     415                 :         -1,
     416                 :         false
     417                 :     },
     418                 :     {
     419                 :         "schema",
     420                 :         NamespaceRelationId,
     421                 :         NamespaceOidIndexId,
     422                 :         NAMESPACEOID,
     423                 :         NAMESPACENAME,
     424                 :         Anum_pg_namespace_oid,
     425                 :         Anum_pg_namespace_nspname,
     426                 :         InvalidAttrNumber,
     427                 :         Anum_pg_namespace_nspowner,
     428                 :         Anum_pg_namespace_nspacl,
     429                 :         OBJECT_SCHEMA,
     430                 :         true
     431                 :     },
     432                 :     {
     433                 :         "relation",
     434                 :         RelationRelationId,
     435                 :         ClassOidIndexId,
     436                 :         RELOID,
     437                 :         RELNAMENSP,
     438                 :         Anum_pg_class_oid,
     439                 :         Anum_pg_class_relname,
     440                 :         Anum_pg_class_relnamespace,
     441                 :         Anum_pg_class_relowner,
     442                 :         Anum_pg_class_relacl,
     443                 :         OBJECT_TABLE,
     444                 :         true
     445                 :     },
     446                 :     {
     447                 :         "tablespace",
     448                 :         TableSpaceRelationId,
     449                 :         TablespaceOidIndexId,
     450                 :         TABLESPACEOID,
     451                 :         -1,
     452                 :         Anum_pg_tablespace_oid,
     453                 :         Anum_pg_tablespace_spcname,
     454                 :         InvalidAttrNumber,
     455                 :         Anum_pg_tablespace_spcowner,
     456                 :         Anum_pg_tablespace_spcacl,
     457                 :         OBJECT_TABLESPACE,
     458                 :         true
     459                 :     },
     460                 :     {
     461                 :         "transform",
     462                 :         TransformRelationId,
     463                 :         TransformOidIndexId,
     464                 :         TRFOID,
     465                 :         InvalidAttrNumber,
     466                 :         Anum_pg_transform_oid
     467                 :     },
     468                 :     {
     469                 :         "trigger",
     470                 :         TriggerRelationId,
     471                 :         TriggerOidIndexId,
     472                 :         -1,
     473                 :         -1,
     474                 :         Anum_pg_trigger_oid,
     475                 :         Anum_pg_trigger_tgname,
     476                 :         InvalidAttrNumber,
     477                 :         InvalidAttrNumber,
     478                 :         InvalidAttrNumber,
     479                 :         -1,
     480                 :         false
     481                 :     },
     482                 :     {
     483                 :         "policy",
     484                 :         PolicyRelationId,
     485                 :         PolicyOidIndexId,
     486                 :         -1,
     487                 :         -1,
     488                 :         Anum_pg_policy_oid,
     489                 :         Anum_pg_policy_polname,
     490                 :         InvalidAttrNumber,
     491                 :         InvalidAttrNumber,
     492                 :         InvalidAttrNumber,
     493                 :         -1,
     494                 :         false
     495                 :     },
     496                 :     {
     497                 :         "event trigger",
     498                 :         EventTriggerRelationId,
     499                 :         EventTriggerOidIndexId,
     500                 :         EVENTTRIGGEROID,
     501                 :         EVENTTRIGGERNAME,
     502                 :         Anum_pg_event_trigger_oid,
     503                 :         Anum_pg_event_trigger_evtname,
     504                 :         InvalidAttrNumber,
     505                 :         Anum_pg_event_trigger_evtowner,
     506                 :         InvalidAttrNumber,
     507                 :         OBJECT_EVENT_TRIGGER,
     508                 :         true
     509                 :     },
     510                 :     {
     511                 :         "text search configuration",
     512                 :         TSConfigRelationId,
     513                 :         TSConfigOidIndexId,
     514                 :         TSCONFIGOID,
     515                 :         TSCONFIGNAMENSP,
     516                 :         Anum_pg_ts_config_oid,
     517                 :         Anum_pg_ts_config_cfgname,
     518                 :         Anum_pg_ts_config_cfgnamespace,
     519                 :         Anum_pg_ts_config_cfgowner,
     520                 :         InvalidAttrNumber,
     521                 :         OBJECT_TSCONFIGURATION,
     522                 :         true
     523                 :     },
     524                 :     {
     525                 :         "text search dictionary",
     526                 :         TSDictionaryRelationId,
     527                 :         TSDictionaryOidIndexId,
     528                 :         TSDICTOID,
     529                 :         TSDICTNAMENSP,
     530                 :         Anum_pg_ts_dict_oid,
     531                 :         Anum_pg_ts_dict_dictname,
     532                 :         Anum_pg_ts_dict_dictnamespace,
     533                 :         Anum_pg_ts_dict_dictowner,
     534                 :         InvalidAttrNumber,
     535                 :         OBJECT_TSDICTIONARY,
     536                 :         true
     537                 :     },
     538                 :     {
     539                 :         "text search parser",
     540                 :         TSParserRelationId,
     541                 :         TSParserOidIndexId,
     542                 :         TSPARSEROID,
     543                 :         TSPARSERNAMENSP,
     544                 :         Anum_pg_ts_parser_oid,
     545                 :         Anum_pg_ts_parser_prsname,
     546                 :         Anum_pg_ts_parser_prsnamespace,
     547                 :         InvalidAttrNumber,
     548                 :         InvalidAttrNumber,
     549                 :         -1,
     550                 :         true
     551                 :     },
     552                 :     {
     553                 :         "text search template",
     554                 :         TSTemplateRelationId,
     555                 :         TSTemplateOidIndexId,
     556                 :         TSTEMPLATEOID,
     557                 :         TSTEMPLATENAMENSP,
     558                 :         Anum_pg_ts_template_oid,
     559                 :         Anum_pg_ts_template_tmplname,
     560                 :         Anum_pg_ts_template_tmplnamespace,
     561                 :         InvalidAttrNumber,
     562                 :         InvalidAttrNumber,
     563                 :         -1,
     564                 :         true,
     565                 :     },
     566                 :     {
     567                 :         "type",
     568                 :         TypeRelationId,
     569                 :         TypeOidIndexId,
     570                 :         TYPEOID,
     571                 :         TYPENAMENSP,
     572                 :         Anum_pg_type_oid,
     573                 :         Anum_pg_type_typname,
     574                 :         Anum_pg_type_typnamespace,
     575                 :         Anum_pg_type_typowner,
     576                 :         Anum_pg_type_typacl,
     577                 :         OBJECT_TYPE,
     578                 :         true
     579                 :     },
     580                 :     {
     581                 :         "publication",
     582                 :         PublicationRelationId,
     583                 :         PublicationObjectIndexId,
     584                 :         PUBLICATIONOID,
     585                 :         PUBLICATIONNAME,
     586                 :         Anum_pg_publication_oid,
     587                 :         Anum_pg_publication_pubname,
     588                 :         InvalidAttrNumber,
     589                 :         Anum_pg_publication_pubowner,
     590                 :         InvalidAttrNumber,
     591                 :         OBJECT_PUBLICATION,
     592                 :         true
     593                 :     },
     594                 :     {
     595                 :         "subscription",
     596                 :         SubscriptionRelationId,
     597                 :         SubscriptionObjectIndexId,
     598                 :         SUBSCRIPTIONOID,
     599                 :         SUBSCRIPTIONNAME,
     600                 :         Anum_pg_subscription_oid,
     601                 :         Anum_pg_subscription_subname,
     602                 :         InvalidAttrNumber,
     603                 :         Anum_pg_subscription_subowner,
     604                 :         InvalidAttrNumber,
     605                 :         OBJECT_SUBSCRIPTION,
     606                 :         true
     607                 :     },
     608                 :     {
     609                 :         "extended statistics",
     610                 :         StatisticExtRelationId,
     611                 :         StatisticExtOidIndexId,
     612                 :         STATEXTOID,
     613                 :         STATEXTNAMENSP,
     614                 :         Anum_pg_statistic_ext_oid,
     615                 :         Anum_pg_statistic_ext_stxname,
     616                 :         Anum_pg_statistic_ext_stxnamespace,
     617                 :         Anum_pg_statistic_ext_stxowner,
     618                 :         InvalidAttrNumber,      /* no ACL (same as relation) */
     619                 :         OBJECT_STATISTIC_EXT,
     620                 :         true
     621                 :     },
     622                 :     {
     623                 :         "user mapping",
     624                 :         UserMappingRelationId,
     625                 :         UserMappingOidIndexId,
     626                 :         USERMAPPINGOID,
     627                 :         -1,
     628                 :         Anum_pg_user_mapping_oid,
     629                 :         InvalidAttrNumber,
     630                 :         InvalidAttrNumber,
     631                 :         InvalidAttrNumber,
     632                 :         InvalidAttrNumber,
     633                 :         OBJECT_USER_MAPPING,
     634                 :         false
     635                 :     },
     636                 : };
     637                 : 
     638                 : /*
     639                 :  * This struct maps the string object types as returned by
     640                 :  * getObjectTypeDescription into ObjectType enum values.  Note that some enum
     641                 :  * values can be obtained by different names, and that some string object types
     642                 :  * do not have corresponding values in the output enum.  The user of this map
     643                 :  * must be careful to test for invalid values being returned.
     644                 :  *
     645                 :  * To ease maintenance, this follows the order of getObjectTypeDescription.
     646                 :  */
     647                 : static const struct object_type_map
     648                 : {
     649                 :     const char *tm_name;
     650                 :     ObjectType  tm_type;
     651                 : }
     652                 : 
     653                 :             ObjectTypeMap[] =
     654                 : {
     655                 :     /* OCLASS_CLASS, all kinds of relations */
     656                 :     {
     657                 :         "table", OBJECT_TABLE
     658                 :     },
     659                 :     {
     660                 :         "index", OBJECT_INDEX
     661                 :     },
     662                 :     {
     663                 :         "sequence", OBJECT_SEQUENCE
     664                 :     },
     665                 :     {
     666                 :         "toast table", -1
     667                 :     },                          /* unmapped */
     668                 :     {
     669                 :         "view", OBJECT_VIEW
     670                 :     },
     671                 :     {
     672                 :         "materialized view", OBJECT_MATVIEW
     673                 :     },
     674                 :     {
     675                 :         "composite type", -1
     676                 :     },                          /* unmapped */
     677                 :     {
     678                 :         "foreign table", OBJECT_FOREIGN_TABLE
     679                 :     },
     680                 :     {
     681                 :         "table column", OBJECT_COLUMN
     682                 :     },
     683                 :     {
     684                 :         "index column", -1
     685                 :     },                          /* unmapped */
     686                 :     {
     687                 :         "sequence column", -1
     688                 :     },                          /* unmapped */
     689                 :     {
     690                 :         "toast table column", -1
     691                 :     },                          /* unmapped */
     692                 :     {
     693                 :         "view column", -1
     694                 :     },                          /* unmapped */
     695                 :     {
     696                 :         "materialized view column", -1
     697                 :     },                          /* unmapped */
     698                 :     {
     699                 :         "composite type column", -1
     700                 :     },                          /* unmapped */
     701                 :     {
     702                 :         "foreign table column", OBJECT_COLUMN
     703                 :     },
     704                 :     /* OCLASS_PROC */
     705                 :     {
     706                 :         "aggregate", OBJECT_AGGREGATE
     707                 :     },
     708                 :     {
     709                 :         "function", OBJECT_FUNCTION
     710                 :     },
     711                 :     {
     712                 :         "procedure", OBJECT_PROCEDURE
     713                 :     },
     714                 :     /* OCLASS_TYPE */
     715                 :     {
     716                 :         "type", OBJECT_TYPE
     717                 :     },
     718                 :     /* OCLASS_CAST */
     719                 :     {
     720                 :         "cast", OBJECT_CAST
     721                 :     },
     722                 :     /* OCLASS_COLLATION */
     723                 :     {
     724                 :         "collation", OBJECT_COLLATION
     725                 :     },
     726                 :     /* OCLASS_CONSTRAINT */
     727                 :     {
     728                 :         "table constraint", OBJECT_TABCONSTRAINT
     729                 :     },
     730                 :     {
     731                 :         "domain constraint", OBJECT_DOMCONSTRAINT
     732                 :     },
     733                 :     /* OCLASS_CONVERSION */
     734                 :     {
     735                 :         "conversion", OBJECT_CONVERSION
     736                 :     },
     737                 :     /* OCLASS_DEFAULT */
     738                 :     {
     739                 :         "default value", OBJECT_DEFAULT
     740                 :     },
     741                 :     /* OCLASS_LANGUAGE */
     742                 :     {
     743                 :         "language", OBJECT_LANGUAGE
     744                 :     },
     745                 :     /* OCLASS_LARGEOBJECT */
     746                 :     {
     747                 :         "large object", OBJECT_LARGEOBJECT
     748                 :     },
     749                 :     /* OCLASS_OPERATOR */
     750                 :     {
     751                 :         "operator", OBJECT_OPERATOR
     752                 :     },
     753                 :     /* OCLASS_OPCLASS */
     754                 :     {
     755                 :         "operator class", OBJECT_OPCLASS
     756                 :     },
     757                 :     /* OCLASS_OPFAMILY */
     758                 :     {
     759                 :         "operator family", OBJECT_OPFAMILY
     760                 :     },
     761                 :     /* OCLASS_AM */
     762                 :     {
     763                 :         "access method", OBJECT_ACCESS_METHOD
     764                 :     },
     765                 :     /* OCLASS_AMOP */
     766                 :     {
     767                 :         "operator of access method", OBJECT_AMOP
     768                 :     },
     769                 :     /* OCLASS_AMPROC */
     770                 :     {
     771                 :         "function of access method", OBJECT_AMPROC
     772                 :     },
     773                 :     /* OCLASS_REWRITE */
     774                 :     {
     775                 :         "rule", OBJECT_RULE
     776                 :     },
     777                 :     /* OCLASS_TRIGGER */
     778                 :     {
     779                 :         "trigger", OBJECT_TRIGGER
     780                 :     },
     781                 :     /* OCLASS_SCHEMA */
     782                 :     {
     783                 :         "schema", OBJECT_SCHEMA
     784                 :     },
     785                 :     /* OCLASS_TSPARSER */
     786                 :     {
     787                 :         "text search parser", OBJECT_TSPARSER
     788                 :     },
     789                 :     /* OCLASS_TSDICT */
     790                 :     {
     791                 :         "text search dictionary", OBJECT_TSDICTIONARY
     792                 :     },
     793                 :     /* OCLASS_TSTEMPLATE */
     794                 :     {
     795                 :         "text search template", OBJECT_TSTEMPLATE
     796                 :     },
     797                 :     /* OCLASS_TSCONFIG */
     798                 :     {
     799                 :         "text search configuration", OBJECT_TSCONFIGURATION
     800                 :     },
     801                 :     /* OCLASS_ROLE */
     802                 :     {
     803                 :         "role", OBJECT_ROLE
     804                 :     },
     805                 :     /* OCLASS_ROLE_MEMBERSHIP */
     806                 :     {
     807                 :         "role membership", -1 /* unmapped */
     808                 :     },
     809                 :     /* OCLASS_DATABASE */
     810                 :     {
     811                 :         "database", OBJECT_DATABASE
     812                 :     },
     813                 :     /* OCLASS_TBLSPACE */
     814                 :     {
     815                 :         "tablespace", OBJECT_TABLESPACE
     816                 :     },
     817                 :     /* OCLASS_FDW */
     818                 :     {
     819                 :         "foreign-data wrapper", OBJECT_FDW
     820                 :     },
     821                 :     /* OCLASS_FOREIGN_SERVER */
     822                 :     {
     823                 :         "server", OBJECT_FOREIGN_SERVER
     824                 :     },
     825                 :     /* OCLASS_USER_MAPPING */
     826                 :     {
     827                 :         "user mapping", OBJECT_USER_MAPPING
     828                 :     },
     829                 :     /* OCLASS_DEFACL */
     830                 :     {
     831                 :         "default acl", OBJECT_DEFACL
     832                 :     },
     833                 :     /* OCLASS_EXTENSION */
     834                 :     {
     835                 :         "extension", OBJECT_EXTENSION
     836                 :     },
     837                 :     /* OCLASS_EVENT_TRIGGER */
     838                 :     {
     839                 :         "event trigger", OBJECT_EVENT_TRIGGER
     840                 :     },
     841                 :     /* OCLASS_PARAMETER_ACL */
     842                 :     {
     843                 :         "parameter ACL", OBJECT_PARAMETER_ACL
     844                 :     },
     845                 :     /* OCLASS_POLICY */
     846                 :     {
     847                 :         "policy", OBJECT_POLICY
     848                 :     },
     849                 :     /* OCLASS_PUBLICATION */
     850                 :     {
     851                 :         "publication", OBJECT_PUBLICATION
     852                 :     },
     853                 :     /* OCLASS_PUBLICATION_NAMESPACE */
     854                 :     {
     855                 :         "publication namespace", OBJECT_PUBLICATION_NAMESPACE
     856                 :     },
     857                 :     /* OCLASS_PUBLICATION_REL */
     858                 :     {
     859                 :         "publication relation", OBJECT_PUBLICATION_REL
     860                 :     },
     861                 :     /* OCLASS_SUBSCRIPTION */
     862                 :     {
     863                 :         "subscription", OBJECT_SUBSCRIPTION
     864                 :     },
     865                 :     /* OCLASS_TRANSFORM */
     866                 :     {
     867                 :         "transform", OBJECT_TRANSFORM
     868                 :     },
     869                 :     /* OCLASS_STATISTIC_EXT */
     870                 :     {
     871                 :         "statistics object", OBJECT_STATISTIC_EXT
     872                 :     }
     873                 : };
     874                 : 
     875                 : const ObjectAddress InvalidObjectAddress =
     876                 : {
     877                 :     InvalidOid,
     878                 :     InvalidOid,
     879                 :     0
     880                 : };
     881                 : 
     882                 : static ObjectAddress get_object_address_unqualified(ObjectType objtype,
     883                 :                                                     String *strval, bool missing_ok);
     884                 : static ObjectAddress get_relation_by_qualified_name(ObjectType objtype,
     885                 :                                                     List *object, Relation *relp,
     886                 :                                                     LOCKMODE lockmode, bool missing_ok);
     887                 : static ObjectAddress get_object_address_relobject(ObjectType objtype,
     888                 :                                                   List *object, Relation *relp, bool missing_ok);
     889                 : static ObjectAddress get_object_address_attribute(ObjectType objtype,
     890                 :                                                   List *object, Relation *relp,
     891                 :                                                   LOCKMODE lockmode, bool missing_ok);
     892                 : static ObjectAddress get_object_address_attrdef(ObjectType objtype,
     893                 :                                                 List *object, Relation *relp, LOCKMODE lockmode,
     894                 :                                                 bool missing_ok);
     895                 : static ObjectAddress get_object_address_type(ObjectType objtype,
     896                 :                                              TypeName *typename, bool missing_ok);
     897                 : static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object,
     898                 :                                              bool missing_ok);
     899                 : static ObjectAddress get_object_address_opf_member(ObjectType objtype,
     900                 :                                                    List *object, bool missing_ok);
     901                 : 
     902                 : static ObjectAddress get_object_address_usermapping(List *object,
     903                 :                                                     bool missing_ok);
     904                 : static ObjectAddress get_object_address_publication_rel(List *object,
     905                 :                                                         Relation *relp,
     906                 :                                                         bool missing_ok);
     907                 : static ObjectAddress get_object_address_publication_schema(List *object,
     908                 :                                                            bool missing_ok);
     909                 : static ObjectAddress get_object_address_defacl(List *object,
     910                 :                                                bool missing_ok);
     911                 : static const ObjectPropertyType *get_object_property_data(Oid class_id);
     912                 : 
     913                 : static void getRelationDescription(StringInfo buffer, Oid relid,
     914                 :                                    bool missing_ok);
     915                 : static void getOpFamilyDescription(StringInfo buffer, Oid opfid,
     916                 :                                    bool missing_ok);
     917                 : static void getRelationTypeDescription(StringInfo buffer, Oid relid,
     918                 :                                        int32 objectSubId, bool missing_ok);
     919                 : static void getProcedureTypeDescription(StringInfo buffer, Oid procid,
     920                 :                                         bool missing_ok);
     921                 : static void getConstraintTypeDescription(StringInfo buffer, Oid constroid,
     922                 :                                          bool missing_ok);
     923                 : static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
     924                 :                                 bool missing_ok);
     925                 : static void getRelationIdentity(StringInfo buffer, Oid relid, List **object,
     926                 :                                 bool missing_ok);
     927                 : 
     928                 : /*
     929                 :  * Translate an object name and arguments (as passed by the parser) to an
     930                 :  * ObjectAddress.
     931                 :  *
     932                 :  * The returned object will be locked using the specified lockmode.  If a
     933                 :  * sub-object is looked up, the parent object will be locked instead.
     934                 :  *
     935                 :  * If the object is a relation or a child object of a relation (e.g. an
     936                 :  * attribute or constraint), the relation is also opened and *relp receives
     937                 :  * the open relcache entry pointer; otherwise, *relp is set to NULL.  This
     938                 :  * is a bit grotty but it makes life simpler, since the caller will
     939                 :  * typically need the relcache entry too.  Caller must close the relcache
     940                 :  * entry when done with it.  The relation is locked with the specified lockmode
     941                 :  * if the target object is the relation itself or an attribute, but for other
     942                 :  * child objects, only AccessShareLock is acquired on the relation.
     943                 :  *
     944                 :  * If the object is not found, an error is thrown, unless missing_ok is
     945                 :  * true.  In this case, no lock is acquired, relp is set to NULL, and the
     946                 :  * returned address has objectId set to InvalidOid.
     947                 :  *
     948                 :  * We don't currently provide a function to release the locks acquired here;
     949                 :  * typically, the lock must be held until commit to guard against a concurrent
     950                 :  * drop operation.
     951                 :  *
     952                 :  * Note: If the object is not found, we don't give any indication of the
     953                 :  * reason.  (It might have been a missing schema if the name was qualified, or
     954                 :  * a nonexistent type name in case of a cast, function or operator; etc).
     955                 :  * Currently there is only one caller that might be interested in such info, so
     956                 :  * we don't spend much effort here.  If more callers start to care, it might be
     957                 :  * better to add some support for that in this function.
     958                 :  */
     959                 : ObjectAddress
     960 GIC       24970 : get_object_address(ObjectType objtype, Node *object,
     961                 :                    Relation *relp, LOCKMODE lockmode, bool missing_ok)
     962                 : {
     963 GNC       24970 :     ObjectAddress address = {InvalidOid, InvalidOid, 0};
     964 GIC       24970 :     ObjectAddress old_address = {InvalidOid, InvalidOid, 0};
     965           24970 :     Relation    relation = NULL;
     966                 :     uint64      inval_count;
     967                 : 
     968                 :     /* Some kind of lock must be taken. */
     969           24970 :     Assert(lockmode != NoLock);
     970                 : 
     971                 :     for (;;)
     972                 :     {
     973                 :         /*
     974                 :          * Remember this value, so that, after looking up the object name and
     975                 :          * locking it, we can check whether any invalidation messages have
     976                 :          * been processed that might require a do-over.
     977                 :          */
     978           25100 :         inval_count = SharedInvalidMessageCounter;
     979 ECB             : 
     980                 :         /* Look up object address. */
     981 GIC       25100 :         switch (objtype)
     982 ECB             :         {
     983 CBC         287 :             case OBJECT_INDEX:
     984 ECB             :             case OBJECT_SEQUENCE:
     985                 :             case OBJECT_TABLE:
     986                 :             case OBJECT_VIEW:
     987                 :             case OBJECT_MATVIEW:
     988                 :             case OBJECT_FOREIGN_TABLE:
     989                 :                 address =
     990 GIC         287 :                     get_relation_by_qualified_name(objtype, castNode(List, object),
     991                 :                                                    &relation, lockmode,
     992                 :                                                    missing_ok);
     993             166 :                 break;
     994 GNC         143 :             case OBJECT_ATTRIBUTE:
     995                 :             case OBJECT_COLUMN:
     996                 :                 address =
     997 GIC         143 :                     get_object_address_attribute(objtype, castNode(List, object),
     998 ECB             :                                                  &relation, lockmode,
     999                 :                                                  missing_ok);
    1000 GIC          97 :                 break;
    1001 CBC          24 :             case OBJECT_DEFAULT:
    1002                 :                 address =
    1003              24 :                     get_object_address_attrdef(objtype, castNode(List, object),
    1004                 :                                                &relation, lockmode,
    1005                 :                                                missing_ok);
    1006 GIC           6 :                 break;
    1007             757 :             case OBJECT_RULE:
    1008                 :             case OBJECT_TRIGGER:
    1009                 :             case OBJECT_TABCONSTRAINT:
    1010 ECB             :             case OBJECT_POLICY:
    1011 GIC         757 :                 address = get_object_address_relobject(objtype, castNode(List, object),
    1012                 :                                                        &relation, missing_ok);
    1013 CBC         637 :                 break;
    1014              32 :             case OBJECT_DOMCONSTRAINT:
    1015                 :                 {
    1016                 :                     List       *objlist;
    1017 ECB             :                     ObjectAddress domaddr;
    1018                 :                     char       *constrname;
    1019                 : 
    1020 CBC          32 :                     objlist = castNode(List, object);
    1021              32 :                     domaddr = get_object_address_type(OBJECT_DOMAIN,
    1022 GIC          32 :                                                       linitial_node(TypeName, objlist),
    1023 ECB             :                                                       missing_ok);
    1024 GIC          26 :                     constrname = strVal(lsecond(objlist));
    1025                 : 
    1026 CBC          26 :                     address.classId = ConstraintRelationId;
    1027              26 :                     address.objectId = get_domain_constraint_oid(domaddr.objectId,
    1028                 :                                                                  constrname, missing_ok);
    1029 GIC          23 :                     address.objectSubId = 0;
    1030                 :                 }
    1031 CBC          23 :                 break;
    1032 GIC        2274 :             case OBJECT_DATABASE:
    1033 ECB             :             case OBJECT_EXTENSION:
    1034                 :             case OBJECT_TABLESPACE:
    1035                 :             case OBJECT_ROLE:
    1036                 :             case OBJECT_SCHEMA:
    1037                 :             case OBJECT_LANGUAGE:
    1038                 :             case OBJECT_FDW:
    1039                 :             case OBJECT_FOREIGN_SERVER:
    1040                 :             case OBJECT_EVENT_TRIGGER:
    1041                 :             case OBJECT_PARAMETER_ACL:
    1042                 :             case OBJECT_ACCESS_METHOD:
    1043                 :             case OBJECT_PUBLICATION:
    1044                 :             case OBJECT_SUBSCRIPTION:
    1045 GIC        2274 :                 address = get_object_address_unqualified(objtype,
    1046 CBC        2274 :                                                          castNode(String, object), missing_ok);
    1047            2207 :                 break;
    1048 GIC         676 :             case OBJECT_TYPE:
    1049 ECB             :             case OBJECT_DOMAIN:
    1050 GIC         676 :                 address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
    1051 CBC         643 :                 break;
    1052            2471 :             case OBJECT_AGGREGATE:
    1053                 :             case OBJECT_FUNCTION:
    1054                 :             case OBJECT_PROCEDURE:
    1055                 :             case OBJECT_ROUTINE:
    1056 GIC        2471 :                 address.classId = ProcedureRelationId;
    1057            2471 :                 address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
    1058            2331 :                 address.objectSubId = 0;
    1059            2331 :                 break;
    1060             158 :             case OBJECT_OPERATOR:
    1061             158 :                 address.classId = OperatorRelationId;
    1062             158 :                 address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
    1063             128 :                 address.objectSubId = 0;
    1064             128 :                 break;
    1065 CBC         109 :             case OBJECT_COLLATION:
    1066             109 :                 address.classId = CollationRelationId;
    1067             109 :                 address.objectId = get_collation_oid(castNode(List, object), missing_ok);
    1068              97 :                 address.objectSubId = 0;
    1069 GIC          97 :                 break;
    1070 CBC          93 :             case OBJECT_CONVERSION:
    1071              93 :                 address.classId = ConversionRelationId;
    1072              93 :                 address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
    1073 GIC          69 :                 address.objectSubId = 0;
    1074              69 :                 break;
    1075             229 :             case OBJECT_OPCLASS:
    1076 ECB             :             case OBJECT_OPFAMILY:
    1077 CBC         229 :                 address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
    1078             187 :                 break;
    1079              24 :             case OBJECT_AMOP:
    1080 ECB             :             case OBJECT_AMPROC:
    1081 CBC          24 :                 address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
    1082              12 :                 break;
    1083              25 :             case OBJECT_LARGEOBJECT:
    1084              25 :                 address.classId = LargeObjectRelationId;
    1085              25 :                 address.objectId = oidparse(object);
    1086              22 :                 address.objectSubId = 0;
    1087              22 :                 if (!LargeObjectExists(address.objectId))
    1088 ECB             :                 {
    1089 CBC           3 :                     if (!missing_ok)
    1090               3 :                         ereport(ERROR,
    1091 ECB             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    1092                 :                                  errmsg("large object %u does not exist",
    1093                 :                                         address.objectId)));
    1094                 :                 }
    1095 CBC          19 :                 break;
    1096 GIC          39 :             case OBJECT_CAST:
    1097 ECB             :                 {
    1098 CBC          39 :                     TypeName   *sourcetype = linitial_node(TypeName, castNode(List, object));
    1099              39 :                     TypeName   *targettype = lsecond_node(TypeName, castNode(List, object));
    1100                 :                     Oid         sourcetypeid;
    1101 ECB             :                     Oid         targettypeid;
    1102                 : 
    1103 CBC          39 :                     sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
    1104              36 :                     targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
    1105              36 :                     address.classId = CastRelationId;
    1106              33 :                     address.objectId =
    1107              36 :                         get_cast_oid(sourcetypeid, targettypeid, missing_ok);
    1108 GIC          33 :                     address.objectSubId = 0;
    1109 ECB             :                 }
    1110 CBC          33 :                 break;
    1111 GIC          25 :             case OBJECT_TRANSFORM:
    1112                 :                 {
    1113              25 :                     TypeName   *typename = linitial_node(TypeName, castNode(List, object));
    1114              25 :                     char       *langname = strVal(lsecond(castNode(List, object)));
    1115 CBC          25 :                     Oid         type_id = LookupTypeNameOid(NULL, typename, missing_ok);
    1116              21 :                     Oid         lang_id = get_language_oid(langname, missing_ok);
    1117                 : 
    1118              20 :                     address.classId = TransformRelationId;
    1119              20 :                     address.objectId =
    1120 GIC          20 :                         get_transform_oid(type_id, lang_id, missing_ok);
    1121              20 :                     address.objectSubId = 0;
    1122                 :                 }
    1123 CBC          20 :                 break;
    1124              50 :             case OBJECT_TSPARSER:
    1125              50 :                 address.classId = TSParserRelationId;
    1126              50 :                 address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
    1127              29 :                 address.objectSubId = 0;
    1128              29 :                 break;
    1129 GIC        8570 :             case OBJECT_TSDICTIONARY:
    1130 CBC        8570 :                 address.classId = TSDictionaryRelationId;
    1131            8570 :                 address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
    1132 GIC        8549 :                 address.objectSubId = 0;
    1133 CBC        8549 :                 break;
    1134             353 :             case OBJECT_TSTEMPLATE:
    1135             353 :                 address.classId = TSTemplateRelationId;
    1136             353 :                 address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
    1137 GIC         332 :                 address.objectSubId = 0;
    1138 CBC         332 :                 break;
    1139            8562 :             case OBJECT_TSCONFIGURATION:
    1140            8562 :                 address.classId = TSConfigRelationId;
    1141            8562 :                 address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
    1142 GIC        8541 :                 address.objectSubId = 0;
    1143 CBC        8541 :                 break;
    1144               9 :             case OBJECT_USER_MAPPING:
    1145               9 :                 address = get_object_address_usermapping(castNode(List, object),
    1146 ECB             :                                                          missing_ok);
    1147 CBC           6 :                 break;
    1148               9 :             case OBJECT_PUBLICATION_NAMESPACE:
    1149               9 :                 address = get_object_address_publication_schema(castNode(List, object),
    1150 ECB             :                                                                 missing_ok);
    1151 CBC           6 :                 break;
    1152              15 :             case OBJECT_PUBLICATION_REL:
    1153              15 :                 address = get_object_address_publication_rel(castNode(List, object),
    1154 ECB             :                                                              &relation,
    1155                 :                                                              missing_ok);
    1156 CBC           6 :                 break;
    1157              21 :             case OBJECT_DEFACL:
    1158              21 :                 address = get_object_address_defacl(castNode(List, object),
    1159 ECB             :                                                     missing_ok);
    1160 CBC          12 :                 break;
    1161             145 :             case OBJECT_STATISTIC_EXT:
    1162             145 :                 address.classId = StatisticExtRelationId;
    1163             145 :                 address.objectId = get_statistics_object_oid(castNode(List, object),
    1164 ECB             :                                                              missing_ok);
    1165 CBC         145 :                 address.objectSubId = 0;
    1166 GIC         145 :                 break;
    1167                 :                 /* no default, to let compiler warn about missing case */
    1168 ECB             :         }
    1169                 : 
    1170 GNC       24301 :         if (!address.classId)
    1171 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1172                 : 
    1173                 :         /*
    1174 ECB             :          * If we could not find the supplied object, return without locking.
    1175                 :          */
    1176 CBC       24301 :         if (!OidIsValid(address.objectId))
    1177                 :         {
    1178             195 :             Assert(missing_ok);
    1179             195 :             return address;
    1180 ECB             :         }
    1181                 : 
    1182                 :         /*
    1183                 :          * If we're retrying, see if we got the same answer as last time.  If
    1184                 :          * so, we're done; if not, we locked the wrong thing, so give up our
    1185                 :          * lock.
    1186                 :          */
    1187 GIC       24106 :         if (OidIsValid(old_address.classId))
    1188 ECB             :         {
    1189 GBC         130 :             if (old_address.classId == address.classId
    1190 GIC         130 :                 && old_address.objectId == address.objectId
    1191             130 :                 && old_address.objectSubId == address.objectSubId)
    1192             130 :                 break;
    1193 UIC           0 :             if (old_address.classId != RelationRelationId)
    1194 ECB             :             {
    1195 UIC           0 :                 if (IsSharedRelation(old_address.classId))
    1196 LBC           0 :                     UnlockSharedObject(old_address.classId,
    1197 ECB             :                                        old_address.objectId,
    1198                 :                                        0, lockmode);
    1199                 :                 else
    1200 UIC           0 :                     UnlockDatabaseObject(old_address.classId,
    1201                 :                                          old_address.objectId,
    1202                 :                                          0, lockmode);
    1203                 :             }
    1204                 :         }
    1205 ECB             : 
    1206                 :         /*
    1207                 :          * If we're dealing with a relation or attribute, then the relation is
    1208                 :          * already locked.  Otherwise, we lock it now.
    1209                 :          */
    1210 CBC       23976 :         if (address.classId != RelationRelationId)
    1211 EUB             :         {
    1212 GIC       23713 :             if (IsSharedRelation(address.classId))
    1213 GBC         660 :                 LockSharedObject(address.classId, address.objectId, 0,
    1214 EUB             :                                  lockmode);
    1215                 :             else
    1216 GIC       23053 :                 LockDatabaseObject(address.classId, address.objectId, 0,
    1217                 :                                    lockmode);
    1218 EUB             :         }
    1219                 : 
    1220                 :         /*
    1221                 :          * At this point, we've resolved the name to an OID and locked the
    1222                 :          * corresponding database object.  However, it's possible that by the
    1223                 :          * time we acquire the lock on the object, concurrent DDL has modified
    1224                 :          * the database in such a way that the name we originally looked up no
    1225                 :          * longer resolves to that OID.
    1226                 :          *
    1227                 :          * We can be certain that this isn't an issue if (a) no shared
    1228 ECB             :          * invalidation messages have been processed or (b) we've locked a
    1229                 :          * relation somewhere along the line.  All the relation name lookups
    1230                 :          * in this module ultimately use RangeVarGetRelid() to acquire a
    1231                 :          * relation lock, and that function protects against the same kinds of
    1232                 :          * races we're worried about here.  Even when operating on a
    1233                 :          * constraint, rule, or trigger, we still acquire AccessShareLock on
    1234                 :          * the relation, which is enough to freeze out any concurrent DDL.
    1235                 :          *
    1236                 :          * In all other cases, however, it's possible that the name we looked
    1237                 :          * up no longer refers to the object we locked, so we retry the lookup
    1238                 :          * and see whether we get the same answer.
    1239                 :          */
    1240 GIC       23976 :         if (inval_count == SharedInvalidMessageCounter || relation != NULL)
    1241                 :             break;
    1242             130 :         old_address = address;
    1243                 :     }
    1244                 : 
    1245                 :     /* Return the object address and the relation. */
    1246           23976 :     *relp = relation;
    1247           23976 :     return address;
    1248                 : }
    1249                 : 
    1250                 : /*
    1251                 :  * Return an ObjectAddress based on a RangeVar and an object name. The
    1252                 :  * name of the relation identified by the RangeVar is prepended to the
    1253                 :  * (possibly empty) list passed in as object. This is useful to find
    1254                 :  * the ObjectAddress of objects that depend on a relation. All other
    1255                 :  * considerations are exactly as for get_object_address above.
    1256                 :  */
    1257                 : ObjectAddress
    1258 CBC          23 : get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object,
    1259                 :                       Relation *relp, LOCKMODE lockmode,
    1260 ECB             :                       bool missing_ok)
    1261                 : {
    1262 GIC          23 :     if (rel)
    1263                 :     {
    1264 CBC          17 :         object = lcons(makeString(rel->relname), object);
    1265              17 :         if (rel->schemaname)
    1266 GIC           2 :             object = lcons(makeString(rel->schemaname), object);
    1267              17 :         if (rel->catalogname)
    1268 UIC           0 :             object = lcons(makeString(rel->catalogname), object);
    1269                 :     }
    1270                 : 
    1271 GIC          23 :     return get_object_address(objtype, (Node *) object,
    1272                 :                               relp, lockmode, missing_ok);
    1273                 : }
    1274                 : 
    1275                 : /*
    1276 ECB             :  * Find an ObjectAddress for a type of object that is identified by an
    1277                 :  * unqualified name.
    1278                 :  */
    1279                 : static ObjectAddress
    1280 CBC        2274 : get_object_address_unqualified(ObjectType objtype,
    1281                 :                                String *strval, bool missing_ok)
    1282 ECB             : {
    1283                 :     const char *name;
    1284                 :     ObjectAddress address;
    1285                 : 
    1286 GBC        2274 :     name = strVal(strval);
    1287                 : 
    1288                 :     /* Translate name to OID. */
    1289 CBC        2274 :     switch (objtype)
    1290                 :     {
    1291 GIC          34 :         case OBJECT_ACCESS_METHOD:
    1292              34 :             address.classId = AccessMethodRelationId;
    1293              34 :             address.objectId = get_am_oid(name, missing_ok);
    1294              28 :             address.objectSubId = 0;
    1295              28 :             break;
    1296             611 :         case OBJECT_DATABASE:
    1297             611 :             address.classId = DatabaseRelationId;
    1298 CBC         611 :             address.objectId = get_database_oid(name, missing_ok);
    1299 GIC         608 :             address.objectSubId = 0;
    1300             608 :             break;
    1301             162 :         case OBJECT_EXTENSION:
    1302             162 :             address.classId = ExtensionRelationId;
    1303             162 :             address.objectId = get_extension_oid(name, missing_ok);
    1304 CBC         156 :             address.objectSubId = 0;
    1305 GIC         156 :             break;
    1306               6 :         case OBJECT_TABLESPACE:
    1307 CBC           6 :             address.classId = TableSpaceRelationId;
    1308 GIC           6 :             address.objectId = get_tablespace_oid(name, missing_ok);
    1309 CBC           3 :             address.objectSubId = 0;
    1310               3 :             break;
    1311              22 :         case OBJECT_ROLE:
    1312              22 :             address.classId = AuthIdRelationId;
    1313              22 :             address.objectId = get_role_oid(name, missing_ok);
    1314              18 :             address.objectSubId = 0;
    1315              18 :             break;
    1316             270 :         case OBJECT_SCHEMA:
    1317             270 :             address.classId = NamespaceRelationId;
    1318             270 :             address.objectId = get_namespace_oid(name, missing_ok);
    1319             261 :             address.objectSubId = 0;
    1320             261 :             break;
    1321             678 :         case OBJECT_LANGUAGE:
    1322             678 :             address.classId = LanguageRelationId;
    1323             678 :             address.objectId = get_language_oid(name, missing_ok);
    1324             672 :             address.objectSubId = 0;
    1325             672 :             break;
    1326              97 :         case OBJECT_FDW:
    1327              97 :             address.classId = ForeignDataWrapperRelationId;
    1328              97 :             address.objectId = get_foreign_data_wrapper_oid(name, missing_ok);
    1329              88 :             address.objectSubId = 0;
    1330              88 :             break;
    1331              88 :         case OBJECT_FOREIGN_SERVER:
    1332              88 :             address.classId = ForeignServerRelationId;
    1333              88 :             address.objectId = get_foreign_server_oid(name, missing_ok);
    1334              79 :             address.objectSubId = 0;
    1335              79 :             break;
    1336              71 :         case OBJECT_EVENT_TRIGGER:
    1337              71 :             address.classId = EventTriggerRelationId;
    1338              71 :             address.objectId = get_event_trigger_oid(name, missing_ok);
    1339              65 :             address.objectSubId = 0;
    1340              65 :             break;
    1341               1 :         case OBJECT_PARAMETER_ACL:
    1342               1 :             address.classId = ParameterAclRelationId;
    1343               1 :             address.objectId = ParameterAclLookup(name, missing_ok);
    1344               1 :             address.objectSubId = 0;
    1345               1 :             break;
    1346             201 :         case OBJECT_PUBLICATION:
    1347             201 :             address.classId = PublicationRelationId;
    1348             201 :             address.objectId = get_publication_oid(name, missing_ok);
    1349             198 :             address.objectSubId = 0;
    1350             198 :             break;
    1351              33 :         case OBJECT_SUBSCRIPTION:
    1352              33 :             address.classId = SubscriptionRelationId;
    1353              33 :             address.objectId = get_subscription_oid(name, missing_ok);
    1354              30 :             address.objectSubId = 0;
    1355              30 :             break;
    1356 LBC           0 :         default:
    1357 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1358 ECB             :             /* placate compiler, which doesn't know elog won't return */
    1359                 :             address.classId = InvalidOid;
    1360                 :             address.objectId = InvalidOid;
    1361                 :             address.objectSubId = 0;
    1362                 :     }
    1363                 : 
    1364 CBC        2207 :     return address;
    1365 ECB             : }
    1366                 : 
    1367                 : /*
    1368                 :  * Locate a relation by qualified name.
    1369                 :  */
    1370                 : static ObjectAddress
    1371 CBC         287 : get_relation_by_qualified_name(ObjectType objtype, List *object,
    1372 ECB             :                                Relation *relp, LOCKMODE lockmode,
    1373                 :                                bool missing_ok)
    1374 EUB             : {
    1375                 :     Relation    relation;
    1376                 :     ObjectAddress address;
    1377                 : 
    1378 GIC         287 :     address.classId = RelationRelationId;
    1379             287 :     address.objectId = InvalidOid;
    1380             287 :     address.objectSubId = 0;
    1381                 : 
    1382 CBC         287 :     relation = relation_openrv_extended(makeRangeVarFromNameList(object),
    1383                 :                                         lockmode, missing_ok);
    1384 GIC         166 :     if (!relation)
    1385 UIC           0 :         return address;
    1386                 : 
    1387 GIC         166 :     switch (objtype)
    1388                 :     {
    1389 CBC          55 :         case OBJECT_INDEX:
    1390 GIC          55 :             if (relation->rd_rel->relkind != RELKIND_INDEX &&
    1391               9 :                 relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
    1392 UIC           0 :                 ereport(ERROR,
    1393                 :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1394                 :                          errmsg("\"%s\" is not an index",
    1395                 :                                 RelationGetRelationName(relation))));
    1396 CBC          55 :             break;
    1397              14 :         case OBJECT_SEQUENCE:
    1398              14 :             if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
    1399 UIC           0 :                 ereport(ERROR,
    1400 ECB             :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1401                 :                          errmsg("\"%s\" is not a sequence",
    1402                 :                                 RelationGetRelationName(relation))));
    1403 GBC          14 :             break;
    1404 GIC          39 :         case OBJECT_TABLE:
    1405 CBC          39 :             if (relation->rd_rel->relkind != RELKIND_RELATION &&
    1406 GIC           9 :                 relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
    1407 LBC           0 :                 ereport(ERROR,
    1408 ECB             :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1409                 :                          errmsg("\"%s\" is not a table",
    1410 EUB             :                                 RelationGetRelationName(relation))));
    1411 GIC          39 :             break;
    1412              28 :         case OBJECT_VIEW:
    1413              28 :             if (relation->rd_rel->relkind != RELKIND_VIEW)
    1414 LBC           0 :                 ereport(ERROR,
    1415 ECB             :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1416                 :                          errmsg("\"%s\" is not a view",
    1417 EUB             :                                 RelationGetRelationName(relation))));
    1418 GIC          28 :             break;
    1419              13 :         case OBJECT_MATVIEW:
    1420              13 :             if (relation->rd_rel->relkind != RELKIND_MATVIEW)
    1421 LBC           0 :                 ereport(ERROR,
    1422 ECB             :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1423                 :                          errmsg("\"%s\" is not a materialized view",
    1424                 :                                 RelationGetRelationName(relation))));
    1425 GBC          13 :             break;
    1426 GIC          17 :         case OBJECT_FOREIGN_TABLE:
    1427              17 :             if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
    1428 UIC           0 :                 ereport(ERROR,
    1429 ECB             :                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1430                 :                          errmsg("\"%s\" is not a foreign table",
    1431                 :                                 RelationGetRelationName(relation))));
    1432 GBC          17 :             break;
    1433 UIC           0 :         default:
    1434 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1435                 :             break;
    1436 ECB             :     }
    1437                 : 
    1438                 :     /* Done. */
    1439 GBC         166 :     address.objectId = RelationGetRelid(relation);
    1440 GIC         166 :     *relp = relation;
    1441                 : 
    1442             166 :     return address;
    1443 ECB             : }
    1444                 : 
    1445                 : /*
    1446 EUB             :  * Find object address for an object that is attached to a relation.
    1447                 :  *
    1448                 :  * Note that we take only an AccessShareLock on the relation.  We need not
    1449                 :  * pass down the LOCKMODE from get_object_address(), because that is the lock
    1450 ECB             :  * mode for the object itself, not the relation to which it is attached.
    1451 EUB             :  */
    1452                 : static ObjectAddress
    1453 GIC         757 : get_object_address_relobject(ObjectType objtype, List *object,
    1454                 :                              Relation *relp, bool missing_ok)
    1455                 : {
    1456                 :     ObjectAddress address;
    1457 CBC         757 :     Relation    relation = NULL;
    1458 ECB             :     int         nnames;
    1459                 :     const char *depname;
    1460                 :     List       *relname;
    1461                 :     Oid         reloid;
    1462                 : 
    1463                 :     /* Extract name of dependent object. */
    1464 GIC         757 :     depname = strVal(llast(object));
    1465                 : 
    1466                 :     /* Separate relation name from dependent object name. */
    1467             757 :     nnames = list_length(object);
    1468             757 :     if (nnames < 2)
    1469              24 :         ereport(ERROR,
    1470                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1471 ECB             :                  errmsg("must specify relation and object name")));
    1472                 : 
    1473                 :     /* Extract relation name and open relation. */
    1474 GNC         733 :     relname = list_copy_head(object, nnames - 1);
    1475 CBC         733 :     relation = table_openrv_extended(makeRangeVarFromNameList(relname),
    1476                 :                                      AccessShareLock,
    1477                 :                                      missing_ok);
    1478                 : 
    1479 GIC         667 :     reloid = relation ? RelationGetRelid(relation) : InvalidOid;
    1480                 : 
    1481             667 :     switch (objtype)
    1482 ECB             :     {
    1483 GIC         113 :         case OBJECT_RULE:
    1484             113 :             address.classId = RewriteRelationId;
    1485 CBC         107 :             address.objectId = relation ?
    1486             113 :                 get_rewrite_oid(reloid, depname, missing_ok) : InvalidOid;
    1487             107 :             address.objectSubId = 0;
    1488 GIC         107 :             break;
    1489             378 :         case OBJECT_TRIGGER:
    1490             378 :             address.classId = TriggerRelationId;
    1491             366 :             address.objectId = relation ?
    1492 CBC         378 :                 get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
    1493             366 :             address.objectSubId = 0;
    1494 GIC         366 :             break;
    1495              94 :         case OBJECT_TABCONSTRAINT:
    1496              94 :             address.classId = ConstraintRelationId;
    1497 CBC          88 :             address.objectId = relation ?
    1498 GIC          94 :                 get_relation_constraint_oid(reloid, depname, missing_ok) :
    1499 ECB             :                 InvalidOid;
    1500 GIC          88 :             address.objectSubId = 0;
    1501 CBC          88 :             break;
    1502              82 :         case OBJECT_POLICY:
    1503              82 :             address.classId = PolicyRelationId;
    1504              76 :             address.objectId = relation ?
    1505              82 :                 get_relation_policy_oid(reloid, depname, missing_ok) :
    1506 ECB             :                 InvalidOid;
    1507 CBC          76 :             address.objectSubId = 0;
    1508              76 :             break;
    1509 LBC           0 :         default:
    1510 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1511 ECB             :     }
    1512                 : 
    1513                 :     /* Avoid relcache leak when object not found. */
    1514 CBC         637 :     if (!OidIsValid(address.objectId))
    1515 ECB             :     {
    1516 CBC          24 :         if (relation != NULL)
    1517 GIC           6 :             table_close(relation, AccessShareLock);
    1518 ECB             : 
    1519 CBC          24 :         relation = NULL;        /* department of accident prevention */
    1520              24 :         return address;
    1521 ECB             :     }
    1522                 : 
    1523                 :     /* Done. */
    1524 GIC         613 :     *relp = relation;
    1525 CBC         613 :     return address;
    1526 ECB             : }
    1527 EUB             : 
    1528                 : /*
    1529                 :  * Find the ObjectAddress for an attribute.
    1530                 :  */
    1531                 : static ObjectAddress
    1532 CBC         143 : get_object_address_attribute(ObjectType objtype, List *object,
    1533                 :                              Relation *relp, LOCKMODE lockmode,
    1534 ECB             :                              bool missing_ok)
    1535                 : {
    1536                 :     ObjectAddress address;
    1537                 :     List       *relname;
    1538                 :     Oid         reloid;
    1539                 :     Relation    relation;
    1540                 :     const char *attname;
    1541                 :     AttrNumber  attnum;
    1542                 : 
    1543                 :     /* Extract relation name and open relation. */
    1544 GIC         143 :     if (list_length(object) < 2)
    1545              13 :         ereport(ERROR,
    1546                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1547                 :                  errmsg("column name must be qualified")));
    1548             130 :     attname = strVal(llast(object));
    1549 GNC         130 :     relname = list_copy_head(object, list_length(object) - 1);
    1550 ECB             :     /* XXX no missing_ok support here */
    1551 GIC         130 :     relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
    1552             106 :     reloid = RelationGetRelid(relation);
    1553                 : 
    1554                 :     /* Look up attribute and construct return value. */
    1555             106 :     attnum = get_attnum(reloid, attname);
    1556             106 :     if (attnum == InvalidAttrNumber)
    1557                 :     {
    1558               9 :         if (!missing_ok)
    1559               9 :             ereport(ERROR,
    1560                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    1561                 :                      errmsg("column \"%s\" of relation \"%s\" does not exist",
    1562 ECB             :                             attname, NameListToString(relname))));
    1563                 : 
    1564 UIC           0 :         address.classId = RelationRelationId;
    1565               0 :         address.objectId = InvalidOid;
    1566 LBC           0 :         address.objectSubId = InvalidAttrNumber;
    1567               0 :         relation_close(relation, lockmode);
    1568 UIC           0 :         return address;
    1569 ECB             :     }
    1570                 : 
    1571 GIC          97 :     address.classId = RelationRelationId;
    1572              97 :     address.objectId = reloid;
    1573 CBC          97 :     address.objectSubId = attnum;
    1574 ECB             : 
    1575 GIC          97 :     *relp = relation;
    1576 CBC          97 :     return address;
    1577 ECB             : }
    1578                 : 
    1579                 : /*
    1580                 :  * Find the ObjectAddress for an attribute's default value.
    1581                 :  */
    1582 EUB             : static ObjectAddress
    1583 GBC          24 : get_object_address_attrdef(ObjectType objtype, List *object,
    1584 EUB             :                            Relation *relp, LOCKMODE lockmode,
    1585                 :                            bool missing_ok)
    1586                 : {
    1587                 :     ObjectAddress address;
    1588                 :     List       *relname;
    1589 ECB             :     Oid         reloid;
    1590                 :     Relation    relation;
    1591                 :     const char *attname;
    1592                 :     AttrNumber  attnum;
    1593                 :     TupleDesc   tupdesc;
    1594                 :     Oid         defoid;
    1595                 : 
    1596                 :     /* Extract relation name and open relation. */
    1597 GIC          24 :     if (list_length(object) < 2)
    1598               6 :         ereport(ERROR,
    1599                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1600                 :                  errmsg("column name must be qualified")));
    1601 CBC          18 :     attname = strVal(llast(object));
    1602 GNC          18 :     relname = list_copy_head(object, list_length(object) - 1);
    1603                 :     /* XXX no missing_ok support here */
    1604 GIC          18 :     relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
    1605               6 :     reloid = RelationGetRelid(relation);
    1606                 : 
    1607               6 :     tupdesc = RelationGetDescr(relation);
    1608                 : 
    1609                 :     /* Look up attribute number and fetch the pg_attrdef OID */
    1610               6 :     attnum = get_attnum(reloid, attname);
    1611               6 :     defoid = InvalidOid;
    1612               6 :     if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
    1613               6 :         defoid = GetAttrDefaultOid(reloid, attnum);
    1614               6 :     if (!OidIsValid(defoid))
    1615 ECB             :     {
    1616 LBC           0 :         if (!missing_ok)
    1617 UIC           0 :             ereport(ERROR,
    1618                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    1619 ECB             :                      errmsg("default value for column \"%s\" of relation \"%s\" does not exist",
    1620                 :                             attname, NameListToString(relname))));
    1621                 : 
    1622 LBC           0 :         address.classId = AttrDefaultRelationId;
    1623               0 :         address.objectId = InvalidOid;
    1624 UIC           0 :         address.objectSubId = InvalidAttrNumber;
    1625 LBC           0 :         relation_close(relation, lockmode);
    1626 UIC           0 :         return address;
    1627                 :     }
    1628 ECB             : 
    1629 CBC           6 :     address.classId = AttrDefaultRelationId;
    1630               6 :     address.objectId = defoid;
    1631               6 :     address.objectSubId = 0;
    1632 ECB             : 
    1633 GIC           6 :     *relp = relation;
    1634 GBC           6 :     return address;
    1635 EUB             : }
    1636                 : 
    1637                 : /*
    1638                 :  * Find the ObjectAddress for a type or domain
    1639                 :  */
    1640                 : static ObjectAddress
    1641 GBC         756 : get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
    1642 EUB             : {
    1643                 :     ObjectAddress address;
    1644                 :     Type        tup;
    1645                 : 
    1646 GIC         756 :     address.classId = TypeRelationId;
    1647 CBC         756 :     address.objectId = InvalidOid;
    1648             756 :     address.objectSubId = 0;
    1649 ECB             : 
    1650 GIC         756 :     tup = LookupTypeName(NULL, typename, NULL, missing_ok);
    1651 CBC         756 :     if (!HeapTupleIsValid(tup))
    1652 ECB             :     {
    1653 GIC          52 :         if (!missing_ok)
    1654              39 :             ereport(ERROR,
    1655                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    1656                 :                      errmsg("type \"%s\" does not exist",
    1657                 :                             TypeNameToString(typename))));
    1658              13 :         return address;
    1659 ECB             :     }
    1660 GIC         704 :     address.objectId = typeTypeId(tup);
    1661                 : 
    1662             704 :     if (objtype == OBJECT_DOMAIN)
    1663                 :     {
    1664 CBC         213 :         if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN)
    1665 LBC           0 :             ereport(ERROR,
    1666 ECB             :                     (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1667                 :                      errmsg("\"%s\" is not a domain",
    1668                 :                             TypeNameToString(typename))));
    1669                 :     }
    1670                 : 
    1671 CBC         704 :     ReleaseSysCache(tup);
    1672 ECB             : 
    1673 GIC         704 :     return address;
    1674                 : }
    1675                 : 
    1676 ECB             : /*
    1677                 :  * Find the ObjectAddress for an opclass or opfamily.
    1678                 :  */
    1679                 : static ObjectAddress
    1680 CBC         253 : get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
    1681                 : {
    1682 ECB             :     Oid         amoid;
    1683 EUB             :     ObjectAddress address;
    1684                 : 
    1685                 :     /* XXX no missing_ok support here */
    1686 GIC         253 :     amoid = get_index_am_oid(strVal(linitial(object)), false);
    1687             217 :     object = list_copy_tail(object, 1);
    1688                 : 
    1689 CBC         217 :     switch (objtype)
    1690                 :     {
    1691              85 :         case OBJECT_OPCLASS:
    1692 GIC          85 :             address.classId = OperatorClassRelationId;
    1693              85 :             address.objectId = get_opclass_oid(amoid, object, missing_ok);
    1694              82 :             address.objectSubId = 0;
    1695              82 :             break;
    1696             132 :         case OBJECT_OPFAMILY:
    1697             132 :             address.classId = OperatorFamilyRelationId;
    1698 CBC         132 :             address.objectId = get_opfamily_oid(amoid, object, missing_ok);
    1699 GIC         129 :             address.objectSubId = 0;
    1700             129 :             break;
    1701 UIC           0 :         default:
    1702 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1703                 :             /* placate compiler, which doesn't know elog won't return */
    1704 ECB             :             address.classId = InvalidOid;
    1705                 :             address.objectId = InvalidOid;
    1706                 :             address.objectSubId = 0;
    1707                 :     }
    1708                 : 
    1709 CBC         211 :     return address;
    1710 ECB             : }
    1711                 : 
    1712                 : /*
    1713                 :  * Find the ObjectAddress for an opclass/opfamily member.
    1714                 :  *
    1715                 :  * (The returned address corresponds to a pg_amop/pg_amproc object).
    1716                 :  */
    1717                 : static ObjectAddress
    1718 CBC          24 : get_object_address_opf_member(ObjectType objtype,
    1719 EUB             :                               List *object, bool missing_ok)
    1720                 : {
    1721                 :     ObjectAddress famaddr;
    1722                 :     ObjectAddress address;
    1723                 :     ListCell   *cell;
    1724                 :     List       *copy;
    1725                 :     TypeName   *typenames[2];
    1726                 :     Oid         typeoids[2];
    1727 ECB             :     int         membernum;
    1728                 :     int         i;
    1729                 : 
    1730                 :     /*
    1731                 :      * The last element of the object list contains the strategy or procedure
    1732                 :      * number.  We need to strip that out before getting the opclass/family
    1733                 :      * address.  The rest can be used directly by get_object_address_opcf().
    1734                 :      */
    1735 GIC          24 :     membernum = atoi(strVal(llast(linitial(object))));
    1736 GNC          24 :     copy = list_copy_head(linitial(object), list_length(linitial(object)) - 1);
    1737                 : 
    1738                 :     /* no missing_ok support here */
    1739 GIC          24 :     famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false);
    1740                 : 
    1741                 :     /* find out left/right type names and OIDs */
    1742              24 :     typenames[0] = typenames[1] = NULL;
    1743              24 :     typeoids[0] = typeoids[1] = InvalidOid;
    1744              24 :     i = 0;
    1745              48 :     foreach(cell, lsecond(object))
    1746                 :     {
    1747                 :         ObjectAddress typaddr;
    1748                 : 
    1749              48 :         typenames[i] = lfirst_node(TypeName, cell);
    1750              48 :         typaddr = get_object_address_type(OBJECT_TYPE, typenames[i], missing_ok);
    1751              48 :         typeoids[i] = typaddr.objectId;
    1752              48 :         if (++i >= 2)
    1753 CBC          24 :             break;
    1754 ECB             :     }
    1755                 : 
    1756 GIC          24 :     switch (objtype)
    1757 ECB             :     {
    1758 GIC          12 :         case OBJECT_AMOP:
    1759                 :             {
    1760 ECB             :                 HeapTuple   tp;
    1761                 : 
    1762 CBC          12 :                 ObjectAddressSet(address, AccessMethodOperatorRelationId,
    1763 ECB             :                                  InvalidOid);
    1764                 : 
    1765 GIC          12 :                 tp = SearchSysCache4(AMOPSTRATEGY,
    1766                 :                                      ObjectIdGetDatum(famaddr.objectId),
    1767 ECB             :                                      ObjectIdGetDatum(typeoids[0]),
    1768                 :                                      ObjectIdGetDatum(typeoids[1]),
    1769                 :                                      Int16GetDatum(membernum));
    1770 CBC          12 :                 if (!HeapTupleIsValid(tp))
    1771 ECB             :                 {
    1772 GIC           6 :                     if (!missing_ok)
    1773               6 :                         ereport(ERROR,
    1774 ECB             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    1775                 :                                  errmsg("operator %d (%s, %s) of %s does not exist",
    1776                 :                                         membernum,
    1777                 :                                         TypeNameToString(typenames[0]),
    1778                 :                                         TypeNameToString(typenames[1]),
    1779                 :                                         getObjectDescription(&famaddr, false))));
    1780                 :                 }
    1781                 :                 else
    1782                 :                 {
    1783 CBC           6 :                     address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
    1784 GIC           6 :                     ReleaseSysCache(tp);
    1785                 :                 }
    1786                 :             }
    1787               6 :             break;
    1788 ECB             : 
    1789 GIC          12 :         case OBJECT_AMPROC:
    1790 ECB             :             {
    1791                 :                 HeapTuple   tp;
    1792                 : 
    1793 GIC          12 :                 ObjectAddressSet(address, AccessMethodProcedureRelationId,
    1794                 :                                  InvalidOid);
    1795                 : 
    1796              12 :                 tp = SearchSysCache4(AMPROCNUM,
    1797                 :                                      ObjectIdGetDatum(famaddr.objectId),
    1798                 :                                      ObjectIdGetDatum(typeoids[0]),
    1799                 :                                      ObjectIdGetDatum(typeoids[1]),
    1800                 :                                      Int16GetDatum(membernum));
    1801 CBC          12 :                 if (!HeapTupleIsValid(tp))
    1802 ECB             :                 {
    1803 GIC           6 :                     if (!missing_ok)
    1804               6 :                         ereport(ERROR,
    1805 ECB             :                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    1806                 :                                  errmsg("function %d (%s, %s) of %s does not exist",
    1807                 :                                         membernum,
    1808                 :                                         TypeNameToString(typenames[0]),
    1809                 :                                         TypeNameToString(typenames[1]),
    1810                 :                                         getObjectDescription(&famaddr, false))));
    1811                 :                 }
    1812                 :                 else
    1813                 :                 {
    1814 CBC           6 :                     address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
    1815 GIC           6 :                     ReleaseSysCache(tp);
    1816                 :                 }
    1817                 :             }
    1818               6 :             break;
    1819 LBC           0 :         default:
    1820 UNC           0 :             elog(ERROR, "unrecognized object type: %d", (int) objtype);
    1821 ECB             :     }
    1822                 : 
    1823 GIC          12 :     return address;
    1824                 : }
    1825                 : 
    1826                 : /*
    1827                 :  * Find the ObjectAddress for a user mapping.
    1828                 :  */
    1829                 : static ObjectAddress
    1830               9 : get_object_address_usermapping(List *object, bool missing_ok)
    1831                 : {
    1832 ECB             :     ObjectAddress address;
    1833                 :     Oid         userid;
    1834                 :     char       *username;
    1835                 :     char       *servername;
    1836                 :     ForeignServer *server;
    1837 EUB             :     HeapTuple   tp;
    1838                 : 
    1839 GIC           9 :     ObjectAddressSet(address, UserMappingRelationId, InvalidOid);
    1840                 : 
    1841 ECB             :     /* fetch string names from input lists, for error messages */
    1842 GIC           9 :     username = strVal(linitial(object));
    1843               9 :     servername = strVal(lsecond(object));
    1844                 : 
    1845                 :     /* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
    1846               9 :     if (strcmp(username, "public") == 0)
    1847 UIC           0 :         userid = InvalidOid;
    1848 ECB             :     else
    1849                 :     {
    1850 GIC           9 :         tp = SearchSysCache1(AUTHNAME,
    1851                 :                              CStringGetDatum(username));
    1852               9 :         if (!HeapTupleIsValid(tp))
    1853                 :         {
    1854               3 :             if (!missing_ok)
    1855               3 :                 ereport(ERROR,
    1856                 :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    1857 ECB             :                          errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
    1858                 :                                 username, servername)));
    1859 UIC           0 :             return address;
    1860 ECB             :         }
    1861 CBC           6 :         userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
    1862 GIC           6 :         ReleaseSysCache(tp);
    1863                 :     }
    1864 ECB             : 
    1865 EUB             :     /* Now look up the pg_user_mapping tuple */
    1866 GIC           6 :     server = GetForeignServerByName(servername, true);
    1867               6 :     if (!server)
    1868 ECB             :     {
    1869 UIC           0 :         if (!missing_ok)
    1870 LBC           0 :             ereport(ERROR,
    1871                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    1872 ECB             :                      errmsg("server \"%s\" does not exist", servername)));
    1873 LBC           0 :         return address;
    1874                 :     }
    1875 GIC           6 :     tp = SearchSysCache2(USERMAPPINGUSERSERVER,
    1876                 :                          ObjectIdGetDatum(userid),
    1877 EUB             :                          ObjectIdGetDatum(server->serverid));
    1878 GIC           6 :     if (!HeapTupleIsValid(tp))
    1879 ECB             :     {
    1880 LBC           0 :         if (!missing_ok)
    1881 UIC           0 :             ereport(ERROR,
    1882                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    1883                 :                      errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
    1884 ECB             :                             username, servername)));
    1885 LBC           0 :         return address;
    1886                 :     }
    1887 EUB             : 
    1888 GBC           6 :     address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
    1889                 : 
    1890 GIC           6 :     ReleaseSysCache(tp);
    1891 EUB             : 
    1892 GIC           6 :     return address;
    1893 ECB             : }
    1894                 : 
    1895                 : /*
    1896                 :  * Find the ObjectAddress for a publication relation.  The first element of
    1897                 :  * the object parameter is the relation name, the second is the
    1898 EUB             :  * publication name.
    1899                 :  */
    1900                 : static ObjectAddress
    1901 GIC          15 : get_object_address_publication_rel(List *object,
    1902                 :                                    Relation *relp, bool missing_ok)
    1903 EUB             : {
    1904                 :     ObjectAddress address;
    1905                 :     Relation    relation;
    1906 ECB             :     List       *relname;
    1907                 :     char       *pubname;
    1908                 :     Publication *pub;
    1909                 : 
    1910 CBC          15 :     ObjectAddressSet(address, PublicationRelRelationId, InvalidOid);
    1911                 : 
    1912 GIC          15 :     relname = linitial(object);
    1913              15 :     relation = relation_openrv_extended(makeRangeVarFromNameList(relname),
    1914                 :                                         AccessShareLock, missing_ok);
    1915               6 :     if (!relation)
    1916 UIC           0 :         return address;
    1917                 : 
    1918                 :     /* fetch publication name from input list */
    1919 CBC           6 :     pubname = strVal(lsecond(object));
    1920                 : 
    1921                 :     /* Now look up the pg_publication tuple */
    1922 GIC           6 :     pub = GetPublicationByName(pubname, missing_ok);
    1923               6 :     if (!pub)
    1924                 :     {
    1925 UIC           0 :         relation_close(relation, AccessShareLock);
    1926               0 :         return address;
    1927                 :     }
    1928 ECB             : 
    1929                 :     /* Find the publication relation mapping in syscache. */
    1930 CBC           6 :     address.objectId =
    1931               6 :         GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid,
    1932                 :                         ObjectIdGetDatum(RelationGetRelid(relation)),
    1933 ECB             :                         ObjectIdGetDatum(pub->oid));
    1934 GBC           6 :     if (!OidIsValid(address.objectId))
    1935                 :     {
    1936 UIC           0 :         if (!missing_ok)
    1937 LBC           0 :             ereport(ERROR,
    1938                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    1939                 :                      errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
    1940 ECB             :                             RelationGetRelationName(relation), pubname)));
    1941 LBC           0 :         relation_close(relation, AccessShareLock);
    1942 UIC           0 :         return address;
    1943 EUB             :     }
    1944                 : 
    1945 GIC           6 :     *relp = relation;
    1946               6 :     return address;
    1947                 : }
    1948 ECB             : 
    1949                 : /*
    1950                 :  * Find the ObjectAddress for a publication schema. The first element of the
    1951                 :  * object parameter is the schema name, the second is the publication name.
    1952                 :  */
    1953                 : static ObjectAddress
    1954 GBC           9 : get_object_address_publication_schema(List *object, bool missing_ok)
    1955 EUB             : {
    1956                 :     ObjectAddress address;
    1957                 :     Publication *pub;
    1958                 :     char       *pubname;
    1959                 :     char       *schemaname;
    1960                 :     Oid         schemaid;
    1961                 : 
    1962 GIC           9 :     ObjectAddressSet(address, PublicationNamespaceRelationId, InvalidOid);
    1963 ECB             : 
    1964                 :     /* Fetch schema name and publication name from input list */
    1965 GIC           9 :     schemaname = strVal(linitial(object));
    1966               9 :     pubname = strVal(lsecond(object));
    1967                 : 
    1968               9 :     schemaid = get_namespace_oid(schemaname, missing_ok);
    1969               6 :     if (!OidIsValid(schemaid))
    1970 UIC           0 :         return address;
    1971                 : 
    1972 ECB             :     /* Now look up the pg_publication tuple */
    1973 GIC           6 :     pub = GetPublicationByName(pubname, missing_ok);
    1974               6 :     if (!pub)
    1975 UIC           0 :         return address;
    1976                 : 
    1977                 :     /* Find the publication schema mapping in syscache */
    1978 GIC           6 :     address.objectId =
    1979               6 :         GetSysCacheOid2(PUBLICATIONNAMESPACEMAP,
    1980 ECB             :                         Anum_pg_publication_namespace_oid,
    1981                 :                         ObjectIdGetDatum(schemaid),
    1982                 :                         ObjectIdGetDatum(pub->oid));
    1983 CBC           6 :     if (!OidIsValid(address.objectId) && !missing_ok)
    1984 LBC           0 :         ereport(ERROR,
    1985                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
    1986 ECB             :                  errmsg("publication schema \"%s\" in publication \"%s\" does not exist",
    1987                 :                         schemaname, pubname)));
    1988 EUB             : 
    1989 GIC           6 :     return address;
    1990                 : }
    1991 ECB             : 
    1992                 : /*
    1993 EUB             :  * Find the ObjectAddress for a default ACL.
    1994                 :  */
    1995                 : static ObjectAddress
    1996 CBC          21 : get_object_address_defacl(List *object, bool missing_ok)
    1997 ECB             : {
    1998                 :     HeapTuple   tp;
    1999                 :     Oid         userid;
    2000                 :     Oid         schemaid;
    2001                 :     char       *username;
    2002 EUB             :     char       *schema;
    2003                 :     char        objtype;
    2004                 :     char       *objtype_str;
    2005                 :     ObjectAddress address;
    2006                 : 
    2007 CBC          21 :     ObjectAddressSet(address, DefaultAclRelationId, InvalidOid);
    2008                 : 
    2009                 :     /*
    2010                 :      * First figure out the textual attributes so that they can be used for
    2011                 :      * error reporting.
    2012                 :      */
    2013 GIC          21 :     username = strVal(lsecond(object));
    2014 CBC          21 :     if (list_length(object) >= 3)
    2015 GIC          12 :         schema = (char *) strVal(lthird(object));
    2016                 :     else
    2017               9 :         schema = NULL;
    2018                 : 
    2019                 :     /*
    2020                 :      * Decode defaclobjtype.  Only first char is considered; the rest of the
    2021                 :      * string, if any, is blissfully ignored.
    2022                 :      */
    2023              21 :     objtype = ((char *) strVal(linitial(object)))[0];
    2024              21 :     switch (objtype)
    2025 ECB             :     {
    2026 GIC          12 :         case DEFACLOBJ_RELATION:
    2027              12 :             objtype_str = "tables";
    2028              12 :             break;
    2029 UIC           0 :         case DEFACLOBJ_SEQUENCE:
    2030               0 :             objtype_str = "sequences";
    2031 LBC           0 :             break;
    2032               0 :         case DEFACLOBJ_FUNCTION:
    2033               0 :             objtype_str = "functions";
    2034 UIC           0 :             break;
    2035 LBC           0 :         case DEFACLOBJ_TYPE:
    2036 UIC           0 :             objtype_str = "types";
    2037               0 :             break;
    2038               0 :         case DEFACLOBJ_NAMESPACE:
    2039               0 :             objtype_str = "schemas";
    2040               0 :             break;
    2041 CBC           9 :         default:
    2042               9 :             ereport(ERROR,
    2043                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2044 ECB             :                      errmsg("unrecognized default ACL object type \"%c\"", objtype),
    2045                 :                      errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
    2046                 :                              DEFACLOBJ_RELATION,
    2047 EUB             :                              DEFACLOBJ_SEQUENCE,
    2048                 :                              DEFACLOBJ_FUNCTION,
    2049                 :                              DEFACLOBJ_TYPE,
    2050                 :                              DEFACLOBJ_NAMESPACE)));
    2051                 :     }
    2052                 : 
    2053                 :     /*
    2054                 :      * Look up user ID.  Behave as "default ACL not found" if the user doesn't
    2055                 :      * exist.
    2056                 :      */
    2057 GBC          12 :     tp = SearchSysCache1(AUTHNAME,
    2058 EUB             :                          CStringGetDatum(username));
    2059 CBC          12 :     if (!HeapTupleIsValid(tp))
    2060 LBC           0 :         goto not_found;
    2061 GIC          12 :     userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
    2062              12 :     ReleaseSysCache(tp);
    2063                 : 
    2064                 :     /*
    2065                 :      * If a schema name was given, look up its OID.  If it doesn't exist,
    2066                 :      * behave as "default ACL not found".
    2067                 :      */
    2068              12 :     if (schema)
    2069                 :     {
    2070               6 :         schemaid = get_namespace_oid(schema, true);
    2071               6 :         if (schemaid == InvalidOid)
    2072 UIC           0 :             goto not_found;
    2073                 :     }
    2074                 :     else
    2075 CBC           6 :         schemaid = InvalidOid;
    2076                 : 
    2077 ECB             :     /* Finally, look up the pg_default_acl object */
    2078 GBC          12 :     tp = SearchSysCache3(DEFACLROLENSPOBJ,
    2079 ECB             :                          ObjectIdGetDatum(userid),
    2080                 :                          ObjectIdGetDatum(schemaid),
    2081                 :                          CharGetDatum(objtype));
    2082 GIC          12 :     if (!HeapTupleIsValid(tp))
    2083 UIC           0 :         goto not_found;
    2084                 : 
    2085 GIC          12 :     address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid;
    2086 CBC          12 :     ReleaseSysCache(tp);
    2087                 : 
    2088              12 :     return address;
    2089 ECB             : 
    2090 UBC           0 : not_found:
    2091 UIC           0 :     if (!missing_ok)
    2092                 :     {
    2093 LBC           0 :         if (schema)
    2094 UIC           0 :             ereport(ERROR,
    2095                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    2096 ECB             :                      errmsg("default ACL for user \"%s\" in schema \"%s\" on %s does not exist",
    2097                 :                             username, schema, objtype_str)));
    2098                 :         else
    2099 UIC           0 :             ereport(ERROR,
    2100 ECB             :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
    2101 EUB             :                      errmsg("default ACL for user \"%s\" on %s does not exist",
    2102                 :                             username, objtype_str)));
    2103 ECB             :     }
    2104 LBC           0 :     return address;
    2105                 : }
    2106 ECB             : 
    2107                 : /*
    2108 EUB             :  * Convert an array of TEXT into a List of string Values, as emitted by the
    2109                 :  * parser, which is what get_object_address uses as input.
    2110                 :  */
    2111                 : static List *
    2112 GBC        1694 : textarray_to_strvaluelist(ArrayType *arr)
    2113                 : {
    2114                 :     Datum      *elems;
    2115                 :     bool       *nulls;
    2116                 :     int         nelems;
    2117            1694 :     List       *list = NIL;
    2118                 :     int         i;
    2119                 : 
    2120 GNC        1694 :     deconstruct_array_builtin(arr, TEXTOID, &elems, &nulls, &nelems);
    2121 EUB             : 
    2122 GIC        3693 :     for (i = 0; i < nelems; i++)
    2123                 :     {
    2124            2002 :         if (nulls[i])
    2125               3 :             ereport(ERROR,
    2126                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2127                 :                      errmsg("name or argument lists may not contain nulls")));
    2128            1999 :         list = lappend(list, makeString(TextDatumGetCString(elems[i])));
    2129 ECB             :     }
    2130                 : 
    2131 GIC        1691 :     return list;
    2132                 : }
    2133                 : 
    2134 ECB             : /*
    2135                 :  * SQL-callable version of get_object_address
    2136                 :  */
    2137                 : Datum
    2138 GIC        1042 : pg_get_object_address(PG_FUNCTION_ARGS)
    2139 ECB             : {
    2140 GIC        1042 :     char       *ttype = TextDatumGetCString(PG_GETARG_DATUM(0));
    2141 CBC        1042 :     ArrayType  *namearr = PG_GETARG_ARRAYTYPE_P(1);
    2142            1042 :     ArrayType  *argsarr = PG_GETARG_ARRAYTYPE_P(2);
    2143                 :     int         itype;
    2144                 :     ObjectType  type;
    2145            1042 :     List       *name = NIL;
    2146 GIC        1042 :     TypeName   *typename = NULL;
    2147            1042 :     List       *args = NIL;
    2148 CBC        1042 :     Node       *objnode = NULL;
    2149                 :     ObjectAddress addr;
    2150                 :     TupleDesc   tupdesc;
    2151                 :     Datum       values[3];
    2152                 :     bool        nulls[3];
    2153                 :     HeapTuple   htup;
    2154                 :     Relation    relation;
    2155 ECB             : 
    2156                 :     /* Decode object type, raise error if unknown */
    2157 CBC        1042 :     itype = read_objtype_from_string(ttype);
    2158            1039 :     if (itype < 0)
    2159              18 :         ereport(ERROR,
    2160                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2161                 :                  errmsg("unsupported object type \"%s\"", ttype)));
    2162            1021 :     type = (ObjectType) itype;
    2163 ECB             : 
    2164                 :     /*
    2165                 :      * Convert the text array to the representation appropriate for the given
    2166                 :      * object type.  Most use a simple string Values list, but there are some
    2167                 :      * exceptions.
    2168                 :      */
    2169 GIC        1021 :     if (type == OBJECT_TYPE || type == OBJECT_DOMAIN || type == OBJECT_CAST ||
    2170             931 :         type == OBJECT_TRANSFORM || type == OBJECT_DOMCONSTRAINT)
    2171              66 :     {
    2172                 :         Datum      *elems;
    2173                 :         bool       *nulls;
    2174 ECB             :         int         nelems;
    2175                 : 
    2176 GNC         114 :         deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
    2177 GIC         114 :         if (nelems != 1)
    2178 CBC          48 :             ereport(ERROR,
    2179                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2180                 :                      errmsg("name list length must be exactly %d", 1)));
    2181 GIC          66 :         if (nulls[0])
    2182 UIC           0 :             ereport(ERROR,
    2183                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2184                 :                      errmsg("name or argument lists may not contain nulls")));
    2185 GNC          66 :         typename = typeStringToTypeName(TextDatumGetCString(elems[0]), NULL);
    2186 ECB             :     }
    2187 CBC         907 :     else if (type == OBJECT_LARGEOBJECT)
    2188                 :     {
    2189                 :         Datum      *elems;
    2190                 :         bool       *nulls;
    2191                 :         int         nelems;
    2192 ECB             : 
    2193 GNC           9 :         deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
    2194 GIC           9 :         if (nelems != 1)
    2195               3 :             ereport(ERROR,
    2196 ECB             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2197 EUB             :                      errmsg("name list length must be exactly %d", 1)));
    2198 GIC           6 :         if (nulls[0])
    2199 UIC           0 :             ereport(ERROR,
    2200 ECB             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2201                 :                      errmsg("large object OID may not be null")));
    2202 CBC           6 :         objnode = (Node *) makeFloat(TextDatumGetCString(elems[0]));
    2203                 :     }
    2204                 :     else
    2205                 :     {
    2206 GIC         898 :         name = textarray_to_strvaluelist(namearr);
    2207 GNC         895 :         if (name == NIL)
    2208 CBC           3 :             ereport(ERROR,
    2209 ECB             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2210                 :                      errmsg("name list length must be at least %d", 1)));
    2211                 :     }
    2212                 : 
    2213                 :     /*
    2214 EUB             :      * If args are given, decode them according to the object type.
    2215                 :      */
    2216 GIC         964 :     if (type == OBJECT_AGGREGATE ||
    2217 CBC         916 :         type == OBJECT_FUNCTION ||
    2218 GIC         892 :         type == OBJECT_PROCEDURE ||
    2219             892 :         type == OBJECT_ROUTINE ||
    2220             868 :         type == OBJECT_OPERATOR ||
    2221 CBC         856 :         type == OBJECT_CAST ||
    2222             826 :         type == OBJECT_AMOP ||
    2223 ECB             :         type == OBJECT_AMPROC)
    2224 GIC         168 :     {
    2225                 :         /* in these cases, the args list must be of TypeName */
    2226                 :         Datum      *elems;
    2227                 :         bool       *nulls;
    2228                 :         int         nelems;
    2229                 :         int         i;
    2230                 : 
    2231 GNC         168 :         deconstruct_array_builtin(argsarr, TEXTOID, &elems, &nulls, &nelems);
    2232 ECB             : 
    2233 CBC         168 :         args = NIL;
    2234             321 :         for (i = 0; i < nelems; i++)
    2235 ECB             :         {
    2236 CBC         153 :             if (nulls[i])
    2237 UIC           0 :                 ereport(ERROR,
    2238 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2239                 :                          errmsg("name or argument lists may not contain nulls")));
    2240 GIC         153 :             args = lappend(args,
    2241 GNC         153 :                            typeStringToTypeName(TextDatumGetCString(elems[i]),
    2242                 :                                                 NULL));
    2243                 :         }
    2244                 :     }
    2245                 :     else
    2246 ECB             :     {
    2247                 :         /* For all other object types, use string Values */
    2248 CBC         796 :         args = textarray_to_strvaluelist(argsarr);
    2249 ECB             :     }
    2250                 : 
    2251                 :     /*
    2252 EUB             :      * get_object_address is pretty sensitive to the length of its input
    2253                 :      * lists; check that they're what it wants.
    2254                 :      */
    2255 CBC         964 :     switch (type)
    2256 ECB             :     {
    2257 GIC          48 :         case OBJECT_PUBLICATION_NAMESPACE:
    2258                 :         case OBJECT_USER_MAPPING:
    2259              48 :             if (list_length(name) != 1)
    2260              24 :                 ereport(ERROR,
    2261                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2262                 :                          errmsg("name list length must be exactly %d", 1)));
    2263 ECB             :             /* fall through to check args length */
    2264                 :             /* FALLTHROUGH */
    2265                 :         case OBJECT_DOMCONSTRAINT:
    2266                 :         case OBJECT_CAST:
    2267                 :         case OBJECT_PUBLICATION_REL:
    2268                 :         case OBJECT_DEFACL:
    2269                 :         case OBJECT_TRANSFORM:
    2270 CBC         114 :             if (list_length(args) != 1)
    2271 GIC          33 :                 ereport(ERROR,
    2272 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2273                 :                          errmsg("argument list length must be exactly %d", 1)));
    2274 CBC          81 :             break;
    2275              48 :         case OBJECT_OPFAMILY:
    2276                 :         case OBJECT_OPCLASS:
    2277 GIC          48 :             if (list_length(name) < 2)
    2278              12 :                 ereport(ERROR,
    2279                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2280                 :                          errmsg("name list length must be at least %d", 2)));
    2281              36 :             break;
    2282              60 :         case OBJECT_AMOP:
    2283                 :         case OBJECT_AMPROC:
    2284              60 :             if (list_length(name) < 3)
    2285 CBC          24 :                 ereport(ERROR,
    2286 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2287                 :                          errmsg("name list length must be at least %d", 3)));
    2288                 :             /* fall through to check args length */
    2289                 :             /* FALLTHROUGH */
    2290                 :         case OBJECT_OPERATOR:
    2291 GIC          60 :             if (list_length(args) != 2)
    2292 CBC          30 :                 ereport(ERROR,
    2293 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2294                 :                          errmsg("argument list length must be exactly %d", 2)));
    2295 GIC          30 :             break;
    2296 CBC         694 :         default:
    2297             694 :             break;
    2298                 :     }
    2299 ECB             : 
    2300                 :     /*
    2301                 :      * Now build the Node type that get_object_address() expects for the given
    2302                 :      * type.
    2303                 :      */
    2304 GIC         841 :     switch (type)
    2305                 :     {
    2306 CBC         492 :         case OBJECT_TABLE:
    2307 ECB             :         case OBJECT_SEQUENCE:
    2308                 :         case OBJECT_VIEW:
    2309                 :         case OBJECT_MATVIEW:
    2310                 :         case OBJECT_INDEX:
    2311                 :         case OBJECT_FOREIGN_TABLE:
    2312                 :         case OBJECT_COLUMN:
    2313                 :         case OBJECT_ATTRIBUTE:
    2314                 :         case OBJECT_COLLATION:
    2315                 :         case OBJECT_CONVERSION:
    2316                 :         case OBJECT_STATISTIC_EXT:
    2317                 :         case OBJECT_TSPARSER:
    2318                 :         case OBJECT_TSDICTIONARY:
    2319                 :         case OBJECT_TSTEMPLATE:
    2320                 :         case OBJECT_TSCONFIGURATION:
    2321                 :         case OBJECT_DEFAULT:
    2322                 :         case OBJECT_POLICY:
    2323                 :         case OBJECT_RULE:
    2324                 :         case OBJECT_TRIGGER:
    2325                 :         case OBJECT_TABCONSTRAINT:
    2326                 :         case OBJECT_OPCLASS:
    2327                 :         case OBJECT_OPFAMILY:
    2328 GIC         492 :             objnode = (Node *) name;
    2329             492 :             break;
    2330             130 :         case OBJECT_ACCESS_METHOD:
    2331                 :         case OBJECT_DATABASE:
    2332                 :         case OBJECT_EVENT_TRIGGER:
    2333                 :         case OBJECT_EXTENSION:
    2334                 :         case OBJECT_FDW:
    2335                 :         case OBJECT_FOREIGN_SERVER:
    2336                 :         case OBJECT_LANGUAGE:
    2337                 :         case OBJECT_PARAMETER_ACL:
    2338                 :         case OBJECT_PUBLICATION:
    2339                 :         case OBJECT_ROLE:
    2340                 :         case OBJECT_SCHEMA:
    2341                 :         case OBJECT_SUBSCRIPTION:
    2342                 :         case OBJECT_TABLESPACE:
    2343 CBC         130 :             if (list_length(name) != 1)
    2344              36 :                 ereport(ERROR,
    2345 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2346                 :                          errmsg("name list length must be exactly %d", 1)));
    2347 GIC          94 :             objnode = linitial(name);
    2348              94 :             break;
    2349              30 :         case OBJECT_TYPE:
    2350                 :         case OBJECT_DOMAIN:
    2351              30 :             objnode = (Node *) typename;
    2352              30 :             break;
    2353              27 :         case OBJECT_CAST:
    2354                 :         case OBJECT_DOMCONSTRAINT:
    2355                 :         case OBJECT_TRANSFORM:
    2356              27 :             objnode = (Node *) list_make2(typename, linitial(args));
    2357              27 :             break;
    2358 CBC          15 :         case OBJECT_PUBLICATION_REL:
    2359              15 :             objnode = (Node *) list_make2(name, linitial(args));
    2360 GIC          15 :             break;
    2361              18 :         case OBJECT_PUBLICATION_NAMESPACE:
    2362 ECB             :         case OBJECT_USER_MAPPING:
    2363 CBC          18 :             objnode = (Node *) list_make2(linitial(name), linitial(args));
    2364              18 :             break;
    2365 GIC          21 :         case OBJECT_DEFACL:
    2366 CBC          21 :             objnode = (Node *) lcons(linitial(args), name);
    2367              21 :             break;
    2368              24 :         case OBJECT_AMOP:
    2369                 :         case OBJECT_AMPROC:
    2370 GIC          24 :             objnode = (Node *) list_make2(name, args);
    2371 CBC          24 :             break;
    2372              78 :         case OBJECT_FUNCTION:
    2373 ECB             :         case OBJECT_PROCEDURE:
    2374                 :         case OBJECT_ROUTINE:
    2375                 :         case OBJECT_AGGREGATE:
    2376                 :         case OBJECT_OPERATOR:
    2377                 :             {
    2378 CBC          78 :                 ObjectWithArgs *owa = makeNode(ObjectWithArgs);
    2379 ECB             : 
    2380 CBC          78 :                 owa->objname = name;
    2381              78 :                 owa->objargs = args;
    2382              78 :                 objnode = (Node *) owa;
    2383              78 :                 break;
    2384                 :             }
    2385               6 :         case OBJECT_LARGEOBJECT:
    2386 ECB             :             /* already handled above */
    2387 CBC           6 :             break;
    2388                 :             /* no default, to let compiler warn about missing case */
    2389                 :     }
    2390                 : 
    2391 GIC         805 :     if (objnode == NULL)
    2392 UIC           0 :         elog(ERROR, "unrecognized object type: %d", type);
    2393 ECB             : 
    2394 GIC         805 :     addr = get_object_address(type, objnode,
    2395 ECB             :                               &relation, AccessShareLock, false);
    2396                 : 
    2397                 :     /* We don't need the relcache entry, thank you very much */
    2398 CBC         310 :     if (relation)
    2399 GIC          96 :         relation_close(relation, AccessShareLock);
    2400 ECB             : 
    2401 GNC         310 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
    2402 UNC           0 :         elog(ERROR, "return type must be a row type");
    2403 ECB             : 
    2404 GIC         310 :     values[0] = ObjectIdGetDatum(addr.classId);
    2405             310 :     values[1] = ObjectIdGetDatum(addr.objectId);
    2406             310 :     values[2] = Int32GetDatum(addr.objectSubId);
    2407 CBC         310 :     nulls[0] = false;
    2408             310 :     nulls[1] = false;
    2409 GIC         310 :     nulls[2] = false;
    2410 ECB             : 
    2411 GBC         310 :     htup = heap_form_tuple(tupdesc, values, nulls);
    2412                 : 
    2413 CBC         310 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
    2414 ECB             : }
    2415                 : 
    2416                 : /*
    2417                 :  * Check ownership of an object previously identified by get_object_address.
    2418                 :  */
    2419                 : void
    2420 CBC       19986 : check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
    2421                 :                        Node *object, Relation relation)
    2422 ECB             : {
    2423 GIC       19986 :     switch (objtype)
    2424                 :     {
    2425             792 :         case OBJECT_INDEX:
    2426                 :         case OBJECT_SEQUENCE:
    2427                 :         case OBJECT_TABLE:
    2428                 :         case OBJECT_VIEW:
    2429 ECB             :         case OBJECT_MATVIEW:
    2430                 :         case OBJECT_FOREIGN_TABLE:
    2431                 :         case OBJECT_COLUMN:
    2432                 :         case OBJECT_RULE:
    2433                 :         case OBJECT_TRIGGER:
    2434                 :         case OBJECT_POLICY:
    2435                 :         case OBJECT_TABCONSTRAINT:
    2436 GNC         792 :             if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), roleid))
    2437 GIC          11 :                 aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
    2438              11 :                                RelationGetRelationName(relation));
    2439             781 :             break;
    2440 CBC          40 :         case OBJECT_TYPE:
    2441 ECB             :         case OBJECT_DOMAIN:
    2442                 :         case OBJECT_ATTRIBUTE:
    2443 GNC          40 :             if (!object_ownercheck(address.classId, address.objectId, roleid))
    2444 LBC           0 :                 aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
    2445 GIC          40 :             break;
    2446              16 :         case OBJECT_DOMCONSTRAINT:
    2447 ECB             :             {
    2448 EUB             :                 HeapTuple   tuple;
    2449 ECB             :                 Oid         contypid;
    2450                 : 
    2451 GIC          16 :                 tuple = SearchSysCache1(CONSTROID,
    2452                 :                                         ObjectIdGetDatum(address.objectId));
    2453              16 :                 if (!HeapTupleIsValid(tuple))
    2454 UIC           0 :                     elog(ERROR, "constraint with OID %u does not exist",
    2455 ECB             :                          address.objectId);
    2456                 : 
    2457 CBC          16 :                 contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid;
    2458 EUB             : 
    2459 GIC          16 :                 ReleaseSysCache(tuple);
    2460                 : 
    2461 ECB             :                 /*
    2462                 :                  * Fallback to type ownership check in this case as this is
    2463                 :                  * what domain constraints rely on.
    2464                 :                  */
    2465 GNC          16 :                 if (!object_ownercheck(TypeRelationId, contypid, roleid))
    2466 GIC           3 :                     aclcheck_error_type(ACLCHECK_NOT_OWNER, contypid);
    2467                 :             }
    2468              13 :             break;
    2469 CBC         186 :         case OBJECT_AGGREGATE:
    2470 ECB             :         case OBJECT_FUNCTION:
    2471                 :         case OBJECT_PROCEDURE:
    2472                 :         case OBJECT_ROUTINE:
    2473                 :         case OBJECT_OPERATOR:
    2474 GNC         186 :             if (!object_ownercheck(address.classId, address.objectId, roleid))
    2475 CBC           9 :                 aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
    2476               9 :                                NameListToString((castNode(ObjectWithArgs, object))->objname));
    2477             177 :             break;
    2478 GNC        1572 :         case OBJECT_DATABASE:
    2479                 :         case OBJECT_EVENT_TRIGGER:
    2480                 :         case OBJECT_EXTENSION:
    2481                 :         case OBJECT_FDW:
    2482                 :         case OBJECT_FOREIGN_SERVER:
    2483                 :         case OBJECT_LANGUAGE:
    2484                 :         case OBJECT_PUBLICATION:
    2485 ECB             :         case OBJECT_SCHEMA:
    2486                 :         case OBJECT_SUBSCRIPTION:
    2487                 :         case OBJECT_TABLESPACE:
    2488 GNC        1572 :             if (!object_ownercheck(address.classId, address.objectId, roleid))
    2489 GIC          21 :                 aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
    2490              21 :                                strVal(object));
    2491            1551 :             break;
    2492           17012 :         case OBJECT_COLLATION:
    2493 ECB             :         case OBJECT_CONVERSION:
    2494                 :         case OBJECT_OPCLASS:
    2495                 :         case OBJECT_OPFAMILY:
    2496                 :         case OBJECT_STATISTIC_EXT:
    2497                 :         case OBJECT_TSDICTIONARY:
    2498                 :         case OBJECT_TSCONFIGURATION:
    2499 GNC       17012 :             if (!object_ownercheck(address.classId, address.objectId, roleid))
    2500 GIC           6 :                 aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
    2501               6 :                                NameListToString(castNode(List, object)));
    2502 CBC       17006 :             break;
    2503              12 :         case OBJECT_LARGEOBJECT:
    2504 GIC          12 :             if (!lo_compat_privileges &&
    2505 GNC          12 :                 !object_ownercheck(address.classId, address.objectId, roleid))
    2506 LBC           0 :                 ereport(ERROR,
    2507                 :                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2508 ECB             :                          errmsg("must be owner of large object %u",
    2509 EUB             :                                 address.objectId)));
    2510 GIC          12 :             break;
    2511 CBC          11 :         case OBJECT_CAST:
    2512 ECB             :             {
    2513                 :                 /* We can only check permissions on the source/target types */
    2514 GIC          11 :                 TypeName   *sourcetype = linitial_node(TypeName, castNode(List, object));
    2515              11 :                 TypeName   *targettype = lsecond_node(TypeName, castNode(List, object));
    2516              11 :                 Oid         sourcetypeid = typenameTypeId(NULL, sourcetype);
    2517              11 :                 Oid         targettypeid = typenameTypeId(NULL, targettype);
    2518                 : 
    2519 GNC          11 :                 if (!object_ownercheck(TypeRelationId, sourcetypeid, roleid)
    2520 UNC           0 :                     && !object_ownercheck(TypeRelationId, targettypeid, roleid))
    2521 UIC           0 :                     ereport(ERROR,
    2522 EUB             :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2523                 :                              errmsg("must be owner of type %s or type %s",
    2524                 :                                     format_type_be(sourcetypeid),
    2525                 :                                     format_type_be(targettypeid))));
    2526                 :             }
    2527 GIC          11 :             break;
    2528 CBC          11 :         case OBJECT_TRANSFORM:
    2529                 :             {
    2530 GIC          11 :                 TypeName   *typename = linitial_node(TypeName, castNode(List, object));
    2531              11 :                 Oid         typeid = typenameTypeId(NULL, typename);
    2532                 : 
    2533 GNC          11 :                 if (!object_ownercheck(TypeRelationId, typeid, roleid))
    2534 UIC           0 :                     aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid);
    2535                 :             }
    2536 CBC          11 :             break;
    2537 GIC          12 :         case OBJECT_ROLE:
    2538                 : 
    2539                 :             /*
    2540 EUB             :              * We treat roles as being "owned" by those with CREATEROLE priv,
    2541                 :              * provided that they also have admin option on the role.
    2542                 :              *
    2543                 :              * However, superusers are only owned by superusers.
    2544                 :              */
    2545 CBC          12 :             if (superuser_arg(address.objectId))
    2546                 :             {
    2547 UIC           0 :                 if (!superuser_arg(roleid))
    2548               0 :                     ereport(ERROR,
    2549                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2550                 :                              errmsg("permission denied"),
    2551                 :                              errdetail("The current user must have the %s attribute.",
    2552                 :                                        "SUPERUSER")));
    2553                 :             }
    2554                 :             else
    2555                 :             {
    2556 CBC          12 :                 if (!has_createrole_privilege(roleid))
    2557 GIC           1 :                     ereport(ERROR,
    2558                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2559                 :                              errmsg("permission denied"),
    2560                 :                              errdetail("The current user must have the %s attribute.",
    2561                 :                                        "CREATEROLE")));
    2562 GNC          11 :                 if (!is_admin_of_role(roleid, address.objectId))
    2563               3 :                     ereport(ERROR,
    2564                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2565                 :                              errmsg("permission denied"),
    2566                 :                              errdetail("The current user must have the %s option on role \"%s\".",
    2567                 :                                        "ADMIN",
    2568                 :                                        GetUserNameFromId(address.objectId,
    2569                 :                                                          true))));
    2570                 :             }
    2571 GIC           8 :             break;
    2572             322 :         case OBJECT_TSPARSER:
    2573                 :         case OBJECT_TSTEMPLATE:
    2574 ECB             :         case OBJECT_ACCESS_METHOD:
    2575                 :         case OBJECT_PARAMETER_ACL:
    2576                 :             /* We treat these object types as being owned by superusers */
    2577 GIC         322 :             if (!superuser_arg(roleid))
    2578 UIC           0 :                 ereport(ERROR,
    2579 ECB             :                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2580                 :                          errmsg("must be superuser")));
    2581 GIC         322 :             break;
    2582 UNC           0 :         case OBJECT_AMOP:
    2583                 :         case OBJECT_AMPROC:
    2584                 :         case OBJECT_DEFAULT:
    2585                 :         case OBJECT_DEFACL:
    2586                 :         case OBJECT_PUBLICATION_NAMESPACE:
    2587                 :         case OBJECT_PUBLICATION_REL:
    2588                 :         case OBJECT_USER_MAPPING:
    2589                 :             /* These are currently not supported or don't make sense here. */
    2590               0 :             elog(ERROR, "unsupported object type: %d", (int) objtype);
    2591                 :             break;
    2592 ECB             :     }
    2593 GIC       19932 : }
    2594 ECB             : 
    2595                 : /*
    2596                 :  * get_object_namespace
    2597                 :  *
    2598                 :  * Find the schema containing the specified object.  For non-schema objects,
    2599                 :  * this function returns InvalidOid.
    2600                 :  */
    2601                 : Oid
    2602 GIC        3589 : get_object_namespace(const ObjectAddress *address)
    2603                 : {
    2604 ECB             :     int         cache;
    2605                 :     HeapTuple   tuple;
    2606                 :     Oid         oid;
    2607                 :     const ObjectPropertyType *property;
    2608                 : 
    2609                 :     /* If not owned by a namespace, just return InvalidOid. */
    2610 CBC        3589 :     property = get_object_property_data(address->classId);
    2611 GIC        3589 :     if (property->attnum_namespace == InvalidAttrNumber)
    2612 CBC        1122 :         return InvalidOid;
    2613                 : 
    2614                 :     /* Currently, we can only handle object types with system caches. */
    2615 GIC        2467 :     cache = property->oid_catcache_id;
    2616            2467 :     Assert(cache != -1);
    2617                 : 
    2618                 :     /* Fetch tuple from syscache and extract namespace attribute. */
    2619            2467 :     tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
    2620            2467 :     if (!HeapTupleIsValid(tuple))
    2621 UIC           0 :         elog(ERROR, "cache lookup failed for cache %d oid %u",
    2622                 :              cache, address->objectId);
    2623 GNC        2467 :     oid = DatumGetObjectId(SysCacheGetAttrNotNull(cache,
    2624                 :                                                   tuple,
    2625            2467 :                                                   property->attnum_namespace));
    2626 GIC        2467 :     ReleaseSysCache(tuple);
    2627                 : 
    2628            2467 :     return oid;
    2629 ECB             : }
    2630                 : 
    2631                 : /*
    2632                 :  * Return ObjectType for the given object type as given by
    2633                 :  * getObjectTypeDescription; if no valid ObjectType code exists, but it's a
    2634                 :  * possible output type from getObjectTypeDescription, return -1.
    2635                 :  * Otherwise, an error is thrown.
    2636                 :  */
    2637                 : int
    2638 GIC        1042 : read_objtype_from_string(const char *objtype)
    2639 ECB             : {
    2640                 :     int         i;
    2641                 : 
    2642 GIC       30697 :     for (i = 0; i < lengthof(ObjectTypeMap); i++)
    2643                 :     {
    2644           30694 :         if (strcmp(ObjectTypeMap[i].tm_name, objtype) == 0)
    2645 CBC        1039 :             return ObjectTypeMap[i].tm_type;
    2646                 :     }
    2647               3 :     ereport(ERROR,
    2648                 :             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2649 ECB             :              errmsg("unrecognized object type \"%s\"", objtype)));
    2650                 : 
    2651                 :     return -1;                  /* keep compiler quiet */
    2652                 : }
    2653                 : 
    2654                 : /*
    2655                 :  * Interfaces to reference fields of ObjectPropertyType
    2656                 :  */
    2657                 : const char *
    2658 UIC           0 : get_object_class_descr(Oid class_id)
    2659                 : {
    2660               0 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2661 ECB             : 
    2662 UIC           0 :     return prop->class_descr;
    2663 ECB             : }
    2664                 : 
    2665                 : Oid
    2666 GIC        1132 : get_object_oid_index(Oid class_id)
    2667                 : {
    2668            1132 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2669 ECB             : 
    2670 GIC        1132 :     return prop->oid_index_oid;
    2671 ECB             : }
    2672                 : 
    2673                 : int
    2674 GIC       50124 : get_object_catcache_oid(Oid class_id)
    2675                 : {
    2676           50124 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2677 ECB             : 
    2678 GIC       50124 :     return prop->oid_catcache_id;
    2679 ECB             : }
    2680                 : 
    2681                 : int
    2682 GIC         341 : get_object_catcache_name(Oid class_id)
    2683                 : {
    2684             341 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2685 ECB             : 
    2686 GIC         341 :     return prop->name_catcache_id;
    2687 ECB             : }
    2688                 : 
    2689                 : AttrNumber
    2690 GIC        3804 : get_object_attnum_oid(Oid class_id)
    2691                 : {
    2692            3804 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2693                 : 
    2694            3804 :     return prop->attnum_oid;
    2695                 : }
    2696                 : 
    2697                 : AttrNumber
    2698           26513 : get_object_attnum_name(Oid class_id)
    2699                 : {
    2700 CBC       26513 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2701                 : 
    2702           26513 :     return prop->attnum_name;
    2703                 : }
    2704 ECB             : 
    2705                 : AttrNumber
    2706 GIC        3348 : get_object_attnum_namespace(Oid class_id)
    2707                 : {
    2708            3348 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2709                 : 
    2710            3348 :     return prop->attnum_namespace;
    2711 EUB             : }
    2712                 : 
    2713                 : AttrNumber
    2714 CBC       46226 : get_object_attnum_owner(Oid class_id)
    2715                 : {
    2716 GIC       46226 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2717                 : 
    2718 CBC       46226 :     return prop->attnum_owner;
    2719                 : }
    2720 ECB             : 
    2721                 : AttrNumber
    2722 CBC       90087 : get_object_attnum_acl(Oid class_id)
    2723                 : {
    2724 GIC       90087 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2725                 : 
    2726           90087 :     return prop->attnum_acl;
    2727                 : }
    2728                 : 
    2729                 : /*
    2730 ECB             :  * get_object_type
    2731                 :  *
    2732                 :  * Return the object type associated with a given object.  This routine
    2733                 :  * is primarily used to determine the object type to mention in ACL check
    2734                 :  * error messages, so it's desirable for it to avoid failing.
    2735                 :  */
    2736                 : ObjectType
    2737 CBC       60750 : get_object_type(Oid class_id, Oid object_id)
    2738                 : {
    2739 GIC       60750 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2740 ECB             : 
    2741 GIC       60750 :     if (prop->objtype == OBJECT_TABLE)
    2742                 :     {
    2743                 :         /*
    2744                 :          * If the property data says it's a table, dig a little deeper to get
    2745                 :          * the real relation kind, so that callers can produce more precise
    2746                 :          * error messages.
    2747 ECB             :          */
    2748 UIC           0 :         return get_relkind_objtype(get_rel_relkind(object_id));
    2749                 :     }
    2750                 :     else
    2751 GIC       60750 :         return prop->objtype;
    2752                 : }
    2753                 : 
    2754                 : bool
    2755            1897 : get_object_namensp_unique(Oid class_id)
    2756 ECB             : {
    2757 CBC        1897 :     const ObjectPropertyType *prop = get_object_property_data(class_id);
    2758                 : 
    2759            1897 :     return prop->is_nsp_name_unique;
    2760                 : }
    2761 ECB             : 
    2762                 : /*
    2763                 :  * Return whether we have useful data for the given object class in the
    2764                 :  * ObjectProperty table.
    2765                 :  */
    2766                 : bool
    2767 GIC        2513 : is_objectclass_supported(Oid class_id)
    2768 EUB             : {
    2769                 :     int         index;
    2770                 : 
    2771 GIC       58873 :     for (index = 0; index < lengthof(ObjectProperty); index++)
    2772                 :     {
    2773           58631 :         if (ObjectProperty[index].class_oid == class_id)
    2774            2271 :             return true;
    2775                 :     }
    2776                 : 
    2777             242 :     return false;
    2778                 : }
    2779                 : 
    2780                 : /*
    2781                 :  * Find ObjectProperty structure by class_id.
    2782 ECB             :  */
    2783                 : static const ObjectPropertyType *
    2784 GIC      287811 : get_object_property_data(Oid class_id)
    2785 ECB             : {
    2786                 :     static const ObjectPropertyType *prop_last = NULL;
    2787                 :     int         index;
    2788                 : 
    2789                 :     /*
    2790                 :      * A shortcut to speed up multiple consecutive lookups of a particular
    2791                 :      * object class.
    2792                 :      */
    2793 GIC      287811 :     if (prop_last && prop_last->class_oid == class_id)
    2794          280432 :         return prop_last;
    2795                 : 
    2796 CBC      127943 :     for (index = 0; index < lengthof(ObjectProperty); index++)
    2797                 :     {
    2798 GIC      127943 :         if (ObjectProperty[index].class_oid == class_id)
    2799                 :         {
    2800 CBC        7379 :             prop_last = &ObjectProperty[index];
    2801 GIC        7379 :             return &ObjectProperty[index];
    2802 ECB             :         }
    2803                 :     }
    2804                 : 
    2805 UIC           0 :     ereport(ERROR,
    2806                 :             (errmsg_internal("unrecognized class ID: %u", class_id)));
    2807 ECB             : 
    2808                 :     return NULL;                /* keep MSC compiler happy */
    2809                 : }
    2810                 : 
    2811                 : /*
    2812                 :  * Return a copy of the tuple for the object with the given object OID, from
    2813                 :  * the given catalog (which must have been opened by the caller and suitably
    2814                 :  * locked).  NULL is returned if the OID is not found.
    2815                 :  *
    2816                 :  * We try a syscache first, if available.
    2817                 :  */
    2818                 : HeapTuple
    2819 GIC        3500 : get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
    2820 ECB             : {
    2821                 :     HeapTuple   tuple;
    2822 GIC        3500 :     Oid         classId = RelationGetRelid(catalog);
    2823            3500 :     int         oidCacheId = get_object_catcache_oid(classId);
    2824                 : 
    2825            3500 :     if (oidCacheId > 0)
    2826                 :     {
    2827            3085 :         tuple = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId));
    2828            3085 :         if (!HeapTupleIsValid(tuple))   /* should not happen */
    2829              93 :             return NULL;
    2830                 :     }
    2831 ECB             :     else
    2832                 :     {
    2833 GIC         415 :         Oid         oidIndexId = get_object_oid_index(classId);
    2834                 :         SysScanDesc scan;
    2835                 :         ScanKeyData skey;
    2836                 : 
    2837 CBC         415 :         Assert(OidIsValid(oidIndexId));
    2838 ECB             : 
    2839 CBC         415 :         ScanKeyInit(&skey,
    2840                 :                     oidcol,
    2841 ECB             :                     BTEqualStrategyNumber, F_OIDEQ,
    2842 EUB             :                     ObjectIdGetDatum(objectId));
    2843                 : 
    2844 CBC         415 :         scan = systable_beginscan(catalog, oidIndexId, true,
    2845                 :                                   NULL, 1, &skey);
    2846 GIC         415 :         tuple = systable_getnext(scan);
    2847 CBC         415 :         if (!HeapTupleIsValid(tuple))
    2848 ECB             :         {
    2849 CBC          51 :             systable_endscan(scan);
    2850 GIC          51 :             return NULL;
    2851 EUB             :         }
    2852 GBC         364 :         tuple = heap_copytuple(tuple);
    2853                 : 
    2854 GIC         364 :         systable_endscan(scan);
    2855 ECB             :     }
    2856                 : 
    2857 GIC        3356 :     return tuple;
    2858 EUB             : }
    2859                 : 
    2860                 : /*
    2861                 :  * getPublicationSchemaInfo
    2862                 :  *
    2863                 :  * Get publication name and schema name from the object address into pubname and
    2864                 :  * nspname. Both pubname and nspname are palloc'd strings which will be freed by
    2865                 :  * the caller.
    2866                 :  */
    2867                 : static bool
    2868 CBC         101 : getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok,
    2869 ECB             :                          char **pubname, char **nspname)
    2870                 : {
    2871                 :     HeapTuple   tup;
    2872                 :     Form_pg_publication_namespace pnform;
    2873                 : 
    2874 GIC         101 :     tup = SearchSysCache1(PUBLICATIONNAMESPACE,
    2875             101 :                           ObjectIdGetDatum(object->objectId));
    2876             101 :     if (!HeapTupleIsValid(tup))
    2877                 :     {
    2878               9 :         if (!missing_ok)
    2879 LBC           0 :             elog(ERROR, "cache lookup failed for publication schema %u",
    2880                 :                  object->objectId);
    2881 GIC           9 :         return false;
    2882                 :     }
    2883 ECB             : 
    2884 GIC          92 :     pnform = (Form_pg_publication_namespace) GETSTRUCT(tup);
    2885 CBC          92 :     *pubname = get_publication_name(pnform->pnpubid, missing_ok);
    2886 GIC          92 :     if (!(*pubname))
    2887 ECB             :     {
    2888 LBC           0 :         ReleaseSysCache(tup);
    2889               0 :         return false;
    2890                 :     }
    2891                 : 
    2892 GIC          92 :     *nspname = get_namespace_name(pnform->pnnspid);
    2893              92 :     if (!(*nspname))
    2894 ECB             :     {
    2895 LBC           0 :         Oid         schemaid = pnform->pnnspid;
    2896                 : 
    2897 UIC           0 :         pfree(*pubname);
    2898 LBC           0 :         ReleaseSysCache(tup);
    2899               0 :         if (!missing_ok)
    2900 UIC           0 :             elog(ERROR, "cache lookup failed for schema %u",
    2901 ECB             :                  schemaid);
    2902 LBC           0 :         return false;
    2903                 :     }
    2904 ECB             : 
    2905 GIC          92 :     ReleaseSysCache(tup);
    2906 CBC          92 :     return true;
    2907                 : }
    2908 ECB             : 
    2909                 : /*
    2910                 :  * getObjectDescription: build an object description for messages
    2911                 :  *
    2912                 :  * The result is a palloc'd string.  NULL is returned for an undefined
    2913                 :  * object if missing_ok is true, else an error is generated.
    2914                 :  */
    2915                 : char *
    2916 CBC       67185 : getObjectDescription(const ObjectAddress *object, bool missing_ok)
    2917 ECB             : {
    2918                 :     StringInfoData buffer;
    2919                 : 
    2920 CBC       67185 :     initStringInfo(&buffer);
    2921                 : 
    2922 GIC       67185 :     switch (getObjectClass(object))
    2923 ECB             :     {
    2924 GIC       19725 :         case OCLASS_CLASS:
    2925 CBC       19725 :             if (object->objectSubId == 0)
    2926           18480 :                 getRelationDescription(&buffer, object->objectId, missing_ok);
    2927                 :             else
    2928                 :             {
    2929 ECB             :                 /* column, not whole relation */
    2930                 :                 StringInfoData rel;
    2931 GIC        1245 :                 char       *attname = get_attname(object->objectId,
    2932 CBC        1245 :                                                   object->objectSubId,
    2933 ECB             :                                                   missing_ok);
    2934                 : 
    2935 GIC        1245 :                 if (!attname)
    2936 CBC           3 :                     break;
    2937                 : 
    2938 GIC        1242 :                 initStringInfo(&rel);
    2939            1242 :                 getRelationDescription(&rel, object->objectId, missing_ok);
    2940                 :                 /* translator: second %s is, e.g., "table %s" */
    2941            1242 :                 appendStringInfo(&buffer, _("column %s of %s"),
    2942                 :                                  attname, rel.data);
    2943            1242 :                 pfree(rel.data);
    2944 ECB             :             }
    2945 GIC       19722 :             break;
    2946 ECB             : 
    2947 GIC        1456 :         case OCLASS_PROC:
    2948                 :             {
    2949 CBC        1456 :                 bits16      flags = FORMAT_PROC_INVALID_AS_NULL;
    2950 GIC        1456 :                 char       *proname = format_procedure_extended(object->objectId,
    2951 ECB             :                                                                 flags);
    2952                 : 
    2953 GIC        1456 :                 if (proname == NULL)
    2954 CBC           3 :                     break;
    2955                 : 
    2956            1453 :                 appendStringInfo(&buffer, _("function %s"), proname);
    2957 GIC        1453 :                 break;
    2958 ECB             :             }
    2959 EUB             : 
    2960 GIC       27644 :         case OCLASS_TYPE:
    2961                 :             {
    2962 CBC       27644 :                 bits16      flags = FORMAT_TYPE_INVALID_AS_NULL;
    2963           27644 :                 char       *typname = format_type_extended(object->objectId, -1,
    2964 ECB             :                                                            flags);
    2965                 : 
    2966 GIC       27644 :                 if (typname == NULL)
    2967 CBC           3 :                     break;
    2968                 : 
    2969           27641 :                 appendStringInfo(&buffer, _("type %s"), typname);
    2970 GIC       27641 :                 break;
    2971                 :             }
    2972                 : 
    2973 CBC         122 :         case OCLASS_CAST:
    2974 ECB             :             {
    2975                 :                 Relation    castDesc;
    2976                 :                 ScanKeyData skey[1];
    2977                 :                 SysScanDesc rcscan;
    2978                 :                 HeapTuple   tup;
    2979                 :                 Form_pg_cast castForm;
    2980                 : 
    2981 GIC         122 :                 castDesc = table_open(CastRelationId, AccessShareLock);
    2982                 : 
    2983             122 :                 ScanKeyInit(&skey[0],
    2984 ECB             :                             Anum_pg_cast_oid,
    2985                 :                             BTEqualStrategyNumber, F_OIDEQ,
    2986 CBC         122 :                             ObjectIdGetDatum(object->objectId));
    2987                 : 
    2988             122 :                 rcscan = systable_beginscan(castDesc, CastOidIndexId, true,
    2989 EUB             :                                             NULL, 1, skey);
    2990                 : 
    2991 CBC         122 :                 tup = systable_getnext(rcscan);
    2992                 : 
    2993 GIC         122 :                 if (!HeapTupleIsValid(tup))
    2994 ECB             :                 {
    2995 GIC           3 :                     if (!missing_ok)
    2996 UIC           0 :                         elog(ERROR, "could not find tuple for cast %u",
    2997 ECB             :                              object->objectId);
    2998                 : 
    2999 GIC           3 :                     systable_endscan(rcscan);
    3000 GBC           3 :                     table_close(castDesc, AccessShareLock);
    3001 GIC           3 :                     break;
    3002 ECB             :                 }
    3003                 : 
    3004 CBC         119 :                 castForm = (Form_pg_cast) GETSTRUCT(tup);
    3005 ECB             : 
    3006 CBC         119 :                 appendStringInfo(&buffer, _("cast from %s to %s"),
    3007                 :                                  format_type_be(castForm->castsource),
    3008                 :                                  format_type_be(castForm->casttarget));
    3009 ECB             : 
    3010 GIC         119 :                 systable_endscan(rcscan);
    3011             119 :                 table_close(castDesc, AccessShareLock);
    3012             119 :                 break;
    3013                 :             }
    3014 ECB             : 
    3015 CBC          51 :         case OCLASS_COLLATION:
    3016 ECB             :             {
    3017                 :                 HeapTuple   collTup;
    3018                 :                 Form_pg_collation coll;
    3019 EUB             :                 char       *nspname;
    3020                 : 
    3021 CBC          51 :                 collTup = SearchSysCache1(COLLOID,
    3022 GIC          51 :                                           ObjectIdGetDatum(object->objectId));
    3023              51 :                 if (!HeapTupleIsValid(collTup))
    3024 ECB             :                 {
    3025 GIC           3 :                     if (!missing_ok)
    3026 LBC           0 :                         elog(ERROR, "cache lookup failed for collation %u",
    3027                 :                              object->objectId);
    3028 GIC           3 :                     break;
    3029                 :                 }
    3030 ECB             : 
    3031 CBC          48 :                 coll = (Form_pg_collation) GETSTRUCT(collTup);
    3032                 : 
    3033 ECB             :                 /* Qualify the name if not visible in search path */
    3034 CBC          48 :                 if (CollationIsVisible(object->objectId))
    3035              48 :                     nspname = NULL;
    3036                 :                 else
    3037 UIC           0 :                     nspname = get_namespace_name(coll->collnamespace);
    3038                 : 
    3039 CBC          48 :                 appendStringInfo(&buffer, _("collation %s"),
    3040 ECB             :                                  quote_qualified_identifier(nspname,
    3041 GIC          48 :                                                             NameStr(coll->collname)));
    3042              48 :                 ReleaseSysCache(collTup);
    3043 CBC          48 :                 break;
    3044 ECB             :             }
    3045                 : 
    3046 GIC        8318 :         case OCLASS_CONSTRAINT:
    3047 ECB             :             {
    3048                 :                 HeapTuple   conTup;
    3049                 :                 Form_pg_constraint con;
    3050                 : 
    3051 GIC        8318 :                 conTup = SearchSysCache1(CONSTROID,
    3052            8318 :                                          ObjectIdGetDatum(object->objectId));
    3053 CBC        8318 :                 if (!HeapTupleIsValid(conTup))
    3054 ECB             :                 {
    3055 CBC           3 :                     if (!missing_ok)
    3056 UIC           0 :                         elog(ERROR, "cache lookup failed for constraint %u",
    3057 ECB             :                              object->objectId);
    3058 GBC           3 :                     break;
    3059                 :                 }
    3060 ECB             : 
    3061 GIC        8315 :                 con = (Form_pg_constraint) GETSTRUCT(conTup);
    3062                 : 
    3063 CBC        8315 :                 if (OidIsValid(con->conrelid))
    3064                 :                 {
    3065                 :                     StringInfoData rel;
    3066 ECB             : 
    3067 CBC        8221 :                     initStringInfo(&rel);
    3068 GIC        8221 :                     getRelationDescription(&rel, con->conrelid, false);
    3069 ECB             :                     /* translator: second %s is, e.g., "table %s" */
    3070 GIC        8221 :                     appendStringInfo(&buffer, _("constraint %s on %s"),
    3071 CBC        8221 :                                      NameStr(con->conname), rel.data);
    3072 GIC        8221 :                     pfree(rel.data);
    3073 ECB             :                 }
    3074                 :                 else
    3075                 :                 {
    3076 GIC          94 :                     appendStringInfo(&buffer, _("constraint %s"),
    3077              94 :                                      NameStr(con->conname));
    3078 ECB             :                 }
    3079                 : 
    3080 GIC        8315 :                 ReleaseSysCache(conTup);
    3081            8315 :                 break;
    3082 ECB             :             }
    3083                 : 
    3084 CBC          18 :         case OCLASS_CONVERSION:
    3085                 :             {
    3086 ECB             :                 HeapTuple   conTup;
    3087 EUB             :                 Form_pg_conversion conv;
    3088                 :                 char       *nspname;
    3089 ECB             : 
    3090 GIC          18 :                 conTup = SearchSysCache1(CONVOID,
    3091              18 :                                          ObjectIdGetDatum(object->objectId));
    3092              18 :                 if (!HeapTupleIsValid(conTup))
    3093 ECB             :                 {
    3094 GIC           3 :                     if (!missing_ok)
    3095 LBC           0 :                         elog(ERROR, "cache lookup failed for conversion %u",
    3096                 :                              object->objectId);
    3097 GIC           3 :                     break;
    3098 ECB             :                 }
    3099                 : 
    3100 CBC          15 :                 conv = (Form_pg_conversion) GETSTRUCT(conTup);
    3101                 : 
    3102                 :                 /* Qualify the name if not visible in search path */
    3103              15 :                 if (ConversionIsVisible(object->objectId))
    3104               9 :                     nspname = NULL;
    3105 ECB             :                 else
    3106 CBC           6 :                     nspname = get_namespace_name(conv->connamespace);
    3107                 : 
    3108 GIC          15 :                 appendStringInfo(&buffer, _("conversion %s"),
    3109 ECB             :                                  quote_qualified_identifier(nspname,
    3110 CBC          15 :                                                             NameStr(conv->conname)));
    3111              15 :                 ReleaseSysCache(conTup);
    3112 GBC          15 :                 break;
    3113 EUB             :             }
    3114                 : 
    3115 GIC        1054 :         case OCLASS_DEFAULT:
    3116 ECB             :             {
    3117                 :                 ObjectAddress colobject;
    3118                 : 
    3119 CBC        1054 :                 colobject = GetAttrDefaultColumnAddress(object->objectId);
    3120                 : 
    3121 GIC        1054 :                 if (!OidIsValid(colobject.objectId))
    3122 ECB             :                 {
    3123 CBC           3 :                     if (!missing_ok)
    3124 UIC           0 :                         elog(ERROR, "could not find tuple for attrdef %u",
    3125 ECB             :                              object->objectId);
    3126 CBC           3 :                     break;
    3127                 :                 }
    3128                 : 
    3129 ECB             :                 /* translator: %s is typically "column %s of table %s" */
    3130 GIC        1051 :                 appendStringInfo(&buffer, _("default value for %s"),
    3131                 :                                  getObjectDescription(&colobject, false));
    3132            1051 :                 break;
    3133                 :             }
    3134                 : 
    3135              12 :         case OCLASS_LANGUAGE:
    3136                 :             {
    3137 CBC          12 :                 char       *langname = get_language_name(object->objectId,
    3138 ECB             :                                                          missing_ok);
    3139                 : 
    3140 GIC          12 :                 if (langname)
    3141 CBC           9 :                     appendStringInfo(&buffer, _("language %s"),
    3142 GBC           9 :                                      get_language_name(object->objectId, false));
    3143 GIC          12 :                 break;
    3144 ECB             :             }
    3145                 : 
    3146 GIC           3 :         case OCLASS_LARGEOBJECT:
    3147 CBC           3 :             if (!LargeObjectExists(object->objectId))
    3148 GIC           3 :                 break;
    3149 LBC           0 :             appendStringInfo(&buffer, _("large object %u"),
    3150 UIC           0 :                              object->objectId);
    3151 LBC           0 :             break;
    3152 EUB             : 
    3153 GIC         334 :         case OCLASS_OPERATOR:
    3154 ECB             :             {
    3155 GIC         334 :                 bits16      flags = FORMAT_OPERATOR_INVALID_AS_NULL;
    3156             334 :                 char       *oprname = format_operator_extended(object->objectId,
    3157 ECB             :                                                                flags);
    3158                 : 
    3159 GIC         334 :                 if (oprname == NULL)
    3160 CBC           3 :                     break;
    3161                 : 
    3162             331 :                 appendStringInfo(&buffer, _("operator %s"), oprname);
    3163 GIC         331 :                 break;
    3164 ECB             :             }
    3165                 : 
    3166 GIC          67 :         case OCLASS_OPCLASS:
    3167 ECB             :             {
    3168                 :                 HeapTuple   opcTup;
    3169                 :                 Form_pg_opclass opcForm;
    3170                 :                 HeapTuple   amTup;
    3171                 :                 Form_pg_am  amForm;
    3172                 :                 char       *nspname;
    3173                 : 
    3174 CBC          67 :                 opcTup = SearchSysCache1(CLAOID,
    3175 GIC          67 :                                          ObjectIdGetDatum(object->objectId));
    3176 CBC          67 :                 if (!HeapTupleIsValid(opcTup))
    3177                 :                 {
    3178 GIC           3 :                     if (!missing_ok)
    3179 UIC           0 :                         elog(ERROR, "cache lookup failed for opclass %u",
    3180 ECB             :                              object->objectId);
    3181 CBC           3 :                     break;
    3182 ECB             :                 }
    3183                 : 
    3184 CBC          64 :                 opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
    3185 EUB             : 
    3186 GIC          64 :                 amTup = SearchSysCache1(AMOID,
    3187 ECB             :                                         ObjectIdGetDatum(opcForm->opcmethod));
    3188 GIC          64 :                 if (!HeapTupleIsValid(amTup))
    3189 UIC           0 :                     elog(ERROR, "cache lookup failed for access method %u",
    3190 ECB             :                          opcForm->opcmethod);
    3191 CBC          64 :                 amForm = (Form_pg_am) GETSTRUCT(amTup);
    3192 ECB             : 
    3193                 :                 /* Qualify the name if not visible in search path */
    3194 GIC          64 :                 if (OpclassIsVisible(object->objectId))
    3195              52 :                     nspname = NULL;
    3196 ECB             :                 else
    3197 GIC          12 :                     nspname = get_namespace_name(opcForm->opcnamespace);
    3198                 : 
    3199              64 :                 appendStringInfo(&buffer, _("operator class %s for access method %s"),
    3200                 :                                  quote_qualified_identifier(nspname,
    3201              64 :                                                             NameStr(opcForm->opcname)),
    3202              64 :                                  NameStr(amForm->amname));
    3203                 : 
    3204              64 :                 ReleaseSysCache(amTup);
    3205 CBC          64 :                 ReleaseSysCache(opcTup);
    3206 GIC          64 :                 break;
    3207                 :             }
    3208 ECB             : 
    3209 GIC          68 :         case OCLASS_OPFAMILY:
    3210              68 :             getOpFamilyDescription(&buffer, object->objectId, missing_ok);
    3211 CBC          68 :             break;
    3212                 : 
    3213              24 :         case OCLASS_AM:
    3214                 :             {
    3215                 :                 HeapTuple   tup;
    3216 ECB             : 
    3217 GIC          24 :                 tup = SearchSysCache1(AMOID,
    3218 CBC          24 :                                       ObjectIdGetDatum(object->objectId));
    3219 GIC          24 :                 if (!HeapTupleIsValid(tup))
    3220 ECB             :                 {
    3221 GBC           3 :                     if (!missing_ok)
    3222 UIC           0 :                         elog(ERROR, "cache lookup failed for access method %u",
    3223                 :                              object->objectId);
    3224 CBC           3 :                     break;
    3225 ECB             :                 }
    3226                 : 
    3227 GIC          21 :                 appendStringInfo(&buffer, _("access method %s"),
    3228              21 :                                  NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
    3229 CBC          21 :                 ReleaseSysCache(tup);
    3230 GIC          21 :                 break;
    3231 ECB             :             }
    3232                 : 
    3233 GIC         466 :         case OCLASS_AMOP:
    3234                 :             {
    3235                 :                 Relation    amopDesc;
    3236                 :                 HeapTuple   tup;
    3237                 :                 ScanKeyData skey[1];
    3238                 :                 SysScanDesc amscan;
    3239 ECB             :                 Form_pg_amop amopForm;
    3240                 :                 StringInfoData opfam;
    3241                 : 
    3242 GIC         466 :                 amopDesc = table_open(AccessMethodOperatorRelationId,
    3243                 :                                       AccessShareLock);
    3244                 : 
    3245             466 :                 ScanKeyInit(&skey[0],
    3246 ECB             :                             Anum_pg_amop_oid,
    3247                 :                             BTEqualStrategyNumber, F_OIDEQ,
    3248 CBC         466 :                             ObjectIdGetDatum(object->objectId));
    3249 ECB             : 
    3250 CBC         466 :                 amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
    3251                 :                                             NULL, 1, skey);
    3252                 : 
    3253             466 :                 tup = systable_getnext(amscan);
    3254                 : 
    3255 GIC         466 :                 if (!HeapTupleIsValid(tup))
    3256                 :                 {
    3257               3 :                     if (!missing_ok)
    3258 UIC           0 :                         elog(ERROR, "could not find tuple for amop entry %u",
    3259                 :                              object->objectId);
    3260                 : 
    3261 GIC           3 :                     systable_endscan(amscan);
    3262 CBC           3 :                     table_close(amopDesc, AccessShareLock);
    3263 GIC           3 :                     break;
    3264                 :                 }
    3265 ECB             : 
    3266 GIC         463 :                 amopForm = (Form_pg_amop) GETSTRUCT(tup);
    3267                 : 
    3268 CBC         463 :                 initStringInfo(&opfam);
    3269 GIC         463 :                 getOpFamilyDescription(&opfam, amopForm->amopfamily, false);
    3270 ECB             : 
    3271                 :                 /*------
    3272                 :                    translator: %d is the operator strategy (a number), the
    3273                 :                    first two %s's are data type names, the third %s is the
    3274                 :                    description of the operator family, and the last %s is the
    3275                 :                    textual form of the operator with arguments.  */
    3276 GIC         463 :                 appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"),
    3277 CBC         463 :                                  amopForm->amopstrategy,
    3278 EUB             :                                  format_type_be(amopForm->amoplefttype),
    3279                 :                                  format_type_be(amopForm->amoprighttype),
    3280                 :                                  opfam.data,
    3281 ECB             :                                  format_operator(amopForm->amopopr));
    3282                 : 
    3283 CBC         463 :                 pfree(opfam.data);
    3284                 : 
    3285 GIC         463 :                 systable_endscan(amscan);
    3286 CBC         463 :                 table_close(amopDesc, AccessShareLock);
    3287 GIC         463 :                 break;
    3288 ECB             :             }
    3289                 : 
    3290 GIC         172 :         case OCLASS_AMPROC:
    3291                 :             {
    3292                 :                 Relation    amprocDesc;
    3293                 :                 ScanKeyData skey[1];
    3294                 :                 SysScanDesc amscan;
    3295                 :                 HeapTuple   tup;
    3296 ECB             :                 Form_pg_amproc amprocForm;
    3297                 :                 StringInfoData opfam;
    3298                 : 
    3299 GIC         172 :                 amprocDesc = table_open(AccessMethodProcedureRelationId,
    3300                 :                                         AccessShareLock);
    3301                 : 
    3302             172 :                 ScanKeyInit(&skey[0],
    3303 ECB             :                             Anum_pg_amproc_oid,
    3304                 :                             BTEqualStrategyNumber, F_OIDEQ,
    3305 CBC         172 :                             ObjectIdGetDatum(object->objectId));
    3306 ECB             : 
    3307 CBC         172 :                 amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
    3308                 :                                             NULL, 1, skey);
    3309                 : 
    3310             172 :                 tup = systable_getnext(amscan);
    3311                 : 
    3312 GIC         172 :                 if (!HeapTupleIsValid(tup))
    3313                 :                 {
    3314               3 :                     if (!missing_ok)
    3315 UIC           0 :                         elog(ERROR, "could not find tuple for amproc entry %u",
    3316                 :                              object->objectId);
    3317                 : 
    3318 GIC           3 :                     systable_endscan(amscan);
    3319 CBC           3 :                     table_close(amprocDesc, AccessShareLock);
    3320 GIC           3 :                     break;
    3321 ECB             :                 }
    3322                 : 
    3323 GIC         169 :                 amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
    3324 ECB             : 
    3325 GIC         169 :                 initStringInfo(&opfam);
    3326 CBC         169 :                 getOpFamilyDescription(&opfam, amprocForm->amprocfamily, false);
    3327                 : 
    3328                 :                 /*------
    3329 ECB             :                    translator: %d is the function number, the first two %s's
    3330                 :                    are data type names, the third %s is the description of the
    3331                 :                    operator family, and the last %s is the textual form of the
    3332                 :                    function with arguments.  */
    3333 CBC         169 :                 appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"),
    3334 GBC         169 :                                  amprocForm->amprocnum,
    3335                 :                                  format_type_be(amprocForm->amproclefttype),
    3336                 :                                  format_type_be(amprocForm->amprocrighttype),
    3337 ECB             :                                  opfam.data,
    3338                 :                                  format_procedure(amprocForm->amproc));
    3339                 : 
    3340 GIC         169 :                 pfree(opfam.data);
    3341                 : 
    3342 CBC         169 :                 systable_endscan(amscan);
    3343 GIC         169 :                 table_close(amprocDesc, AccessShareLock);
    3344 CBC         169 :                 break;
    3345 ECB             :             }
    3346                 : 
    3347 GIC        1219 :         case OCLASS_REWRITE:
    3348 ECB             :             {
    3349                 :                 Relation    ruleDesc;
    3350                 :                 ScanKeyData skey[1];
    3351                 :                 SysScanDesc rcscan;
    3352                 :                 HeapTuple   tup;
    3353                 :                 Form_pg_rewrite rule;
    3354                 :                 StringInfoData rel;
    3355                 : 
    3356 CBC        1219 :                 ruleDesc = table_open(RewriteRelationId, AccessShareLock);
    3357                 : 
    3358 GIC        1219 :                 ScanKeyInit(&skey[0],
    3359                 :                             Anum_pg_rewrite_oid,
    3360                 :                             BTEqualStrategyNumber, F_OIDEQ,
    3361            1219 :                             ObjectIdGetDatum(object->objectId));
    3362                 : 
    3363            1219 :                 rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true,
    3364                 :                                             NULL, 1, skey);
    3365 ECB             : 
    3366 GIC        1219 :                 tup = systable_getnext(rcscan);
    3367 ECB             : 
    3368 GIC        1219 :                 if (!HeapTupleIsValid(tup))
    3369                 :                 {
    3370 CBC           3 :                     if (!missing_ok)
    3371 UIC           0 :                         elog(ERROR, "could not find tuple for rule %u",
    3372 ECB             :                              object->objectId);
    3373                 : 
    3374 GIC           3 :                     systable_endscan(rcscan);
    3375 CBC           3 :                     table_close(ruleDesc, AccessShareLock);
    3376 GIC           3 :                     break;
    3377 ECB             :                 }
    3378                 : 
    3379 CBC        1216 :                 rule = (Form_pg_rewrite) GETSTRUCT(tup);
    3380 EUB             : 
    3381 GIC        1216 :                 initStringInfo(&rel);
    3382            1216 :                 getRelationDescription(&rel, rule->ev_class, false);
    3383 ECB             : 
    3384                 :                 /* translator: second %s is, e.g., "table %s" */
    3385 CBC        1216 :                 appendStringInfo(&buffer, _("rule %s on %s"),
    3386 GIC        1216 :                                  NameStr(rule->rulename), rel.data);
    3387            1216 :                 pfree(rel.data);
    3388 CBC        1216 :                 systable_endscan(rcscan);
    3389 GIC        1216 :                 table_close(ruleDesc, AccessShareLock);
    3390 CBC        1216 :                 break;
    3391 ECB             :             }
    3392                 : 
    3393 GIC        5347 :         case OCLASS_TRIGGER:
    3394 ECB             :             {
    3395                 :                 Relation    trigDesc;
    3396                 :                 ScanKeyData skey[1];
    3397                 :                 SysScanDesc tgscan;
    3398                 :                 HeapTuple   tup;
    3399                 :                 Form_pg_trigger trig;
    3400                 :                 StringInfoData rel;
    3401                 : 
    3402 CBC        5347 :                 trigDesc = table_open(TriggerRelationId, AccessShareLock);
    3403                 : 
    3404 GIC        5347 :                 ScanKeyInit(&skey[0],
    3405                 :                             Anum_pg_trigger_oid,
    3406 ECB             :                             BTEqualStrategyNumber, F_OIDEQ,
    3407 CBC        5347 :                             ObjectIdGetDatum(object->objectId));
    3408                 : 
    3409            5347 :                 tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true,
    3410 EUB             :                                             NULL, 1, skey);
    3411                 : 
    3412 CBC        5347 :                 tup = systable_getnext(tgscan);
    3413                 : 
    3414            5347 :                 if (!HeapTupleIsValid(tup))
    3415 ECB             :                 {
    3416 GIC           3 :                     if (!missing_ok)
    3417 UIC           0 :                         elog(ERROR, "could not find tuple for trigger %u",
    3418 ECB             :                              object->objectId);
    3419                 : 
    3420 GIC           3 :                     systable_endscan(tgscan);
    3421               3 :                     table_close(trigDesc, AccessShareLock);
    3422               3 :                     break;
    3423                 :                 }
    3424 ECB             : 
    3425 CBC        5344 :                 trig = (Form_pg_trigger) GETSTRUCT(tup);
    3426 ECB             : 
    3427 GIC        5344 :                 initStringInfo(&rel);
    3428 CBC        5344 :                 getRelationDescription(&rel, trig->tgrelid, false);
    3429 EUB             : 
    3430                 :                 /* translator: second %s is, e.g., "table %s" */
    3431 CBC        5344 :                 appendStringInfo(&buffer, _("trigger %s on %s"),
    3432 GIC        5344 :                                  NameStr(trig->tgname), rel.data);
    3433            5344 :                 pfree(rel.data);
    3434 CBC        5344 :                 systable_endscan(tgscan);
    3435 GIC        5344 :                 table_close(trigDesc, AccessShareLock);
    3436            5344 :                 break;
    3437 ECB             :             }
    3438                 : 
    3439 GIC          65 :         case OCLASS_SCHEMA:
    3440 ECB             :             {
    3441                 :                 char       *nspname;
    3442                 : 
    3443 GIC          65 :                 nspname = get_namespace_name(object->objectId);
    3444 CBC          65 :                 if (!nspname)
    3445                 :                 {
    3446               3 :                     if (!missing_ok)
    3447 LBC           0 :                         elog(ERROR, "cache lookup failed for namespace %u",
    3448                 :                              object->objectId);
    3449 GIC           3 :                     break;
    3450 ECB             :                 }
    3451 GIC          62 :                 appendStringInfo(&buffer, _("schema %s"), nspname);
    3452              62 :                 break;
    3453                 :             }
    3454                 : 
    3455             143 :         case OCLASS_STATISTIC_EXT:
    3456 ECB             :             {
    3457                 :                 HeapTuple   stxTup;
    3458                 :                 Form_pg_statistic_ext stxForm;
    3459                 :                 char       *nspname;
    3460                 : 
    3461 GBC         143 :                 stxTup = SearchSysCache1(STATEXTOID,
    3462 GIC         143 :                                          ObjectIdGetDatum(object->objectId));
    3463 CBC         143 :                 if (!HeapTupleIsValid(stxTup))
    3464                 :                 {
    3465               3 :                     if (!missing_ok)
    3466 UIC           0 :                         elog(ERROR, "could not find tuple for statistics object %u",
    3467                 :                              object->objectId);
    3468 CBC           3 :                     break;
    3469 ECB             :                 }
    3470                 : 
    3471 CBC         140 :                 stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup);
    3472                 : 
    3473 ECB             :                 /* Qualify the name if not visible in search path */
    3474 GIC         140 :                 if (StatisticsObjIsVisible(object->objectId))
    3475 CBC         116 :                     nspname = NULL;
    3476 ECB             :                 else
    3477 CBC          24 :                     nspname = get_namespace_name(stxForm->stxnamespace);
    3478                 : 
    3479 GIC         140 :                 appendStringInfo(&buffer, _("statistics object %s"),
    3480 ECB             :                                  quote_qualified_identifier(nspname,
    3481 GIC         140 :                                                             NameStr(stxForm->stxname)));
    3482                 : 
    3483             140 :                 ReleaseSysCache(stxTup);
    3484             140 :                 break;
    3485                 :             }
    3486 ECB             : 
    3487 CBC          18 :         case OCLASS_TSPARSER:
    3488 ECB             :             {
    3489                 :                 HeapTuple   tup;
    3490                 :                 Form_pg_ts_parser prsForm;
    3491 EUB             :                 char       *nspname;
    3492                 : 
    3493 CBC          18 :                 tup = SearchSysCache1(TSPARSEROID,
    3494 GIC          18 :                                       ObjectIdGetDatum(object->objectId));
    3495              18 :                 if (!HeapTupleIsValid(tup))
    3496 ECB             :                 {
    3497 GIC           3 :                     if (!missing_ok)
    3498 UIC           0 :                         elog(ERROR, "cache lookup failed for text search parser %u",
    3499 ECB             :                              object->objectId);
    3500 CBC           3 :                     break;
    3501                 :                 }
    3502              15 :                 prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
    3503                 : 
    3504 ECB             :                 /* Qualify the name if not visible in search path */
    3505 GIC          15 :                 if (TSParserIsVisible(object->objectId))
    3506 CBC           9 :                     nspname = NULL;
    3507 ECB             :                 else
    3508 CBC           6 :                     nspname = get_namespace_name(prsForm->prsnamespace);
    3509                 : 
    3510 GIC          15 :                 appendStringInfo(&buffer, _("text search parser %s"),
    3511 ECB             :                                  quote_qualified_identifier(nspname,
    3512 GIC          15 :                                                             NameStr(prsForm->prsname)));
    3513              15 :                 ReleaseSysCache(tup);
    3514              15 :                 break;
    3515                 :             }
    3516                 : 
    3517 CBC          21 :         case OCLASS_TSDICT:
    3518 ECB             :             {
    3519                 :                 HeapTuple   tup;
    3520                 :                 Form_pg_ts_dict dictForm;
    3521                 :                 char       *nspname;
    3522 EUB             : 
    3523 GIC          21 :                 tup = SearchSysCache1(TSDICTOID,
    3524 CBC          21 :                                       ObjectIdGetDatum(object->objectId));
    3525 GIC          21 :                 if (!HeapTupleIsValid(tup))
    3526                 :                 {
    3527 CBC           3 :                     if (!missing_ok)
    3528 UIC           0 :                         elog(ERROR, "cache lookup failed for text search dictionary %u",
    3529                 :                              object->objectId);
    3530 CBC           3 :                     break;
    3531 ECB             :                 }
    3532                 : 
    3533 CBC          18 :                 dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
    3534                 : 
    3535 ECB             :                 /* Qualify the name if not visible in search path */
    3536 GIC          18 :                 if (TSDictionaryIsVisible(object->objectId))
    3537 CBC          12 :                     nspname = NULL;
    3538 ECB             :                 else
    3539 CBC           6 :                     nspname = get_namespace_name(dictForm->dictnamespace);
    3540                 : 
    3541 GIC          18 :                 appendStringInfo(&buffer, _("text search dictionary %s"),
    3542 ECB             :                                  quote_qualified_identifier(nspname,
    3543 GIC          18 :                                                             NameStr(dictForm->dictname)));
    3544              18 :                 ReleaseSysCache(tup);
    3545              18 :                 break;
    3546                 :             }
    3547                 : 
    3548 CBC          18 :         case OCLASS_TSTEMPLATE:
    3549 ECB             :             {
    3550                 :                 HeapTuple   tup;
    3551                 :                 Form_pg_ts_template tmplForm;
    3552                 :                 char       *nspname;
    3553 EUB             : 
    3554 GIC          18 :                 tup = SearchSysCache1(TSTEMPLATEOID,
    3555 CBC          18 :                                       ObjectIdGetDatum(object->objectId));
    3556 GIC          18 :                 if (!HeapTupleIsValid(tup))
    3557                 :                 {
    3558 CBC           3 :                     if (!missing_ok)
    3559 UIC           0 :                         elog(ERROR, "cache lookup failed for text search template %u",
    3560                 :                              object->objectId);
    3561 CBC           3 :                     break;
    3562 ECB             :                 }
    3563                 : 
    3564 CBC          15 :                 tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
    3565                 : 
    3566 ECB             :                 /* Qualify the name if not visible in search path */
    3567 GIC          15 :                 if (TSTemplateIsVisible(object->objectId))
    3568 CBC           9 :                     nspname = NULL;
    3569 ECB             :                 else
    3570 CBC           6 :                     nspname = get_namespace_name(tmplForm->tmplnamespace);
    3571                 : 
    3572 GIC          15 :                 appendStringInfo(&buffer, _("text search template %s"),
    3573 ECB             :                                  quote_qualified_identifier(nspname,
    3574 GIC          15 :                                                             NameStr(tmplForm->tmplname)));
    3575 CBC          15 :                 ReleaseSysCache(tup);
    3576 GIC          15 :                 break;
    3577                 :             }
    3578 ECB             : 
    3579 CBC          21 :         case OCLASS_TSCONFIG:
    3580 ECB             :             {
    3581                 :                 HeapTuple   tup;
    3582                 :                 Form_pg_ts_config cfgForm;
    3583                 :                 char       *nspname;
    3584                 : 
    3585 GIC          21 :                 tup = SearchSysCache1(TSCONFIGOID,
    3586              21 :                                       ObjectIdGetDatum(object->objectId));
    3587              21 :                 if (!HeapTupleIsValid(tup))
    3588                 :                 {
    3589               3 :                     if (!missing_ok)
    3590 UIC           0 :                         elog(ERROR, "cache lookup failed for text search configuration %u",
    3591 ECB             :                              object->objectId);
    3592 GIC           3 :                     break;
    3593 ECB             :                 }
    3594                 : 
    3595 GIC          18 :                 cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
    3596 ECB             : 
    3597                 :                 /* Qualify the name if not visible in search path */
    3598 CBC          18 :                 if (TSConfigIsVisible(object->objectId))
    3599 GIC          12 :                     nspname = NULL;
    3600                 :                 else
    3601 CBC           6 :                     nspname = get_namespace_name(cfgForm->cfgnamespace);
    3602                 : 
    3603              18 :                 appendStringInfo(&buffer, _("text search configuration %s"),
    3604                 :                                  quote_qualified_identifier(nspname,
    3605              18 :                                                             NameStr(cfgForm->cfgname)));
    3606 GBC          18 :                 ReleaseSysCache(tup);
    3607 GIC          18 :                 break;
    3608                 :             }
    3609 ECB             : 
    3610 CBC           5 :         case OCLASS_ROLE:
    3611 ECB             :             {
    3612 GIC           5 :                 char       *username = GetUserNameFromId(object->objectId,
    3613                 :                                                          missing_ok);
    3614 ECB             : 
    3615 GIC           5 :                 if (username)
    3616 CBC           2 :                     appendStringInfo(&buffer, _("role %s"), username);
    3617 GIC           5 :                 break;
    3618                 :             }
    3619                 : 
    3620 GNC          27 :         case OCLASS_ROLE_MEMBERSHIP:
    3621                 :             {
    3622                 :                 Relation    amDesc;
    3623                 :                 ScanKeyData skey[1];
    3624                 :                 SysScanDesc rcscan;
    3625                 :                 HeapTuple   tup;
    3626                 :                 Form_pg_auth_members amForm;
    3627                 : 
    3628              27 :                 amDesc = table_open(AuthMemRelationId, AccessShareLock);
    3629                 : 
    3630              27 :                 ScanKeyInit(&skey[0],
    3631                 :                             Anum_pg_auth_members_oid,
    3632                 :                             BTEqualStrategyNumber, F_OIDEQ,
    3633              27 :                             ObjectIdGetDatum(object->objectId));
    3634                 : 
    3635              27 :                 rcscan = systable_beginscan(amDesc, AuthMemOidIndexId, true,
    3636                 :                                             NULL, 1, skey);
    3637                 : 
    3638              27 :                 tup = systable_getnext(rcscan);
    3639                 : 
    3640              27 :                 if (!HeapTupleIsValid(tup))
    3641                 :                 {
    3642               3 :                     if (!missing_ok)
    3643 UNC           0 :                         elog(ERROR, "could not find tuple for role membership %u",
    3644                 :                              object->objectId);
    3645                 : 
    3646 GNC           3 :                     systable_endscan(rcscan);
    3647               3 :                     table_close(amDesc, AccessShareLock);
    3648               3 :                     break;
    3649                 :                 }
    3650                 : 
    3651              24 :                 amForm = (Form_pg_auth_members) GETSTRUCT(tup);
    3652                 : 
    3653              24 :                 appendStringInfo(&buffer, _("membership of role %s in role %s"),
    3654                 :                                  GetUserNameFromId(amForm->member, false),
    3655                 :                                  GetUserNameFromId(amForm->roleid, false));
    3656                 : 
    3657              24 :                 systable_endscan(rcscan);
    3658              24 :                 table_close(amDesc, AccessShareLock);
    3659              24 :                 break;
    3660                 :             }
    3661                 : 
    3662 CBC           9 :         case OCLASS_DATABASE:
    3663 ECB             :             {
    3664                 :                 char       *datname;
    3665                 : 
    3666 GIC           9 :                 datname = get_database_name(object->objectId);
    3667 CBC           9 :                 if (!datname)
    3668                 :                 {
    3669 GIC           3 :                     if (!missing_ok)
    3670 UIC           0 :                         elog(ERROR, "cache lookup failed for database %u",
    3671 ECB             :                              object->objectId);
    3672 CBC           3 :                     break;
    3673                 :                 }
    3674               6 :                 appendStringInfo(&buffer, _("database %s"), datname);
    3675 GBC           6 :                 break;
    3676                 :             }
    3677 ECB             : 
    3678 GIC           3 :         case OCLASS_TBLSPACE:
    3679 ECB             :             {
    3680                 :                 char       *tblspace;
    3681                 : 
    3682 GIC           3 :                 tblspace = get_tablespace_name(object->objectId);
    3683 CBC           3 :                 if (!tblspace)
    3684                 :                 {
    3685 GIC           3 :                     if (!missing_ok)
    3686 UIC           0 :                         elog(ERROR, "cache lookup failed for tablespace %u",
    3687 ECB             :                              object->objectId);
    3688 CBC           3 :                     break;
    3689                 :                 }
    3690 LBC           0 :                 appendStringInfo(&buffer, _("tablespace %s"), tblspace);
    3691 UBC           0 :                 break;
    3692                 :             }
    3693 ECB             : 
    3694 GIC          36 :         case OCLASS_FDW:
    3695 EUB             :             {
    3696                 :                 ForeignDataWrapper *fdw;
    3697                 : 
    3698 GIC          36 :                 fdw = GetForeignDataWrapperExtended(object->objectId,
    3699 ECB             :                                                     missing_ok);
    3700 GIC          36 :                 if (fdw)
    3701              33 :                     appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
    3702              36 :                 break;
    3703 ECB             :             }
    3704                 : 
    3705 CBC          64 :         case OCLASS_FOREIGN_SERVER:
    3706 ECB             :             {
    3707                 :                 ForeignServer *srv;
    3708                 : 
    3709 GIC          64 :                 srv = GetForeignServerExtended(object->objectId, missing_ok);
    3710 CBC          64 :                 if (srv)
    3711 GIC          61 :                     appendStringInfo(&buffer, _("server %s"), srv->servername);
    3712              64 :                 break;
    3713                 :             }
    3714 ECB             : 
    3715 CBC          66 :         case OCLASS_USER_MAPPING:
    3716 ECB             :             {
    3717                 :                 HeapTuple   tup;
    3718                 :                 Oid         useid;
    3719                 :                 char       *usename;
    3720                 :                 Form_pg_user_mapping umform;
    3721                 :                 ForeignServer *srv;
    3722                 : 
    3723 GIC          66 :                 tup = SearchSysCache1(USERMAPPINGOID,
    3724              66 :                                       ObjectIdGetDatum(object->objectId));
    3725              66 :                 if (!HeapTupleIsValid(tup))
    3726                 :                 {
    3727               3 :                     if (!missing_ok)
    3728 LBC           0 :                         elog(ERROR, "cache lookup failed for user mapping %u",
    3729 ECB             :                              object->objectId);
    3730 CBC           3 :                     break;
    3731                 :                 }
    3732 ECB             : 
    3733 GBC          63 :                 umform = (Form_pg_user_mapping) GETSTRUCT(tup);
    3734 GIC          63 :                 useid = umform->umuser;
    3735 CBC          63 :                 srv = GetForeignServer(umform->umserver);
    3736                 : 
    3737 GIC          63 :                 ReleaseSysCache(tup);
    3738 ECB             : 
    3739 CBC          63 :                 if (OidIsValid(useid))
    3740              50 :                     usename = GetUserNameFromId(useid, false);
    3741                 :                 else
    3742              13 :                     usename = "public";
    3743                 : 
    3744              63 :                 appendStringInfo(&buffer, _("user mapping for %s on server %s"), usename,
    3745 ECB             :                                  srv->servername);
    3746 GIC          63 :                 break;
    3747 ECB             :             }
    3748                 : 
    3749 CBC          24 :         case OCLASS_DEFACL:
    3750                 :             {
    3751 ECB             :                 Relation    defaclrel;
    3752                 :                 ScanKeyData skey[1];
    3753                 :                 SysScanDesc rcscan;
    3754                 :                 HeapTuple   tup;
    3755                 :                 Form_pg_default_acl defacl;
    3756                 :                 char       *rolename;
    3757                 :                 char       *nspname;
    3758                 : 
    3759 GIC          24 :                 defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
    3760                 : 
    3761              24 :                 ScanKeyInit(&skey[0],
    3762                 :                             Anum_pg_default_acl_oid,
    3763                 :                             BTEqualStrategyNumber, F_OIDEQ,
    3764 CBC          24 :                             ObjectIdGetDatum(object->objectId));
    3765                 : 
    3766              24 :                 rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
    3767                 :                                             true, NULL, 1, skey);
    3768                 : 
    3769              24 :                 tup = systable_getnext(rcscan);
    3770                 : 
    3771              24 :                 if (!HeapTupleIsValid(tup))
    3772                 :                 {
    3773 GIC           3 :                     if (!missing_ok)
    3774 LBC           0 :                         elog(ERROR, "could not find tuple for default ACL %u",
    3775                 :                              object->objectId);
    3776 ECB             : 
    3777 GIC           3 :                     systable_endscan(rcscan);
    3778 CBC           3 :                     table_close(defaclrel, AccessShareLock);
    3779 GBC           3 :                     break;
    3780                 :                 }
    3781                 : 
    3782 CBC          21 :                 defacl = (Form_pg_default_acl) GETSTRUCT(tup);
    3783 ECB             : 
    3784 CBC          21 :                 rolename = GetUserNameFromId(defacl->defaclrole, false);
    3785                 : 
    3786 GIC          21 :                 if (OidIsValid(defacl->defaclnamespace))
    3787 CBC          15 :                     nspname = get_namespace_name(defacl->defaclnamespace);
    3788                 :                 else
    3789               6 :                     nspname = NULL;
    3790                 : 
    3791              21 :                 switch (defacl->defaclobjtype)
    3792 ECB             :                 {
    3793 GIC          15 :                     case DEFACLOBJ_RELATION:
    3794 CBC          15 :                         if (nspname)
    3795 GIC           9 :                             appendStringInfo(&buffer,
    3796 CBC           9 :                                              _("default privileges on new relations belonging to role %s in schema %s"),
    3797                 :                                              rolename, nspname);
    3798 ECB             :                         else
    3799 CBC           6 :                             appendStringInfo(&buffer,
    3800               6 :                                              _("default privileges on new relations belonging to role %s"),
    3801 ECB             :                                              rolename);
    3802 GIC          15 :                         break;
    3803 UIC           0 :                     case DEFACLOBJ_SEQUENCE:
    3804 LBC           0 :                         if (nspname)
    3805               0 :                             appendStringInfo(&buffer,
    3806 UIC           0 :                                              _("default privileges on new sequences belonging to role %s in schema %s"),
    3807 ECB             :                                              rolename, nspname);
    3808 EUB             :                         else
    3809 UBC           0 :                             appendStringInfo(&buffer,
    3810               0 :                                              _("default privileges on new sequences belonging to role %s"),
    3811 EUB             :                                              rolename);
    3812 UIC           0 :                         break;
    3813 GIC           3 :                     case DEFACLOBJ_FUNCTION:
    3814 GBC           3 :                         if (nspname)
    3815               3 :                             appendStringInfo(&buffer,
    3816 GIC           3 :                                              _("default privileges on new functions belonging to role %s in schema %s"),
    3817 EUB             :                                              rolename, nspname);
    3818 ECB             :                         else
    3819 LBC           0 :                             appendStringInfo(&buffer,
    3820               0 :                                              _("default privileges on new functions belonging to role %s"),
    3821 ECB             :                                              rolename);
    3822 GIC           3 :                         break;
    3823               3 :                     case DEFACLOBJ_TYPE:
    3824 GBC           3 :                         if (nspname)
    3825               3 :                             appendStringInfo(&buffer,
    3826 GIC           3 :                                              _("default privileges on new types belonging to role %s in schema %s"),
    3827 ECB             :                                              rolename, nspname);
    3828                 :                         else
    3829 LBC           0 :                             appendStringInfo(&buffer,
    3830               0 :                                              _("default privileges on new types belonging to role %s"),
    3831 ECB             :                                              rolename);
    3832 GIC           3 :                         break;
    3833 UIC           0 :                     case DEFACLOBJ_NAMESPACE:
    3834 UBC           0 :                         Assert(!nspname);
    3835               0 :                         appendStringInfo(&buffer,
    3836 UIC           0 :                                          _("default privileges on new schemas belonging to role %s"),
    3837 ECB             :                                          rolename);
    3838 UBC           0 :                         break;
    3839               0 :                     default:
    3840 EUB             :                         /* shouldn't get here */
    3841 UBC           0 :                         if (nspname)
    3842 UIC           0 :                             appendStringInfo(&buffer,
    3843 UBC           0 :                                              _("default privileges belonging to role %s in schema %s"),
    3844 EUB             :                                              rolename, nspname);
    3845                 :                         else
    3846 UBC           0 :                             appendStringInfo(&buffer,
    3847               0 :                                              _("default privileges belonging to role %s"),
    3848 EUB             :                                              rolename);
    3849 UIC           0 :                         break;
    3850                 :                 }
    3851 EUB             : 
    3852 GBC          21 :                 systable_endscan(rcscan);
    3853 GIC          21 :                 table_close(defaclrel, AccessShareLock);
    3854 GBC          21 :                 break;
    3855                 :             }
    3856                 : 
    3857 CBC          25 :         case OCLASS_EXTENSION:
    3858 ECB             :             {
    3859                 :                 char       *extname;
    3860                 : 
    3861 GIC          25 :                 extname = get_extension_name(object->objectId);
    3862 CBC          25 :                 if (!extname)
    3863                 :                 {
    3864 GIC           3 :                     if (!missing_ok)
    3865 UIC           0 :                         elog(ERROR, "cache lookup failed for extension %u",
    3866 ECB             :                              object->objectId);
    3867 CBC           3 :                     break;
    3868                 :                 }
    3869              22 :                 appendStringInfo(&buffer, _("extension %s"), extname);
    3870 GBC          22 :                 break;
    3871                 :             }
    3872 ECB             : 
    3873 GIC          19 :         case OCLASS_EVENT_TRIGGER:
    3874 ECB             :             {
    3875                 :                 HeapTuple   tup;
    3876                 : 
    3877 GIC          19 :                 tup = SearchSysCache1(EVENTTRIGGEROID,
    3878 CBC          19 :                                       ObjectIdGetDatum(object->objectId));
    3879 GIC          19 :                 if (!HeapTupleIsValid(tup))
    3880                 :                 {
    3881               3 :                     if (!missing_ok)
    3882 LBC           0 :                         elog(ERROR, "cache lookup failed for event trigger %u",
    3883 ECB             :                              object->objectId);
    3884 CBC           3 :                     break;
    3885                 :                 }
    3886              16 :                 appendStringInfo(&buffer, _("event trigger %s"),
    3887 GBC          16 :                                  NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname));
    3888 GIC          16 :                 ReleaseSysCache(tup);
    3889 CBC          16 :                 break;
    3890                 :             }
    3891 ECB             : 
    3892 CBC          64 :         case OCLASS_PARAMETER_ACL:
    3893 ECB             :             {
    3894                 :                 HeapTuple   tup;
    3895                 :                 Datum       nameDatum;
    3896                 :                 char       *parname;
    3897                 : 
    3898 GIC          64 :                 tup = SearchSysCache1(PARAMETERACLOID,
    3899              64 :                                       ObjectIdGetDatum(object->objectId));
    3900              64 :                 if (!HeapTupleIsValid(tup))
    3901                 :                 {
    3902 CBC           3 :                     if (!missing_ok)
    3903 LBC           0 :                         elog(ERROR, "cache lookup failed for parameter ACL %u",
    3904 ECB             :                              object->objectId);
    3905 GIC           3 :                     break;
    3906 ECB             :                 }
    3907 GNC          61 :                 nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
    3908                 :                                                    Anum_pg_parameter_acl_parname);
    3909 CBC          61 :                 parname = TextDatumGetCString(nameDatum);
    3910 GIC          61 :                 appendStringInfo(&buffer, _("parameter %s"), parname);
    3911 CBC          61 :                 ReleaseSysCache(tup);
    3912              61 :                 break;
    3913 ECB             :             }
    3914                 : 
    3915 GIC         206 :         case OCLASS_POLICY:
    3916                 :             {
    3917 ECB             :                 Relation    policy_rel;
    3918                 :                 ScanKeyData skey[1];
    3919                 :                 SysScanDesc sscan;
    3920                 :                 HeapTuple   tuple;
    3921                 :                 Form_pg_policy form_policy;
    3922                 :                 StringInfoData rel;
    3923                 : 
    3924 GIC         206 :                 policy_rel = table_open(PolicyRelationId, AccessShareLock);
    3925                 : 
    3926 CBC         206 :                 ScanKeyInit(&skey[0],
    3927                 :                             Anum_pg_policy_oid,
    3928 ECB             :                             BTEqualStrategyNumber, F_OIDEQ,
    3929 GIC         206 :                             ObjectIdGetDatum(object->objectId));
    3930                 : 
    3931 CBC         206 :                 sscan = systable_beginscan(policy_rel, PolicyOidIndexId,
    3932                 :                                            true, NULL, 1, skey);
    3933 ECB             : 
    3934 GIC         206 :                 tuple = systable_getnext(sscan);
    3935                 : 
    3936 CBC         206 :                 if (!HeapTupleIsValid(tuple))
    3937                 :                 {
    3938               3 :                     if (!missing_ok)
    3939 UIC           0 :                         elog(ERROR, "could not find tuple for policy %u",
    3940 ECB             :                              object->objectId);
    3941 EUB             : 
    3942 GIC           3 :                     systable_endscan(sscan);
    3943               3 :                     table_close(policy_rel, AccessShareLock);
    3944 CBC           3 :                     break;
    3945 ECB             :                 }
    3946                 : 
    3947 GIC         203 :                 form_policy = (Form_pg_policy) GETSTRUCT(tuple);
    3948                 : 
    3949 CBC         203 :                 initStringInfo(&rel);
    3950 GIC         203 :                 getRelationDescription(&rel, form_policy->polrelid, false);
    3951 ECB             : 
    3952                 :                 /* translator: second %s is, e.g., "table %s" */
    3953 GIC         203 :                 appendStringInfo(&buffer, _("policy %s on %s"),
    3954             203 :                                  NameStr(form_policy->polname), rel.data);
    3955 CBC         203 :                 pfree(rel.data);
    3956             203 :                 systable_endscan(sscan);
    3957             203 :                 table_close(policy_rel, AccessShareLock);
    3958             203 :                 break;
    3959 ECB             :             }
    3960                 : 
    3961 GIC           3 :         case OCLASS_PUBLICATION:
    3962                 :             {
    3963 CBC           3 :                 char       *pubname = get_publication_name(object->objectId,
    3964                 :                                                            missing_ok);
    3965 ECB             : 
    3966 GIC           3 :                 if (pubname)
    3967 UIC           0 :                     appendStringInfo(&buffer, _("publication %s"), pubname);
    3968 CBC           3 :                 break;
    3969 EUB             :             }
    3970 ECB             : 
    3971 GIC          74 :         case OCLASS_PUBLICATION_NAMESPACE:
    3972                 :             {
    3973 ECB             :                 char       *pubname;
    3974                 :                 char       *nspname;
    3975                 : 
    3976 GIC          74 :                 if (!getPublicationSchemaInfo(object, missing_ok,
    3977                 :                                               &pubname, &nspname))
    3978 CBC           3 :                     break;
    3979                 : 
    3980              71 :                 appendStringInfo(&buffer, _("publication of schema %s in publication %s"),
    3981                 :                                  nspname, pubname);
    3982              71 :                 pfree(pubname);
    3983 GIC          71 :                 pfree(nspname);
    3984 CBC          71 :                 break;
    3985 ECB             :             }
    3986                 : 
    3987 GIC         159 :         case OCLASS_PUBLICATION_REL:
    3988                 :             {
    3989 ECB             :                 HeapTuple   tup;
    3990                 :                 char       *pubname;
    3991                 :                 Form_pg_publication_rel prform;
    3992                 :                 StringInfoData rel;
    3993                 : 
    3994 GIC         159 :                 tup = SearchSysCache1(PUBLICATIONREL,
    3995             159 :                                       ObjectIdGetDatum(object->objectId));
    3996 CBC         159 :                 if (!HeapTupleIsValid(tup))
    3997 ECB             :                 {
    3998 CBC           3 :                     if (!missing_ok)
    3999 UIC           0 :                         elog(ERROR, "cache lookup failed for publication table %u",
    4000 ECB             :                              object->objectId);
    4001 GBC           3 :                     break;
    4002                 :                 }
    4003 ECB             : 
    4004 GIC         156 :                 prform = (Form_pg_publication_rel) GETSTRUCT(tup);
    4005             156 :                 pubname = get_publication_name(prform->prpubid, false);
    4006 ECB             : 
    4007 CBC         156 :                 initStringInfo(&rel);
    4008 GIC         156 :                 getRelationDescription(&rel, prform->prrelid, false);
    4009 ECB             : 
    4010                 :                 /* translator: first %s is, e.g., "table %s" */
    4011 GIC         156 :                 appendStringInfo(&buffer, _("publication of %s in publication %s"),
    4012                 :                                  rel.data, pubname);
    4013 CBC         156 :                 pfree(rel.data);
    4014 GIC         156 :                 ReleaseSysCache(tup);
    4015 CBC         156 :                 break;
    4016 ECB             :             }
    4017                 : 
    4018 GIC           3 :         case OCLASS_SUBSCRIPTION:
    4019                 :             {
    4020 CBC           3 :                 char       *subname = get_subscription_name(object->objectId,
    4021                 :                                                             missing_ok);
    4022 ECB             : 
    4023 GIC           3 :                 if (subname)
    4024 UIC           0 :                     appendStringInfo(&buffer, _("subscription %s"), subname);
    4025 CBC           3 :                 break;
    4026 EUB             :             }
    4027 ECB             : 
    4028 GIC          12 :         case OCLASS_TRANSFORM:
    4029                 :             {
    4030 ECB             :                 HeapTuple   trfTup;
    4031                 :                 Form_pg_transform trfForm;
    4032                 : 
    4033 GIC          12 :                 trfTup = SearchSysCache1(TRFOID,
    4034              12 :                                          ObjectIdGetDatum(object->objectId));
    4035 CBC          12 :                 if (!HeapTupleIsValid(trfTup))
    4036 ECB             :                 {
    4037 CBC           3 :                     if (!missing_ok)
    4038 UIC           0 :                         elog(ERROR, "could not find tuple for transform %u",
    4039 ECB             :                              object->objectId);
    4040 GBC           3 :                     break;
    4041                 :                 }
    4042 ECB             : 
    4043 GIC           9 :                 trfForm = (Form_pg_transform) GETSTRUCT(trfTup);
    4044                 : 
    4045 CBC           9 :                 appendStringInfo(&buffer, _("transform for %s language %s"),
    4046                 :                                  format_type_be(trfForm->trftype),
    4047 ECB             :                                  get_language_name(trfForm->trflang, false));
    4048                 : 
    4049 GIC           9 :                 ReleaseSysCache(trfTup);
    4050               9 :                 break;
    4051 ECB             :             }
    4052                 : 
    4053                 :             /*
    4054                 :              * There's intentionally no default: case here; we want the
    4055                 :              * compiler to warn if a new OCLASS hasn't been handled above.
    4056                 :              */
    4057                 :     }
    4058                 : 
    4059                 :     /* an empty buffer is equivalent to no object found */
    4060 GIC       67185 :     if (buffer.len == 0)
    4061             126 :         return NULL;
    4062 ECB             : 
    4063 CBC       67059 :     return buffer.data;
    4064                 : }
    4065 ECB             : 
    4066                 : /*
    4067                 :  * getObjectDescriptionOids: as above, except the object is specified by Oids
    4068                 :  */
    4069                 : char *
    4070 UIC           0 : getObjectDescriptionOids(Oid classid, Oid objid)
    4071                 : {
    4072 EUB             :     ObjectAddress address;
    4073                 : 
    4074 UIC           0 :     address.classId = classid;
    4075               0 :     address.objectId = objid;
    4076 UBC           0 :     address.objectSubId = 0;
    4077 EUB             : 
    4078 UBC           0 :     return getObjectDescription(&address, false);
    4079                 : }
    4080 EUB             : 
    4081                 : /*
    4082                 :  * subroutine for getObjectDescription: describe a relation
    4083                 :  *
    4084                 :  * The result is appended to "buffer".
    4085                 :  */
    4086                 : static void
    4087 GIC       34862 : getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
    4088                 : {
    4089 ECB             :     HeapTuple   relTup;
    4090                 :     Form_pg_class relForm;
    4091                 :     char       *nspname;
    4092                 :     char       *relname;
    4093                 : 
    4094 GIC       34862 :     relTup = SearchSysCache1(RELOID,
    4095                 :                              ObjectIdGetDatum(relid));
    4096 CBC       34862 :     if (!HeapTupleIsValid(relTup))
    4097                 :     {
    4098               3 :         if (!missing_ok)
    4099 UIC           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    4100 CBC           3 :         return;
    4101 EUB             :     }
    4102 CBC       34859 :     relForm = (Form_pg_class) GETSTRUCT(relTup);
    4103                 : 
    4104 ECB             :     /* Qualify the name if not visible in search path */
    4105 GIC       34859 :     if (RelationIsVisible(relid))
    4106           24913 :         nspname = NULL;
    4107 ECB             :     else
    4108 CBC        9946 :         nspname = get_namespace_name(relForm->relnamespace);
    4109                 : 
    4110           34859 :     relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));
    4111                 : 
    4112           34859 :     switch (relForm->relkind)
    4113                 :     {
    4114           18884 :         case RELKIND_RELATION:
    4115                 :         case RELKIND_PARTITIONED_TABLE:
    4116           18884 :             appendStringInfo(buffer, _("table %s"),
    4117                 :                              relname);
    4118           18884 :             break;
    4119 GIC        9264 :         case RELKIND_INDEX:
    4120 ECB             :         case RELKIND_PARTITIONED_INDEX:
    4121 CBC        9264 :             appendStringInfo(buffer, _("index %s"),
    4122                 :                              relname);
    4123            9264 :             break;
    4124 GIC         340 :         case RELKIND_SEQUENCE:
    4125 CBC         340 :             appendStringInfo(buffer, _("sequence %s"),
    4126 ECB             :                              relname);
    4127 CBC         340 :             break;
    4128 GIC        4038 :         case RELKIND_TOASTVALUE:
    4129 CBC        4038 :             appendStringInfo(buffer, _("toast table %s"),
    4130 ECB             :                              relname);
    4131 CBC        4038 :             break;
    4132 GIC        1655 :         case RELKIND_VIEW:
    4133 CBC        1655 :             appendStringInfo(buffer, _("view %s"),
    4134 ECB             :                              relname);
    4135 CBC        1655 :             break;
    4136 GIC         285 :         case RELKIND_MATVIEW:
    4137 CBC         285 :             appendStringInfo(buffer, _("materialized view %s"),
    4138 ECB             :                              relname);
    4139 CBC         285 :             break;
    4140 GIC         220 :         case RELKIND_COMPOSITE_TYPE:
    4141 CBC         220 :             appendStringInfo(buffer, _("composite type %s"),
    4142 ECB             :                              relname);
    4143 CBC         220 :             break;
    4144 GIC         173 :         case RELKIND_FOREIGN_TABLE:
    4145 CBC         173 :             appendStringInfo(buffer, _("foreign table %s"),
    4146 ECB             :                              relname);
    4147 CBC         173 :             break;
    4148 UIC           0 :         default:
    4149 ECB             :             /* shouldn't get here */
    4150 UBC           0 :             appendStringInfo(buffer, _("relation %s"),
    4151                 :                              relname);
    4152               0 :             break;
    4153                 :     }
    4154 EUB             : 
    4155 GIC       34859 :     ReleaseSysCache(relTup);
    4156                 : }
    4157 ECB             : 
    4158                 : /*
    4159                 :  * subroutine for getObjectDescription: describe an operator family
    4160                 :  */
    4161                 : static void
    4162 GIC         700 : getOpFamilyDescription(StringInfo buffer, Oid opfid, bool missing_ok)
    4163                 : {
    4164 ECB             :     HeapTuple   opfTup;
    4165                 :     Form_pg_opfamily opfForm;
    4166                 :     HeapTuple   amTup;
    4167                 :     Form_pg_am  amForm;
    4168                 :     char       *nspname;
    4169                 : 
    4170 GIC         700 :     opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
    4171             700 :     if (!HeapTupleIsValid(opfTup))
    4172 ECB             :     {
    4173 CBC           3 :         if (!missing_ok)
    4174 UIC           0 :             elog(ERROR, "cache lookup failed for opfamily %u", opfid);
    4175 CBC           3 :         return;
    4176 EUB             :     }
    4177 CBC         697 :     opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
    4178                 : 
    4179             697 :     amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
    4180 GIC         697 :     if (!HeapTupleIsValid(amTup))
    4181 LBC           0 :         elog(ERROR, "cache lookup failed for access method %u",
    4182 ECB             :              opfForm->opfmethod);
    4183 GBC         697 :     amForm = (Form_pg_am) GETSTRUCT(amTup);
    4184                 : 
    4185 ECB             :     /* Qualify the name if not visible in search path */
    4186 GIC         697 :     if (OpfamilyIsVisible(opfid))
    4187             622 :         nspname = NULL;
    4188 ECB             :     else
    4189 CBC          75 :         nspname = get_namespace_name(opfForm->opfnamespace);
    4190                 : 
    4191             697 :     appendStringInfo(buffer, _("operator family %s for access method %s"),
    4192                 :                      quote_qualified_identifier(nspname,
    4193             697 :                                                 NameStr(opfForm->opfname)),
    4194 GIC         697 :                      NameStr(amForm->amname));
    4195 ECB             : 
    4196 CBC         697 :     ReleaseSysCache(amTup);
    4197 GIC         697 :     ReleaseSysCache(opfTup);
    4198 ECB             : }
    4199                 : 
    4200                 : /*
    4201                 :  * SQL-level callable version of getObjectDescription
    4202                 :  */
    4203                 : Datum
    4204 GIC         684 : pg_describe_object(PG_FUNCTION_ARGS)
    4205                 : {
    4206 CBC         684 :     Oid         classid = PG_GETARG_OID(0);
    4207 GIC         684 :     Oid         objid = PG_GETARG_OID(1);
    4208 CBC         684 :     int32       objsubid = PG_GETARG_INT32(2);
    4209 ECB             :     char       *description;
    4210                 :     ObjectAddress address;
    4211                 : 
    4212                 :     /* for "pinned" items in pg_depend, return null */
    4213 GIC         684 :     if (!OidIsValid(classid) && !OidIsValid(objid))
    4214 UIC           0 :         PG_RETURN_NULL();
    4215 ECB             : 
    4216 GBC         684 :     address.classId = classid;
    4217 GIC         684 :     address.objectId = objid;
    4218 CBC         684 :     address.objectSubId = objsubid;
    4219 ECB             : 
    4220 CBC         684 :     description = getObjectDescription(&address, true);
    4221                 : 
    4222             684 :     if (description == NULL)
    4223 GIC         126 :         PG_RETURN_NULL();
    4224 ECB             : 
    4225 CBC         558 :     PG_RETURN_TEXT_P(cstring_to_text(description));
    4226                 : }
    4227 ECB             : 
    4228                 : /*
    4229                 :  * SQL-level callable function to obtain object type + identity
    4230                 :  */
    4231                 : Datum
    4232 GIC        1041 : pg_identify_object(PG_FUNCTION_ARGS)
    4233                 : {
    4234 CBC        1041 :     Oid         classid = PG_GETARG_OID(0);
    4235 GIC        1041 :     Oid         objid = PG_GETARG_OID(1);
    4236 CBC        1041 :     int32       objsubid = PG_GETARG_INT32(2);
    4237            1041 :     Oid         schema_oid = InvalidOid;
    4238            1041 :     const char *objname = NULL;
    4239 ECB             :     char       *objidentity;
    4240                 :     ObjectAddress address;
    4241                 :     Datum       values[4];
    4242                 :     bool        nulls[4];
    4243                 :     TupleDesc   tupdesc;
    4244                 :     HeapTuple   htup;
    4245                 : 
    4246 GIC        1041 :     address.classId = classid;
    4247            1041 :     address.objectId = objid;
    4248 CBC        1041 :     address.objectSubId = objsubid;
    4249 ECB             : 
    4250 GNC        1041 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
    4251 UNC           0 :         elog(ERROR, "return type must be a row type");
    4252                 : 
    4253 GIC        1041 :     if (is_objectclass_supported(address.classId))
    4254                 :     {
    4255                 :         HeapTuple   objtup;
    4256 CBC         971 :         Relation    catalog = table_open(address.classId, AccessShareLock);
    4257 ECB             : 
    4258 GIC         971 :         objtup = get_catalog_object_by_oid(catalog,
    4259 CBC         971 :                                            get_object_attnum_oid(address.classId),
    4260                 :                                            address.objectId);
    4261             971 :         if (objtup != NULL)
    4262 EUB             :         {
    4263                 :             bool        isnull;
    4264                 :             AttrNumber  nspAttnum;
    4265                 :             AttrNumber  nameAttnum;
    4266                 : 
    4267 GIC         863 :             nspAttnum = get_object_attnum_namespace(address.classId);
    4268             863 :             if (nspAttnum != InvalidAttrNumber)
    4269                 :             {
    4270 CBC         529 :                 schema_oid = heap_getattr(objtup, nspAttnum,
    4271                 :                                           RelationGetDescr(catalog), &isnull);
    4272             529 :                 if (isnull)
    4273 LBC           0 :                     elog(ERROR, "invalid null namespace in object %u/%u/%d",
    4274                 :                          address.classId, address.objectId, address.objectSubId);
    4275                 :             }
    4276                 : 
    4277 ECB             :             /*
    4278                 :              * We only return the object name if it can be used (together with
    4279                 :              * the schema name, if any) as a unique identifier.
    4280 EUB             :              */
    4281 GIC         863 :             if (get_object_namensp_unique(address.classId))
    4282 ECB             :             {
    4283 GIC         572 :                 nameAttnum = get_object_attnum_name(address.classId);
    4284             572 :                 if (nameAttnum != InvalidAttrNumber)
    4285                 :                 {
    4286                 :                     Datum       nameDatum;
    4287 ECB             : 
    4288 GIC         572 :                     nameDatum = heap_getattr(objtup, nameAttnum,
    4289                 :                                              RelationGetDescr(catalog), &isnull);
    4290             572 :                     if (isnull)
    4291 LBC           0 :                         elog(ERROR, "invalid null name in object %u/%u/%d",
    4292 ECB             :                              address.classId, address.objectId, address.objectSubId);
    4293 GIC         572 :                     objname = quote_identifier(NameStr(*(DatumGetName(nameDatum))));
    4294                 :                 }
    4295                 :             }
    4296                 :         }
    4297                 : 
    4298 CBC         971 :         table_close(catalog, AccessShareLock);
    4299                 :     }
    4300                 : 
    4301 ECB             :     /* object type, which can never be NULL */
    4302 CBC        1041 :     values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
    4303            1041 :     nulls[0] = false;
    4304                 : 
    4305 ECB             :     /*
    4306                 :      * Before doing anything, extract the object identity.  If the identity
    4307                 :      * could not be found, set all the fields except the object type to NULL.
    4308                 :      */
    4309 CBC        1041 :     objidentity = getObjectIdentity(&address, true);
    4310                 : 
    4311                 :     /* schema name */
    4312            1041 :     if (OidIsValid(schema_oid) && objidentity)
    4313 GIC         526 :     {
    4314 CBC         526 :         const char *schema = quote_identifier(get_namespace_name(schema_oid));
    4315 ECB             : 
    4316 GIC         526 :         values[1] = CStringGetTextDatum(schema);
    4317             526 :         nulls[1] = false;
    4318 ECB             :     }
    4319                 :     else
    4320 GIC         515 :         nulls[1] = true;
    4321 ECB             : 
    4322                 :     /* object name */
    4323 CBC        1041 :     if (objname && objidentity)
    4324 ECB             :     {
    4325 GIC         569 :         values[2] = CStringGetTextDatum(objname);
    4326             569 :         nulls[2] = false;
    4327 ECB             :     }
    4328                 :     else
    4329 CBC         472 :         nulls[2] = true;
    4330                 : 
    4331 ECB             :     /* object identity */
    4332 GIC        1041 :     if (objidentity)
    4333                 :     {
    4334             915 :         values[3] = CStringGetTextDatum(objidentity);
    4335             915 :         nulls[3] = false;
    4336                 :     }
    4337                 :     else
    4338 CBC         126 :         nulls[3] = true;
    4339                 : 
    4340            1041 :     htup = heap_form_tuple(tupdesc, values, nulls);
    4341 ECB             : 
    4342 CBC        1041 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
    4343                 : }
    4344                 : 
    4345                 : /*
    4346                 :  * SQL-level callable function to obtain object type + identity
    4347                 :  */
    4348                 : Datum
    4349 GIC         286 : pg_identify_object_as_address(PG_FUNCTION_ARGS)
    4350                 : {
    4351             286 :     Oid         classid = PG_GETARG_OID(0);
    4352 CBC         286 :     Oid         objid = PG_GETARG_OID(1);
    4353             286 :     int32       objsubid = PG_GETARG_INT32(2);
    4354 ECB             :     ObjectAddress address;
    4355                 :     char       *identity;
    4356                 :     List       *names;
    4357 EUB             :     List       *args;
    4358                 :     Datum       values[3];
    4359                 :     bool        nulls[3];
    4360 ECB             :     TupleDesc   tupdesc;
    4361                 :     HeapTuple   htup;
    4362                 : 
    4363 GIC         286 :     address.classId = classid;
    4364 CBC         286 :     address.objectId = objid;
    4365             286 :     address.objectSubId = objsubid;
    4366                 : 
    4367 GNC         286 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
    4368 UNC           0 :         elog(ERROR, "return type must be a row type");
    4369                 : 
    4370                 :     /* object type, which can never be NULL */
    4371 CBC         286 :     values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
    4372             286 :     nulls[0] = false;
    4373                 : 
    4374 ECB             :     /* object identity */
    4375 CBC         286 :     identity = getObjectIdentityParts(&address, &names, &args, true);
    4376 GIC         286 :     if (identity == NULL)
    4377                 :     {
    4378 CBC         126 :         nulls[1] = true;
    4379 GIC         126 :         nulls[2] = true;
    4380 ECB             :     }
    4381                 :     else
    4382                 :     {
    4383 GIC         160 :         pfree(identity);
    4384                 : 
    4385                 :         /* object_names */
    4386             160 :         if (names != NIL)
    4387             160 :             values[1] = PointerGetDatum(strlist_to_textarray(names));
    4388                 :         else
    4389 UIC           0 :             values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
    4390 CBC         160 :         nulls[1] = false;
    4391                 : 
    4392                 :         /* object_args */
    4393 GIC         160 :         if (args)
    4394 CBC          42 :             values[2] = PointerGetDatum(strlist_to_textarray(args));
    4395                 :         else
    4396             118 :             values[2] = PointerGetDatum(construct_empty_array(TEXTOID));
    4397 GIC         160 :         nulls[2] = false;
    4398 ECB             :     }
    4399                 : 
    4400 CBC         286 :     htup = heap_form_tuple(tupdesc, values, nulls);
    4401                 : 
    4402             286 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
    4403                 : }
    4404 ECB             : 
    4405                 : /*
    4406                 :  * Return a palloc'ed string that describes the type of object that the
    4407                 :  * passed address is for.
    4408                 :  *
    4409                 :  * Keep ObjectTypeMap in sync with this.
    4410                 :  */
    4411                 : char *
    4412 GIC        2799 : getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
    4413 ECB             : {
    4414                 :     StringInfoData buffer;
    4415                 : 
    4416 GIC        2799 :     initStringInfo(&buffer);
    4417 ECB             : 
    4418 CBC        2799 :     switch (getObjectClass(object))
    4419 ECB             :     {
    4420 GIC         790 :         case OCLASS_CLASS:
    4421 CBC         790 :             getRelationTypeDescription(&buffer, object->objectId,
    4422             790 :                                        object->objectSubId,
    4423                 :                                        missing_ok);
    4424             790 :             break;
    4425                 : 
    4426             131 :         case OCLASS_PROC:
    4427             131 :             getProcedureTypeDescription(&buffer, object->objectId,
    4428 ECB             :                                         missing_ok);
    4429 GIC         131 :             break;
    4430 ECB             : 
    4431 CBC         468 :         case OCLASS_TYPE:
    4432             468 :             appendStringInfoString(&buffer, "type");
    4433 GIC         468 :             break;
    4434 ECB             : 
    4435 CBC          31 :         case OCLASS_CAST:
    4436              31 :             appendStringInfoString(&buffer, "cast");
    4437 GIC          31 :             break;
    4438 ECB             : 
    4439 CBC          27 :         case OCLASS_COLLATION:
    4440              27 :             appendStringInfoString(&buffer, "collation");
    4441 GIC          27 :             break;
    4442 ECB             : 
    4443 CBC         207 :         case OCLASS_CONSTRAINT:
    4444             207 :             getConstraintTypeDescription(&buffer, object->objectId,
    4445                 :                                          missing_ok);
    4446             207 :             break;
    4447 ECB             : 
    4448 CBC          28 :         case OCLASS_CONVERSION:
    4449 GIC          28 :             appendStringInfoString(&buffer, "conversion");
    4450 CBC          28 :             break;
    4451 ECB             : 
    4452 CBC         199 :         case OCLASS_DEFAULT:
    4453 GIC         199 :             appendStringInfoString(&buffer, "default value");
    4454 CBC         199 :             break;
    4455 ECB             : 
    4456 CBC          27 :         case OCLASS_LANGUAGE:
    4457 GIC          27 :             appendStringInfoString(&buffer, "language");
    4458 CBC          27 :             break;
    4459 ECB             : 
    4460 CBC           6 :         case OCLASS_LARGEOBJECT:
    4461 GIC           6 :             appendStringInfoString(&buffer, "large object");
    4462 CBC           6 :             break;
    4463 ECB             : 
    4464 CBC          29 :         case OCLASS_OPERATOR:
    4465 GIC          29 :             appendStringInfoString(&buffer, "operator");
    4466 CBC          29 :             break;
    4467 ECB             : 
    4468 CBC          31 :         case OCLASS_OPCLASS:
    4469 GIC          31 :             appendStringInfoString(&buffer, "operator class");
    4470 CBC          31 :             break;
    4471 ECB             : 
    4472 CBC          32 :         case OCLASS_OPFAMILY:
    4473 GIC          32 :             appendStringInfoString(&buffer, "operator family");
    4474 CBC          32 :             break;
    4475 ECB             : 
    4476 CBC          27 :         case OCLASS_AM:
    4477 GIC          27 :             appendStringInfoString(&buffer, "access method");
    4478 CBC          27 :             break;
    4479 ECB             : 
    4480 CBC          27 :         case OCLASS_AMOP:
    4481 GIC          27 :             appendStringInfoString(&buffer, "operator of access method");
    4482 CBC          27 :             break;
    4483 ECB             : 
    4484 CBC          27 :         case OCLASS_AMPROC:
    4485 GIC          27 :             appendStringInfoString(&buffer, "function of access method");
    4486 CBC          27 :             break;
    4487 ECB             : 
    4488 CBC          38 :         case OCLASS_REWRITE:
    4489 GIC          38 :             appendStringInfoString(&buffer, "rule");
    4490 CBC          38 :             break;
    4491 ECB             : 
    4492 CBC          78 :         case OCLASS_TRIGGER:
    4493 GIC          78 :             appendStringInfoString(&buffer, "trigger");
    4494 CBC          78 :             break;
    4495 ECB             : 
    4496 CBC          59 :         case OCLASS_SCHEMA:
    4497 GIC          59 :             appendStringInfoString(&buffer, "schema");
    4498 CBC          59 :             break;
    4499 ECB             : 
    4500 CBC          28 :         case OCLASS_STATISTIC_EXT:
    4501 GIC          28 :             appendStringInfoString(&buffer, "statistics object");
    4502 CBC          28 :             break;
    4503 ECB             : 
    4504 CBC          27 :         case OCLASS_TSPARSER:
    4505 GIC          27 :             appendStringInfoString(&buffer, "text search parser");
    4506 CBC          27 :             break;
    4507 ECB             : 
    4508 CBC          27 :         case OCLASS_TSDICT:
    4509 GIC          27 :             appendStringInfoString(&buffer, "text search dictionary");
    4510 CBC          27 :             break;
    4511 ECB             : 
    4512 CBC          27 :         case OCLASS_TSTEMPLATE:
    4513 GIC          27 :             appendStringInfoString(&buffer, "text search template");
    4514 CBC          27 :             break;
    4515 ECB             : 
    4516 CBC          29 :         case OCLASS_TSCONFIG:
    4517 GIC          29 :             appendStringInfoString(&buffer, "text search configuration");
    4518 CBC          29 :             break;
    4519 ECB             : 
    4520 CBC          27 :         case OCLASS_ROLE:
    4521 GIC          27 :             appendStringInfoString(&buffer, "role");
    4522 CBC          27 :             break;
    4523 ECB             : 
    4524 GNC           6 :         case OCLASS_ROLE_MEMBERSHIP:
    4525               6 :             appendStringInfoString(&buffer, "role membership");
    4526               6 :             break;
    4527                 : 
    4528 CBC           6 :         case OCLASS_DATABASE:
    4529 GIC           6 :             appendStringInfoString(&buffer, "database");
    4530 CBC           6 :             break;
    4531 ECB             : 
    4532 CBC           6 :         case OCLASS_TBLSPACE:
    4533 GIC           6 :             appendStringInfoString(&buffer, "tablespace");
    4534 CBC           6 :             break;
    4535 ECB             : 
    4536 CBC          30 :         case OCLASS_FDW:
    4537 GIC          30 :             appendStringInfoString(&buffer, "foreign-data wrapper");
    4538 CBC          30 :             break;
    4539 ECB             : 
    4540 CBC          30 :         case OCLASS_FOREIGN_SERVER:
    4541 GIC          30 :             appendStringInfoString(&buffer, "server");
    4542 CBC          30 :             break;
    4543 ECB             : 
    4544 CBC          30 :         case OCLASS_USER_MAPPING:
    4545 GIC          30 :             appendStringInfoString(&buffer, "user mapping");
    4546 CBC          30 :             break;
    4547 ECB             : 
    4548 CBC          51 :         case OCLASS_DEFACL:
    4549 GIC          51 :             appendStringInfoString(&buffer, "default acl");
    4550 CBC          51 :             break;
    4551 ECB             : 
    4552 CBC          14 :         case OCLASS_EXTENSION:
    4553 GIC          14 :             appendStringInfoString(&buffer, "extension");
    4554 CBC          14 :             break;
    4555 ECB             : 
    4556 CBC          24 :         case OCLASS_EVENT_TRIGGER:
    4557 GIC          24 :             appendStringInfoString(&buffer, "event trigger");
    4558 CBC          24 :             break;
    4559 ECB             : 
    4560 CBC           8 :         case OCLASS_PARAMETER_ACL:
    4561 GIC           8 :             appendStringInfoString(&buffer, "parameter ACL");
    4562 CBC           8 :             break;
    4563 ECB             : 
    4564 CBC          30 :         case OCLASS_POLICY:
    4565 GIC          30 :             appendStringInfoString(&buffer, "policy");
    4566 CBC          30 :             break;
    4567 ECB             : 
    4568 CBC          27 :         case OCLASS_PUBLICATION:
    4569 GIC          27 :             appendStringInfoString(&buffer, "publication");
    4570              27 :             break;
    4571                 : 
    4572              27 :         case OCLASS_PUBLICATION_NAMESPACE:
    4573              27 :             appendStringInfoString(&buffer, "publication namespace");
    4574              27 :             break;
    4575                 : 
    4576              27 :         case OCLASS_PUBLICATION_REL:
    4577 CBC          27 :             appendStringInfoString(&buffer, "publication relation");
    4578 GIC          27 :             break;
    4579 ECB             : 
    4580 GIC          27 :         case OCLASS_SUBSCRIPTION:
    4581              27 :             appendStringInfoString(&buffer, "subscription");
    4582              27 :             break;
    4583                 : 
    4584              29 :         case OCLASS_TRANSFORM:
    4585              29 :             appendStringInfoString(&buffer, "transform");
    4586 CBC          29 :             break;
    4587                 : 
    4588                 :             /*
    4589                 :              * There's intentionally no default: case here; we want the
    4590                 :              * compiler to warn if a new OCLASS hasn't been handled above.
    4591                 :              */
    4592 ECB             :     }
    4593                 : 
    4594                 :     /* the result can never be empty */
    4595 GIC        2799 :     Assert(buffer.len > 0);
    4596 ECB             : 
    4597 GBC        2799 :     return buffer.data;
    4598                 : }
    4599                 : 
    4600 ECB             : /*
    4601                 :  * subroutine for getObjectTypeDescription: describe a relation type
    4602                 :  */
    4603                 : static void
    4604 GIC         790 : getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId,
    4605 ECB             :                            bool missing_ok)
    4606                 : {
    4607                 :     HeapTuple   relTup;
    4608                 :     Form_pg_class relForm;
    4609                 : 
    4610 CBC         790 :     relTup = SearchSysCache1(RELOID,
    4611 ECB             :                              ObjectIdGetDatum(relid));
    4612 GIC         790 :     if (!HeapTupleIsValid(relTup))
    4613 ECB             :     {
    4614 CBC           6 :         if (!missing_ok)
    4615 LBC           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    4616 ECB             : 
    4617                 :         /* fallback to "relation" for an undefined object */
    4618 CBC           6 :         appendStringInfoString(buffer, "relation");
    4619               6 :         return;
    4620 ECB             :     }
    4621 CBC         784 :     relForm = (Form_pg_class) GETSTRUCT(relTup);
    4622 ECB             : 
    4623 CBC         784 :     switch (relForm->relkind)
    4624 ECB             :     {
    4625 CBC         365 :         case RELKIND_RELATION:
    4626 ECB             :         case RELKIND_PARTITIONED_TABLE:
    4627 CBC         365 :             appendStringInfoString(buffer, "table");
    4628             365 :             break;
    4629             177 :         case RELKIND_INDEX:
    4630 ECB             :         case RELKIND_PARTITIONED_INDEX:
    4631 CBC         177 :             appendStringInfoString(buffer, "index");
    4632             177 :             break;
    4633 GBC          91 :         case RELKIND_SEQUENCE:
    4634 GIC          91 :             appendStringInfoString(buffer, "sequence");
    4635 GBC          91 :             break;
    4636              42 :         case RELKIND_TOASTVALUE:
    4637 GIC          42 :             appendStringInfoString(buffer, "toast table");
    4638              42 :             break;
    4639 CBC          36 :         case RELKIND_VIEW:
    4640              36 :             appendStringInfoString(buffer, "view");
    4641 GIC          36 :             break;
    4642 CBC          27 :         case RELKIND_MATVIEW:
    4643 GIC          27 :             appendStringInfoString(buffer, "materialized view");
    4644              27 :             break;
    4645               1 :         case RELKIND_COMPOSITE_TYPE:
    4646               1 :             appendStringInfoString(buffer, "composite type");
    4647               1 :             break;
    4648              45 :         case RELKIND_FOREIGN_TABLE:
    4649 CBC          45 :             appendStringInfoString(buffer, "foreign table");
    4650 GIC          45 :             break;
    4651 UIC           0 :         default:
    4652                 :             /* shouldn't get here */
    4653               0 :             appendStringInfoString(buffer, "relation");
    4654               0 :             break;
    4655 ECB             :     }
    4656                 : 
    4657 GIC         784 :     if (objectSubId != 0)
    4658 CBC          61 :         appendStringInfoString(buffer, " column");
    4659                 : 
    4660             784 :     ReleaseSysCache(relTup);
    4661 EUB             : }
    4662                 : 
    4663 ECB             : /*
    4664                 :  * subroutine for getObjectTypeDescription: describe a constraint type
    4665                 :  */
    4666                 : static void
    4667 CBC         207 : getConstraintTypeDescription(StringInfo buffer, Oid constroid, bool missing_ok)
    4668                 : {
    4669                 :     Relation    constrRel;
    4670 ECB             :     HeapTuple   constrTup;
    4671                 :     Form_pg_constraint constrForm;
    4672                 : 
    4673 CBC         207 :     constrRel = table_open(ConstraintRelationId, AccessShareLock);
    4674             207 :     constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid,
    4675 ECB             :                                           constroid);
    4676 GIC         207 :     if (!HeapTupleIsValid(constrTup))
    4677 EUB             :     {
    4678 GIC           6 :         if (!missing_ok)
    4679 LBC           0 :             elog(ERROR, "cache lookup failed for constraint %u", constroid);
    4680                 : 
    4681 GIC           6 :         table_close(constrRel, AccessShareLock);
    4682                 : 
    4683                 :         /* fallback to "constraint" for an undefined object */
    4684               6 :         appendStringInfoString(buffer, "constraint");
    4685               6 :         return;
    4686 ECB             :     }
    4687                 : 
    4688 GIC         201 :     constrForm = (Form_pg_constraint) GETSTRUCT(constrTup);
    4689                 : 
    4690             201 :     if (OidIsValid(constrForm->conrelid))
    4691             180 :         appendStringInfoString(buffer, "table constraint");
    4692 CBC          21 :     else if (OidIsValid(constrForm->contypid))
    4693 GIC          21 :         appendStringInfoString(buffer, "domain constraint");
    4694 ECB             :     else
    4695 UIC           0 :         elog(ERROR, "invalid constraint %u", constrForm->oid);
    4696 ECB             : 
    4697 GBC         201 :     table_close(constrRel, AccessShareLock);
    4698                 : }
    4699                 : 
    4700 ECB             : /*
    4701                 :  * subroutine for getObjectTypeDescription: describe a procedure type
    4702                 :  */
    4703                 : static void
    4704 GIC         131 : getProcedureTypeDescription(StringInfo buffer, Oid procid,
    4705 ECB             :                             bool missing_ok)
    4706                 : {
    4707                 :     HeapTuple   procTup;
    4708                 :     Form_pg_proc procForm;
    4709                 : 
    4710 CBC         131 :     procTup = SearchSysCache1(PROCOID,
    4711                 :                               ObjectIdGetDatum(procid));
    4712             131 :     if (!HeapTupleIsValid(procTup))
    4713                 :     {
    4714 GIC           6 :         if (!missing_ok)
    4715 UIC           0 :             elog(ERROR, "cache lookup failed for procedure %u", procid);
    4716                 : 
    4717                 :         /* fallback to "procedure" for an undefined object */
    4718 GIC           6 :         appendStringInfoString(buffer, "routine");
    4719               6 :         return;
    4720                 :     }
    4721             125 :     procForm = (Form_pg_proc) GETSTRUCT(procTup);
    4722                 : 
    4723 CBC         125 :     if (procForm->prokind == PROKIND_AGGREGATE)
    4724 GIC          30 :         appendStringInfoString(buffer, "aggregate");
    4725 CBC          95 :     else if (procForm->prokind == PROKIND_PROCEDURE)
    4726 GIC          24 :         appendStringInfoString(buffer, "procedure");
    4727                 :     else                        /* function or window function */
    4728              71 :         appendStringInfoString(buffer, "function");
    4729                 : 
    4730             125 :     ReleaseSysCache(procTup);
    4731                 : }
    4732                 : 
    4733                 : /*
    4734                 :  * Obtain a given object's identity, as a palloc'ed string.
    4735                 :  *
    4736                 :  * This is for machine consumption, so it's not translated.  All elements are
    4737                 :  * schema-qualified when appropriate.  Returns NULL if the object could not
    4738 ECB             :  * be found.
    4739                 :  */
    4740                 : char *
    4741 GIC        1310 : getObjectIdentity(const ObjectAddress *object, bool missing_ok)
    4742                 : {
    4743            1310 :     return getObjectIdentityParts(object, NULL, NULL, missing_ok);
    4744 ECB             : }
    4745                 : 
    4746                 : /*
    4747                 :  * As above, but more detailed.
    4748                 :  *
    4749                 :  * There are two sets of return values: the identity itself as a palloc'd
    4750                 :  * string is returned.  objname and objargs, if not NULL, are output parameters
    4751                 :  * that receive lists of C-strings that are useful to give back to
    4752                 :  * get_object_address() to reconstruct the ObjectAddress.  Returns NULL if
    4753                 :  * the object could not be found.
    4754                 :  */
    4755                 : char *
    4756 CBC        3016 : getObjectIdentityParts(const ObjectAddress *object,
    4757                 :                        List **objname, List **objargs,
    4758                 :                        bool missing_ok)
    4759 ECB             : {
    4760                 :     StringInfoData buffer;
    4761                 : 
    4762 GIC        3016 :     initStringInfo(&buffer);
    4763 ECB             : 
    4764                 :     /*
    4765                 :      * Make sure that both objname and objargs were passed, or none was; and
    4766                 :      * initialize them to empty lists.  For objname this is useless because it
    4767                 :      * will be initialized in all cases inside the switch; but we do it anyway
    4768                 :      * so that we can test below that no branch leaves it unset.
    4769                 :      */
    4770 GIC        3016 :     Assert(PointerIsValid(objname) == PointerIsValid(objargs));
    4771 CBC        3016 :     if (objname)
    4772 ECB             :     {
    4773 GIC        1670 :         *objname = NIL;
    4774            1670 :         *objargs = NIL;
    4775 ECB             :     }
    4776                 : 
    4777 GIC        3016 :     switch (getObjectClass(object))
    4778                 :     {
    4779 CBC         986 :         case OCLASS_CLASS:
    4780                 :             {
    4781             986 :                 char       *attr = NULL;
    4782 ECB             : 
    4783                 :                 /*
    4784                 :                  * Check for the attribute first, so as if it is missing we
    4785                 :                  * can skip the entire relation description.
    4786                 :                  */
    4787 GIC         986 :                 if (object->objectSubId != 0)
    4788 ECB             :                 {
    4789 CBC         254 :                     attr = get_attname(object->objectId,
    4790 GIC         254 :                                        object->objectSubId,
    4791                 :                                        missing_ok);
    4792 ECB             : 
    4793 GIC         254 :                     if (missing_ok && attr == NULL)
    4794 CBC           6 :                         break;
    4795                 :                 }
    4796 ECB             : 
    4797 CBC         980 :                 getRelationIdentity(&buffer, object->objectId, objname,
    4798                 :                                     missing_ok);
    4799 GIC         980 :                 if (objname && *objname == NIL)
    4800 CBC           3 :                     break;
    4801 ECB             : 
    4802 GIC         977 :                 if (attr)
    4803 ECB             :                 {
    4804 CBC         248 :                     appendStringInfo(&buffer, ".%s",
    4805 ECB             :                                      quote_identifier(attr));
    4806 GIC         248 :                     if (objname)
    4807 CBC         193 :                         *objname = lappend(*objname, attr);
    4808                 :                 }
    4809                 :             }
    4810             977 :             break;
    4811                 : 
    4812             131 :         case OCLASS_PROC:
    4813                 :             {
    4814 GIC         131 :                 bits16      flags = FORMAT_PROC_FORCE_QUALIFY | FORMAT_PROC_INVALID_AS_NULL;
    4815 CBC         131 :                 char       *proname = format_procedure_extended(object->objectId,
    4816                 :                                                                 flags);
    4817 ECB             : 
    4818 CBC         131 :                 if (proname == NULL)
    4819 GIC           6 :                     break;
    4820 ECB             : 
    4821 CBC         125 :                 appendStringInfoString(&buffer, proname);
    4822             125 :                 if (objname)
    4823 GIC          51 :                     format_procedure_parts(object->objectId, objname, objargs,
    4824 ECB             :                                            missing_ok);
    4825 GIC         125 :                 break;
    4826 ECB             :             }
    4827                 : 
    4828 GIC         489 :         case OCLASS_TYPE:
    4829                 :             {
    4830             489 :                 bits16      flags = FORMAT_TYPE_INVALID_AS_NULL | FORMAT_TYPE_FORCE_QUALIFY;
    4831                 :                 char       *typeout;
    4832 ECB             : 
    4833 GIC         489 :                 typeout = format_type_extended(object->objectId, -1, flags);
    4834 ECB             : 
    4835 CBC         489 :                 if (typeout == NULL)
    4836 GIC           6 :                     break;
    4837 ECB             : 
    4838 GIC         483 :                 appendStringInfoString(&buffer, typeout);
    4839 CBC         483 :                 if (objname)
    4840 GBC         375 :                     *objname = list_make1(typeout);
    4841                 :             }
    4842 GIC         483 :             break;
    4843 ECB             : 
    4844 CBC          31 :         case OCLASS_CAST:
    4845                 :             {
    4846                 :                 Relation    castRel;
    4847 ECB             :                 HeapTuple   tup;
    4848                 :                 Form_pg_cast castForm;
    4849                 : 
    4850 GIC          31 :                 castRel = table_open(CastRelationId, AccessShareLock);
    4851                 : 
    4852              31 :                 tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid,
    4853 CBC          31 :                                                 object->objectId);
    4854                 : 
    4855              31 :                 if (!HeapTupleIsValid(tup))
    4856 ECB             :                 {
    4857 GIC           6 :                     if (!missing_ok)
    4858 UIC           0 :                         elog(ERROR, "could not find tuple for cast %u",
    4859 ECB             :                              object->objectId);
    4860                 : 
    4861 GIC           6 :                     table_close(castRel, AccessShareLock);
    4862               6 :                     break;
    4863 ECB             :                 }
    4864                 : 
    4865 GIC          25 :                 castForm = (Form_pg_cast) GETSTRUCT(tup);
    4866                 : 
    4867              25 :                 appendStringInfo(&buffer, "(%s AS %s)",
    4868                 :                                  format_type_be_qualified(castForm->castsource),
    4869 ECB             :                                  format_type_be_qualified(castForm->casttarget));
    4870                 : 
    4871 CBC          25 :                 if (objname)
    4872                 :                 {
    4873               3 :                     *objname = list_make1(format_type_be_qualified(castForm->castsource));
    4874 GBC           3 :                     *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
    4875                 :                 }
    4876 ECB             : 
    4877 GIC          25 :                 table_close(castRel, AccessShareLock);
    4878 CBC          25 :                 break;
    4879 ECB             :             }
    4880                 : 
    4881 CBC          27 :         case OCLASS_COLLATION:
    4882 ECB             :             {
    4883                 :                 HeapTuple   collTup;
    4884                 :                 Form_pg_collation coll;
    4885                 :                 char       *schema;
    4886                 : 
    4887 CBC          27 :                 collTup = SearchSysCache1(COLLOID,
    4888 GIC          27 :                                           ObjectIdGetDatum(object->objectId));
    4889              27 :                 if (!HeapTupleIsValid(collTup))
    4890 ECB             :                 {
    4891 GIC           6 :                     if (!missing_ok)
    4892 UIC           0 :                         elog(ERROR, "cache lookup failed for collation %u",
    4893                 :                              object->objectId);
    4894 GIC           6 :                     break;
    4895 ECB             :                 }
    4896 CBC          21 :                 coll = (Form_pg_collation) GETSTRUCT(collTup);
    4897              21 :                 schema = get_namespace_name_or_temp(coll->collnamespace);
    4898 GIC          21 :                 appendStringInfoString(&buffer,
    4899 CBC          21 :                                        quote_qualified_identifier(schema,
    4900 GBC          21 :                                                                   NameStr(coll->collname)));
    4901 GIC          21 :                 if (objname)
    4902 CBC           3 :                     *objname = list_make2(schema,
    4903                 :                                           pstrdup(NameStr(coll->collname)));
    4904              21 :                 ReleaseSysCache(collTup);
    4905 GIC          21 :                 break;
    4906 ECB             :             }
    4907                 : 
    4908 CBC         207 :         case OCLASS_CONSTRAINT:
    4909 ECB             :             {
    4910                 :                 HeapTuple   conTup;
    4911                 :                 Form_pg_constraint con;
    4912                 : 
    4913 CBC         207 :                 conTup = SearchSysCache1(CONSTROID,
    4914 GIC         207 :                                          ObjectIdGetDatum(object->objectId));
    4915             207 :                 if (!HeapTupleIsValid(conTup))
    4916                 :                 {
    4917               6 :                     if (!missing_ok)
    4918 UIC           0 :                         elog(ERROR, "cache lookup failed for constraint %u",
    4919 ECB             :                              object->objectId);
    4920 CBC           6 :                     break;
    4921 ECB             :                 }
    4922 CBC         201 :                 con = (Form_pg_constraint) GETSTRUCT(conTup);
    4923                 : 
    4924             201 :                 if (OidIsValid(con->conrelid))
    4925 ECB             :                 {
    4926 GIC         180 :                     appendStringInfo(&buffer, "%s on ",
    4927             180 :                                      quote_identifier(NameStr(con->conname)));
    4928             180 :                     getRelationIdentity(&buffer, con->conrelid, objname,
    4929 ECB             :                                         false);
    4930 CBC         180 :                     if (objname)
    4931 GIC         162 :                         *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
    4932                 :                 }
    4933 ECB             :                 else
    4934                 :                 {
    4935                 :                     ObjectAddress domain;
    4936                 : 
    4937 CBC          21 :                     Assert(OidIsValid(con->contypid));
    4938 GIC          21 :                     domain.classId = TypeRelationId;
    4939              21 :                     domain.objectId = con->contypid;
    4940              21 :                     domain.objectSubId = 0;
    4941                 : 
    4942              42 :                     appendStringInfo(&buffer, "%s on %s",
    4943 CBC          21 :                                      quote_identifier(NameStr(con->conname)),
    4944 ECB             :                                      getObjectIdentityParts(&domain, objname,
    4945                 :                                                             objargs, false));
    4946                 : 
    4947 CBC          21 :                     if (objname)
    4948 GBC           3 :                         *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
    4949                 :                 }
    4950 ECB             : 
    4951 GIC         201 :                 ReleaseSysCache(conTup);
    4952 CBC         201 :                 break;
    4953 ECB             :             }
    4954                 : 
    4955 CBC          28 :         case OCLASS_CONVERSION:
    4956 ECB             :             {
    4957                 :                 HeapTuple   conTup;
    4958                 :                 Form_pg_conversion conForm;
    4959                 :                 char       *schema;
    4960                 : 
    4961 CBC          28 :                 conTup = SearchSysCache1(CONVOID,
    4962 GIC          28 :                                          ObjectIdGetDatum(object->objectId));
    4963              28 :                 if (!HeapTupleIsValid(conTup))
    4964 ECB             :                 {
    4965 GIC           6 :                     if (!missing_ok)
    4966 UIC           0 :                         elog(ERROR, "cache lookup failed for conversion %u",
    4967                 :                              object->objectId);
    4968 CBC           6 :                     break;
    4969                 :                 }
    4970              22 :                 conForm = (Form_pg_conversion) GETSTRUCT(conTup);
    4971 GIC          22 :                 schema = get_namespace_name_or_temp(conForm->connamespace);
    4972 CBC          22 :                 appendStringInfoString(&buffer,
    4973 GBC          22 :                                        quote_qualified_identifier(schema,
    4974 GIC          22 :                                                                   NameStr(conForm->conname)));
    4975 CBC          22 :                 if (objname)
    4976 GIC           3 :                     *objname = list_make2(schema,
    4977                 :                                           pstrdup(NameStr(conForm->conname)));
    4978 CBC          22 :                 ReleaseSysCache(conTup);
    4979 GIC          22 :                 break;
    4980                 :             }
    4981                 : 
    4982 CBC         199 :         case OCLASS_DEFAULT:
    4983                 :             {
    4984                 :                 ObjectAddress colobject;
    4985 ECB             : 
    4986 GIC         199 :                 colobject = GetAttrDefaultColumnAddress(object->objectId);
    4987                 : 
    4988             199 :                 if (!OidIsValid(colobject.objectId))
    4989                 :                 {
    4990 CBC           6 :                     if (!missing_ok)
    4991 LBC           0 :                         elog(ERROR, "could not find tuple for attrdef %u",
    4992 ECB             :                              object->objectId);
    4993 GIC           6 :                     break;
    4994 ECB             :                 }
    4995 EUB             : 
    4996 GIC         193 :                 appendStringInfo(&buffer, "for %s",
    4997 ECB             :                                  getObjectIdentityParts(&colobject,
    4998                 :                                                         objname, objargs,
    4999                 :                                                         false));
    5000 CBC         193 :                 break;
    5001 ECB             :             }
    5002                 : 
    5003 CBC          27 :         case OCLASS_LANGUAGE:
    5004 ECB             :             {
    5005                 :                 HeapTuple   langTup;
    5006                 :                 Form_pg_language langForm;
    5007                 : 
    5008 CBC          27 :                 langTup = SearchSysCache1(LANGOID,
    5009              27 :                                           ObjectIdGetDatum(object->objectId));
    5010 GBC          27 :                 if (!HeapTupleIsValid(langTup))
    5011 EUB             :                 {
    5012 GBC           6 :                     if (!missing_ok)
    5013 UBC           0 :                         elog(ERROR, "cache lookup failed for language %u",
    5014 EUB             :                              object->objectId);
    5015 GIC           6 :                     break;
    5016 ECB             :                 }
    5017 GIC          21 :                 langForm = (Form_pg_language) GETSTRUCT(langTup);
    5018 CBC          21 :                 appendStringInfoString(&buffer,
    5019              21 :                                        quote_identifier(NameStr(langForm->lanname)));
    5020 GIC          21 :                 if (objname)
    5021               3 :                     *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
    5022 CBC          21 :                 ReleaseSysCache(langTup);
    5023              21 :                 break;
    5024                 :             }
    5025               6 :         case OCLASS_LARGEOBJECT:
    5026               6 :             if (!LargeObjectExists(object->objectId))
    5027               6 :                 break;
    5028 LBC           0 :             appendStringInfo(&buffer, "%u",
    5029 UIC           0 :                              object->objectId);
    5030               0 :             if (objname)
    5031 LBC           0 :                 *objname = list_make1(psprintf("%u", object->objectId));
    5032 UIC           0 :             break;
    5033                 : 
    5034 GIC          29 :         case OCLASS_OPERATOR:
    5035                 :             {
    5036              29 :                 bits16      flags = FORMAT_OPERATOR_FORCE_QUALIFY | FORMAT_OPERATOR_INVALID_AS_NULL;
    5037              29 :                 char       *oprname = format_operator_extended(object->objectId,
    5038                 :                                                                flags);
    5039 ECB             : 
    5040 CBC          29 :                 if (oprname == NULL)
    5041               6 :                     break;
    5042                 : 
    5043              23 :                 appendStringInfoString(&buffer, oprname);
    5044 GBC          23 :                 if (objname)
    5045 GIC           3 :                     format_operator_parts(object->objectId, objname, objargs, missing_ok);
    5046 CBC          23 :                 break;
    5047                 :             }
    5048 ECB             : 
    5049 CBC          31 :         case OCLASS_OPCLASS:
    5050                 :             {
    5051 ECB             :                 HeapTuple   opcTup;
    5052                 :                 Form_pg_opclass opcForm;
    5053                 :                 HeapTuple   amTup;
    5054 EUB             :                 Form_pg_am  amForm;
    5055                 :                 char       *schema;
    5056 ECB             : 
    5057 GIC          31 :                 opcTup = SearchSysCache1(CLAOID,
    5058 CBC          31 :                                          ObjectIdGetDatum(object->objectId));
    5059 GIC          31 :                 if (!HeapTupleIsValid(opcTup))
    5060 ECB             :                 {
    5061 CBC           6 :                     if (!missing_ok)
    5062 LBC           0 :                         elog(ERROR, "cache lookup failed for opclass %u",
    5063 ECB             :                              object->objectId);
    5064 GIC           6 :                     break;
    5065                 :                 }
    5066              25 :                 opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
    5067 CBC          25 :                 schema = get_namespace_name_or_temp(opcForm->opcnamespace);
    5068 ECB             : 
    5069 CBC          25 :                 amTup = SearchSysCache1(AMOID,
    5070                 :                                         ObjectIdGetDatum(opcForm->opcmethod));
    5071 GIC          25 :                 if (!HeapTupleIsValid(amTup))
    5072 LBC           0 :                     elog(ERROR, "cache lookup failed for access method %u",
    5073 ECB             :                          opcForm->opcmethod);
    5074 GIC          25 :                 amForm = (Form_pg_am) GETSTRUCT(amTup);
    5075 ECB             : 
    5076 GIC          25 :                 appendStringInfo(&buffer, "%s USING %s",
    5077 ECB             :                                  quote_qualified_identifier(schema,
    5078 GIC          25 :                                                             NameStr(opcForm->opcname)),
    5079              25 :                                  quote_identifier(NameStr(amForm->amname)));
    5080              25 :                 if (objname)
    5081 CBC           3 :                     *objname = list_make3(pstrdup(NameStr(amForm->amname)),
    5082 ECB             :                                           schema,
    5083                 :                                           pstrdup(NameStr(opcForm->opcname)));
    5084                 : 
    5085 GBC          25 :                 ReleaseSysCache(amTup);
    5086 GIC          25 :                 ReleaseSysCache(opcTup);
    5087 CBC          25 :                 break;
    5088                 :             }
    5089 ECB             : 
    5090 CBC          32 :         case OCLASS_OPFAMILY:
    5091              32 :             getOpFamilyIdentity(&buffer, object->objectId, objname,
    5092                 :                                 missing_ok);
    5093              32 :             break;
    5094                 : 
    5095              27 :         case OCLASS_AM:
    5096                 :             {
    5097                 :                 char       *amname;
    5098                 : 
    5099 GIC          27 :                 amname = get_am_name(object->objectId);
    5100              27 :                 if (!amname)
    5101                 :                 {
    5102               6 :                     if (!missing_ok)
    5103 UIC           0 :                         elog(ERROR, "cache lookup failed for access method %u",
    5104                 :                              object->objectId);
    5105 GIC           6 :                     break;
    5106 ECB             :                 }
    5107 GIC          21 :                 appendStringInfoString(&buffer, quote_identifier(amname));
    5108              21 :                 if (objname)
    5109 CBC           3 :                     *objname = list_make1(amname);
    5110                 :             }
    5111 GIC          21 :             break;
    5112 ECB             : 
    5113 GIC          27 :         case OCLASS_AMOP:
    5114 ECB             :             {
    5115                 :                 Relation    amopDesc;
    5116                 :                 HeapTuple   tup;
    5117                 :                 ScanKeyData skey[1];
    5118                 :                 SysScanDesc amscan;
    5119                 :                 Form_pg_amop amopForm;
    5120                 :                 StringInfoData opfam;
    5121                 :                 char       *ltype;
    5122 EUB             :                 char       *rtype;
    5123                 : 
    5124 GIC          27 :                 amopDesc = table_open(AccessMethodOperatorRelationId,
    5125 ECB             :                                       AccessShareLock);
    5126                 : 
    5127 CBC          27 :                 ScanKeyInit(&skey[0],
    5128                 :                             Anum_pg_amop_oid,
    5129                 :                             BTEqualStrategyNumber, F_OIDEQ,
    5130              27 :                             ObjectIdGetDatum(object->objectId));
    5131                 : 
    5132              27 :                 amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
    5133 ECB             :                                             NULL, 1, skey);
    5134                 : 
    5135 GIC          27 :                 tup = systable_getnext(amscan);
    5136 ECB             : 
    5137 CBC          27 :                 if (!HeapTupleIsValid(tup))
    5138                 :                 {
    5139               6 :                     if (!missing_ok)
    5140 UIC           0 :                         elog(ERROR, "could not find tuple for amop entry %u",
    5141 ECB             :                              object->objectId);
    5142                 : 
    5143 CBC           6 :                     systable_endscan(amscan);
    5144 GIC           6 :                     table_close(amopDesc, AccessShareLock);
    5145               6 :                     break;
    5146 ECB             :                 }
    5147                 : 
    5148 GIC          21 :                 amopForm = (Form_pg_amop) GETSTRUCT(tup);
    5149                 : 
    5150 CBC          21 :                 initStringInfo(&opfam);
    5151 GIC          21 :                 getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
    5152 ECB             :                                     false);
    5153                 : 
    5154 CBC          21 :                 ltype = format_type_be_qualified(amopForm->amoplefttype);
    5155 GIC          21 :                 rtype = format_type_be_qualified(amopForm->amoprighttype);
    5156                 : 
    5157 CBC          21 :                 if (objname)
    5158                 :                 {
    5159 GIC           3 :                     *objname = lappend(*objname,
    5160               3 :                                        psprintf("%d", amopForm->amopstrategy));
    5161               3 :                     *objargs = list_make2(ltype, rtype);
    5162                 :                 }
    5163                 : 
    5164              21 :                 appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
    5165              21 :                                  amopForm->amopstrategy,
    5166                 :                                  ltype, rtype, opfam.data);
    5167                 : 
    5168 CBC          21 :                 pfree(opfam.data);
    5169                 : 
    5170 GIC          21 :                 systable_endscan(amscan);
    5171 CBC          21 :                 table_close(amopDesc, AccessShareLock);
    5172 GIC          21 :                 break;
    5173                 :             }
    5174 ECB             : 
    5175 GIC          27 :         case OCLASS_AMPROC:
    5176 ECB             :             {
    5177                 :                 Relation    amprocDesc;
    5178                 :                 ScanKeyData skey[1];
    5179                 :                 SysScanDesc amscan;
    5180                 :                 HeapTuple   tup;
    5181                 :                 Form_pg_amproc amprocForm;
    5182                 :                 StringInfoData opfam;
    5183                 :                 char       *ltype;
    5184 EUB             :                 char       *rtype;
    5185                 : 
    5186 GIC          27 :                 amprocDesc = table_open(AccessMethodProcedureRelationId,
    5187 ECB             :                                         AccessShareLock);
    5188                 : 
    5189 CBC          27 :                 ScanKeyInit(&skey[0],
    5190                 :                             Anum_pg_amproc_oid,
    5191                 :                             BTEqualStrategyNumber, F_OIDEQ,
    5192              27 :                             ObjectIdGetDatum(object->objectId));
    5193                 : 
    5194              27 :                 amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
    5195 ECB             :                                             NULL, 1, skey);
    5196                 : 
    5197 GIC          27 :                 tup = systable_getnext(amscan);
    5198 ECB             : 
    5199 CBC          27 :                 if (!HeapTupleIsValid(tup))
    5200                 :                 {
    5201               6 :                     if (!missing_ok)
    5202 UIC           0 :                         elog(ERROR, "could not find tuple for amproc entry %u",
    5203 ECB             :                              object->objectId);
    5204                 : 
    5205 CBC           6 :                     systable_endscan(amscan);
    5206 GIC           6 :                     table_close(amprocDesc, AccessShareLock);
    5207               6 :                     break;
    5208 ECB             :                 }
    5209                 : 
    5210 GIC          21 :                 amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
    5211                 : 
    5212 CBC          21 :                 initStringInfo(&opfam);
    5213 GIC          21 :                 getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
    5214 ECB             :                                     false);
    5215                 : 
    5216 CBC          21 :                 ltype = format_type_be_qualified(amprocForm->amproclefttype);
    5217 GIC          21 :                 rtype = format_type_be_qualified(amprocForm->amprocrighttype);
    5218                 : 
    5219 CBC          21 :                 if (objname)
    5220                 :                 {
    5221 GIC           3 :                     *objname = lappend(*objname,
    5222               3 :                                        psprintf("%d", amprocForm->amprocnum));
    5223               3 :                     *objargs = list_make2(ltype, rtype);
    5224                 :                 }
    5225 ECB             : 
    5226 GIC          21 :                 appendStringInfo(&buffer, "function %d (%s, %s) of %s",
    5227 CBC          21 :                                  amprocForm->amprocnum,
    5228 ECB             :                                  ltype, rtype, opfam.data);
    5229                 : 
    5230 CBC          21 :                 pfree(opfam.data);
    5231                 : 
    5232              21 :                 systable_endscan(amscan);
    5233 GBC          21 :                 table_close(amprocDesc, AccessShareLock);
    5234 GIC          21 :                 break;
    5235                 :             }
    5236 ECB             : 
    5237 CBC          38 :         case OCLASS_REWRITE:
    5238                 :             {
    5239                 :                 Relation    ruleDesc;
    5240 ECB             :                 HeapTuple   tup;
    5241                 :                 Form_pg_rewrite rule;
    5242                 : 
    5243 CBC          38 :                 ruleDesc = table_open(RewriteRelationId, AccessShareLock);
    5244 ECB             : 
    5245 CBC          38 :                 tup = get_catalog_object_by_oid(ruleDesc, Anum_pg_rewrite_oid,
    5246              38 :                                                 object->objectId);
    5247                 : 
    5248              38 :                 if (!HeapTupleIsValid(tup))
    5249 ECB             :                 {
    5250 GIC           6 :                     if (!missing_ok)
    5251 UIC           0 :                         elog(ERROR, "could not find tuple for rule %u",
    5252 ECB             :                              object->objectId);
    5253                 : 
    5254 GIC           6 :                     table_close(ruleDesc, AccessShareLock);
    5255               6 :                     break;
    5256                 :                 }
    5257                 : 
    5258 CBC          32 :                 rule = (Form_pg_rewrite) GETSTRUCT(tup);
    5259                 : 
    5260              32 :                 appendStringInfo(&buffer, "%s on ",
    5261              32 :                                  quote_identifier(NameStr(rule->rulename)));
    5262 GIC          32 :                 getRelationIdentity(&buffer, rule->ev_class, objname, false);
    5263 CBC          32 :                 if (objname)
    5264 GIC           9 :                     *objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
    5265 ECB             : 
    5266 GBC          32 :                 table_close(ruleDesc, AccessShareLock);
    5267 GIC          32 :                 break;
    5268                 :             }
    5269 ECB             : 
    5270 CBC          78 :         case OCLASS_TRIGGER:
    5271                 :             {
    5272                 :                 Relation    trigDesc;
    5273 ECB             :                 HeapTuple   tup;
    5274                 :                 Form_pg_trigger trig;
    5275                 : 
    5276 CBC          78 :                 trigDesc = table_open(TriggerRelationId, AccessShareLock);
    5277 ECB             : 
    5278 CBC          78 :                 tup = get_catalog_object_by_oid(trigDesc, Anum_pg_trigger_oid,
    5279              78 :                                                 object->objectId);
    5280                 : 
    5281              78 :                 if (!HeapTupleIsValid(tup))
    5282 ECB             :                 {
    5283 GIC           6 :                     if (!missing_ok)
    5284 UIC           0 :                         elog(ERROR, "could not find tuple for trigger %u",
    5285 ECB             :                              object->objectId);
    5286                 : 
    5287 GIC           6 :                     table_close(trigDesc, AccessShareLock);
    5288               6 :                     break;
    5289 ECB             :                 }
    5290                 : 
    5291 GIC          72 :                 trig = (Form_pg_trigger) GETSTRUCT(tup);
    5292 ECB             : 
    5293 GBC          72 :                 appendStringInfo(&buffer, "%s on ",
    5294 GIC          72 :                                  quote_identifier(NameStr(trig->tgname)));
    5295 CBC          72 :                 getRelationIdentity(&buffer, trig->tgrelid, objname, false);
    5296 GIC          72 :                 if (objname)
    5297 CBC          51 :                     *objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
    5298                 : 
    5299              72 :                 table_close(trigDesc, AccessShareLock);
    5300              72 :                 break;
    5301 ECB             :             }
    5302                 : 
    5303 GIC          59 :         case OCLASS_SCHEMA:
    5304 ECB             :             {
    5305                 :                 char       *nspname;
    5306                 : 
    5307 GIC          59 :                 nspname = get_namespace_name_or_temp(object->objectId);
    5308              59 :                 if (!nspname)
    5309                 :                 {
    5310 CBC           6 :                     if (!missing_ok)
    5311 LBC           0 :                         elog(ERROR, "cache lookup failed for namespace %u",
    5312 ECB             :                              object->objectId);
    5313 GIC           6 :                     break;
    5314 ECB             :                 }
    5315 GBC          53 :                 appendStringInfoString(&buffer,
    5316                 :                                        quote_identifier(nspname));
    5317 CBC          53 :                 if (objname)
    5318 GIC          27 :                     *objname = list_make1(nspname);
    5319 CBC          53 :                 break;
    5320 ECB             :             }
    5321                 : 
    5322 CBC          28 :         case OCLASS_STATISTIC_EXT:
    5323 ECB             :             {
    5324                 :                 HeapTuple   tup;
    5325                 :                 Form_pg_statistic_ext formStatistic;
    5326                 :                 char       *schema;
    5327                 : 
    5328 GIC          28 :                 tup = SearchSysCache1(STATEXTOID,
    5329 CBC          28 :                                       ObjectIdGetDatum(object->objectId));
    5330 GIC          28 :                 if (!HeapTupleIsValid(tup))
    5331 ECB             :                 {
    5332 GIC           6 :                     if (!missing_ok)
    5333 UIC           0 :                         elog(ERROR, "cache lookup failed for statistics object %u",
    5334                 :                              object->objectId);
    5335 GIC           6 :                     break;
    5336                 :                 }
    5337 CBC          22 :                 formStatistic = (Form_pg_statistic_ext) GETSTRUCT(tup);
    5338              22 :                 schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
    5339              22 :                 appendStringInfoString(&buffer,
    5340 GIC          22 :                                        quote_qualified_identifier(schema,
    5341 CBC          22 :                                                                   NameStr(formStatistic->stxname)));
    5342 GBC          22 :                 if (objname)
    5343 GIC           3 :                     *objname = list_make2(schema,
    5344 ECB             :                                           pstrdup(NameStr(formStatistic->stxname)));
    5345 GIC          22 :                 ReleaseSysCache(tup);
    5346 ECB             :             }
    5347 CBC          22 :             break;
    5348 ECB             : 
    5349 CBC          27 :         case OCLASS_TSPARSER:
    5350 ECB             :             {
    5351                 :                 HeapTuple   tup;
    5352                 :                 Form_pg_ts_parser formParser;
    5353                 :                 char       *schema;
    5354                 : 
    5355 CBC          27 :                 tup = SearchSysCache1(TSPARSEROID,
    5356 GIC          27 :                                       ObjectIdGetDatum(object->objectId));
    5357              27 :                 if (!HeapTupleIsValid(tup))
    5358 ECB             :                 {
    5359 GIC           6 :                     if (!missing_ok)
    5360 UIC           0 :                         elog(ERROR, "cache lookup failed for text search parser %u",
    5361                 :                              object->objectId);
    5362 GIC           6 :                     break;
    5363                 :                 }
    5364 CBC          21 :                 formParser = (Form_pg_ts_parser) GETSTRUCT(tup);
    5365              21 :                 schema = get_namespace_name_or_temp(formParser->prsnamespace);
    5366              21 :                 appendStringInfoString(&buffer,
    5367 GIC          21 :                                        quote_qualified_identifier(schema,
    5368 CBC          21 :                                                                   NameStr(formParser->prsname)));
    5369 GBC          21 :                 if (objname)
    5370 GIC           3 :                     *objname = list_make2(schema,
    5371 ECB             :                                           pstrdup(NameStr(formParser->prsname)));
    5372 GIC          21 :                 ReleaseSysCache(tup);
    5373 CBC          21 :                 break;
    5374 ECB             :             }
    5375                 : 
    5376 CBC          27 :         case OCLASS_TSDICT:
    5377 ECB             :             {
    5378                 :                 HeapTuple   tup;
    5379                 :                 Form_pg_ts_dict formDict;
    5380                 :                 char       *schema;
    5381                 : 
    5382 CBC          27 :                 tup = SearchSysCache1(TSDICTOID,
    5383 GIC          27 :                                       ObjectIdGetDatum(object->objectId));
    5384              27 :                 if (!HeapTupleIsValid(tup))
    5385 ECB             :                 {
    5386 GIC           6 :                     if (!missing_ok)
    5387 UIC           0 :                         elog(ERROR, "cache lookup failed for text search dictionary %u",
    5388                 :                              object->objectId);
    5389 GIC           6 :                     break;
    5390                 :                 }
    5391 CBC          21 :                 formDict = (Form_pg_ts_dict) GETSTRUCT(tup);
    5392              21 :                 schema = get_namespace_name_or_temp(formDict->dictnamespace);
    5393              21 :                 appendStringInfoString(&buffer,
    5394 GIC          21 :                                        quote_qualified_identifier(schema,
    5395 CBC          21 :                                                                   NameStr(formDict->dictname)));
    5396 GBC          21 :                 if (objname)
    5397 GIC           3 :                     *objname = list_make2(schema,
    5398 ECB             :                                           pstrdup(NameStr(formDict->dictname)));
    5399 GIC          21 :                 ReleaseSysCache(tup);
    5400 CBC          21 :                 break;
    5401 ECB             :             }
    5402                 : 
    5403 CBC          27 :         case OCLASS_TSTEMPLATE:
    5404 ECB             :             {
    5405                 :                 HeapTuple   tup;
    5406                 :                 Form_pg_ts_template formTmpl;
    5407                 :                 char       *schema;
    5408                 : 
    5409 CBC          27 :                 tup = SearchSysCache1(TSTEMPLATEOID,
    5410 GIC          27 :                                       ObjectIdGetDatum(object->objectId));
    5411              27 :                 if (!HeapTupleIsValid(tup))
    5412 ECB             :                 {
    5413 GIC           6 :                     if (!missing_ok)
    5414 UIC           0 :                         elog(ERROR, "cache lookup failed for text search template %u",
    5415                 :                              object->objectId);
    5416 GIC           6 :                     break;
    5417                 :                 }
    5418 CBC          21 :                 formTmpl = (Form_pg_ts_template) GETSTRUCT(tup);
    5419              21 :                 schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
    5420              21 :                 appendStringInfoString(&buffer,
    5421 GIC          21 :                                        quote_qualified_identifier(schema,
    5422 CBC          21 :                                                                   NameStr(formTmpl->tmplname)));
    5423 GBC          21 :                 if (objname)
    5424 GIC           3 :                     *objname = list_make2(schema,
    5425 ECB             :                                           pstrdup(NameStr(formTmpl->tmplname)));
    5426 GIC          21 :                 ReleaseSysCache(tup);
    5427 CBC          21 :                 break;
    5428 ECB             :             }
    5429                 : 
    5430 CBC          29 :         case OCLASS_TSCONFIG:
    5431 ECB             :             {
    5432                 :                 HeapTuple   tup;
    5433                 :                 Form_pg_ts_config formCfg;
    5434                 :                 char       *schema;
    5435                 : 
    5436 CBC          29 :                 tup = SearchSysCache1(TSCONFIGOID,
    5437 GIC          29 :                                       ObjectIdGetDatum(object->objectId));
    5438              29 :                 if (!HeapTupleIsValid(tup))
    5439 ECB             :                 {
    5440 GIC           6 :                     if (!missing_ok)
    5441 UIC           0 :                         elog(ERROR, "cache lookup failed for text search configuration %u",
    5442                 :                              object->objectId);
    5443 CBC           6 :                     break;
    5444 ECB             :                 }
    5445 CBC          23 :                 formCfg = (Form_pg_ts_config) GETSTRUCT(tup);
    5446              23 :                 schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
    5447              23 :                 appendStringInfoString(&buffer,
    5448              23 :                                        quote_qualified_identifier(schema,
    5449 GIC          23 :                                                                   NameStr(formCfg->cfgname)));
    5450 CBC          23 :                 if (objname)
    5451 GIC           3 :                     *objname = list_make2(schema,
    5452                 :                                           pstrdup(NameStr(formCfg->cfgname)));
    5453 CBC          23 :                 ReleaseSysCache(tup);
    5454 GIC          23 :                 break;
    5455                 :             }
    5456                 : 
    5457              27 :         case OCLASS_ROLE:
    5458                 :             {
    5459                 :                 char       *username;
    5460                 : 
    5461 CBC          27 :                 username = GetUserNameFromId(object->objectId, missing_ok);
    5462 GIC          27 :                 if (!username)
    5463               6 :                     break;
    5464 CBC          21 :                 if (objname)
    5465 GIC           3 :                     *objname = list_make1(username);
    5466              21 :                 appendStringInfoString(&buffer,
    5467 ECB             :                                        quote_identifier(username));
    5468 GIC          21 :                 break;
    5469 ECB             :             }
    5470                 : 
    5471 GNC           6 :         case OCLASS_ROLE_MEMBERSHIP:
    5472                 :             {
    5473                 :                 Relation    authMemDesc;
    5474                 :                 ScanKeyData skey[1];
    5475                 :                 SysScanDesc amscan;
    5476                 :                 HeapTuple   tup;
    5477                 :                 Form_pg_auth_members amForm;
    5478                 : 
    5479               6 :                 authMemDesc = table_open(AuthMemRelationId,
    5480                 :                                          AccessShareLock);
    5481                 : 
    5482               6 :                 ScanKeyInit(&skey[0],
    5483                 :                             Anum_pg_auth_members_oid,
    5484                 :                             BTEqualStrategyNumber, F_OIDEQ,
    5485               6 :                             ObjectIdGetDatum(object->objectId));
    5486                 : 
    5487               6 :                 amscan = systable_beginscan(authMemDesc, AuthMemOidIndexId, true,
    5488                 :                                             NULL, 1, skey);
    5489                 : 
    5490               6 :                 tup = systable_getnext(amscan);
    5491                 : 
    5492               6 :                 if (!HeapTupleIsValid(tup))
    5493                 :                 {
    5494               6 :                     if (!missing_ok)
    5495 UNC           0 :                         elog(ERROR, "could not find tuple for pg_auth_members entry %u",
    5496                 :                              object->objectId);
    5497                 : 
    5498 GNC           6 :                     systable_endscan(amscan);
    5499               6 :                     table_close(authMemDesc, AccessShareLock);
    5500               6 :                     break;
    5501                 :                 }
    5502                 : 
    5503 UNC           0 :                 amForm = (Form_pg_auth_members) GETSTRUCT(tup);
    5504                 : 
    5505               0 :                 appendStringInfo(&buffer, _("membership of role %s in role %s"),
    5506                 :                                  GetUserNameFromId(amForm->member, false),
    5507                 :                                  GetUserNameFromId(amForm->roleid, false));
    5508                 : 
    5509               0 :                 systable_endscan(amscan);
    5510               0 :                 table_close(authMemDesc, AccessShareLock);
    5511               0 :                 break;
    5512                 :             }
    5513                 : 
    5514 GIC           6 :         case OCLASS_DATABASE:
    5515 ECB             :             {
    5516                 :                 char       *datname;
    5517                 : 
    5518 GIC           6 :                 datname = get_database_name(object->objectId);
    5519 CBC           6 :                 if (!datname)
    5520 EUB             :                 {
    5521 GIC           6 :                     if (!missing_ok)
    5522 UIC           0 :                         elog(ERROR, "cache lookup failed for database %u",
    5523 ECB             :                              object->objectId);
    5524 CBC           6 :                     break;
    5525 ECB             :                 }
    5526 UIC           0 :                 if (objname)
    5527               0 :                     *objname = list_make1(datname);
    5528 UBC           0 :                 appendStringInfoString(&buffer,
    5529                 :                                        quote_identifier(datname));
    5530               0 :                 break;
    5531                 :             }
    5532                 : 
    5533 GIC           6 :         case OCLASS_TBLSPACE:
    5534 EUB             :             {
    5535                 :                 char       *tblspace;
    5536                 : 
    5537 GIC           6 :                 tblspace = get_tablespace_name(object->objectId);
    5538               6 :                 if (!tblspace)
    5539 ECB             :                 {
    5540 GIC           6 :                     if (!missing_ok)
    5541 UIC           0 :                         elog(ERROR, "cache lookup failed for tablespace %u",
    5542                 :                              object->objectId);
    5543 CBC           6 :                     break;
    5544 ECB             :                 }
    5545 UIC           0 :                 if (objname)
    5546 LBC           0 :                     *objname = list_make1(tblspace);
    5547 UBC           0 :                 appendStringInfoString(&buffer,
    5548                 :                                        quote_identifier(tblspace));
    5549 LBC           0 :                 break;
    5550                 :             }
    5551 EUB             : 
    5552 GBC          30 :         case OCLASS_FDW:
    5553 EUB             :             {
    5554                 :                 ForeignDataWrapper *fdw;
    5555                 : 
    5556 GIC          30 :                 fdw = GetForeignDataWrapperExtended(object->objectId,
    5557                 :                                                     missing_ok);
    5558 CBC          30 :                 if (fdw)
    5559                 :                 {
    5560 GIC          24 :                     appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
    5561              24 :                     if (objname)
    5562 CBC           6 :                         *objname = list_make1(pstrdup(fdw->fdwname));
    5563 ECB             :                 }
    5564 GIC          30 :                 break;
    5565 ECB             :             }
    5566 EUB             : 
    5567 GIC          30 :         case OCLASS_FOREIGN_SERVER:
    5568 ECB             :             {
    5569                 :                 ForeignServer *srv;
    5570 EUB             : 
    5571 GBC          30 :                 srv = GetForeignServerExtended(object->objectId,
    5572 EUB             :                                                missing_ok);
    5573 GIC          30 :                 if (srv)
    5574 EUB             :                 {
    5575 GIC          24 :                     appendStringInfoString(&buffer,
    5576              24 :                                            quote_identifier(srv->servername));
    5577 CBC          24 :                     if (objname)
    5578 GIC           6 :                         *objname = list_make1(pstrdup(srv->servername));
    5579                 :                 }
    5580              30 :                 break;
    5581 ECB             :             }
    5582                 : 
    5583 CBC          30 :         case OCLASS_USER_MAPPING:
    5584                 :             {
    5585 ECB             :                 HeapTuple   tup;
    5586                 :                 Oid         useid;
    5587                 :                 Form_pg_user_mapping umform;
    5588                 :                 ForeignServer *srv;
    5589                 :                 const char *usename;
    5590                 : 
    5591 GIC          30 :                 tup = SearchSysCache1(USERMAPPINGOID,
    5592 CBC          30 :                                       ObjectIdGetDatum(object->objectId));
    5593 GIC          30 :                 if (!HeapTupleIsValid(tup))
    5594                 :                 {
    5595               6 :                     if (!missing_ok)
    5596 LBC           0 :                         elog(ERROR, "cache lookup failed for user mapping %u",
    5597                 :                              object->objectId);
    5598 CBC           6 :                     break;
    5599                 :                 }
    5600              24 :                 umform = (Form_pg_user_mapping) GETSTRUCT(tup);
    5601              24 :                 useid = umform->umuser;
    5602              24 :                 srv = GetForeignServer(umform->umserver);
    5603 ECB             : 
    5604 GIC          24 :                 ReleaseSysCache(tup);
    5605 ECB             : 
    5606 GIC          24 :                 if (OidIsValid(useid))
    5607              24 :                     usename = GetUserNameFromId(useid, false);
    5608 ECB             :                 else
    5609 UIC           0 :                     usename = "public";
    5610                 : 
    5611 GIC          24 :                 if (objname)
    5612                 :                 {
    5613               6 :                     *objname = list_make1(pstrdup(usename));
    5614               6 :                     *objargs = list_make1(pstrdup(srv->servername));
    5615                 :                 }
    5616 ECB             : 
    5617 CBC          24 :                 appendStringInfo(&buffer, "%s on server %s",
    5618 ECB             :                                  quote_identifier(usename),
    5619                 :                                  srv->servername);
    5620 CBC          24 :                 break;
    5621 EUB             :             }
    5622                 : 
    5623 CBC          51 :         case OCLASS_DEFACL:
    5624                 :             {
    5625 ECB             :                 Relation    defaclrel;
    5626                 :                 ScanKeyData skey[1];
    5627                 :                 SysScanDesc rcscan;
    5628                 :                 HeapTuple   tup;
    5629                 :                 Form_pg_default_acl defacl;
    5630                 :                 char       *schema;
    5631                 :                 char       *username;
    5632                 : 
    5633 GIC          51 :                 defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
    5634 EUB             : 
    5635 GIC          51 :                 ScanKeyInit(&skey[0],
    5636 ECB             :                             Anum_pg_default_acl_oid,
    5637                 :                             BTEqualStrategyNumber, F_OIDEQ,
    5638 CBC          51 :                             ObjectIdGetDatum(object->objectId));
    5639 ECB             : 
    5640 GIC          51 :                 rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
    5641                 :                                             true, NULL, 1, skey);
    5642 ECB             : 
    5643 GIC          51 :                 tup = systable_getnext(rcscan);
    5644                 : 
    5645 CBC          51 :                 if (!HeapTupleIsValid(tup))
    5646                 :                 {
    5647 GIC           6 :                     if (!missing_ok)
    5648 LBC           0 :                         elog(ERROR, "could not find tuple for default ACL %u",
    5649                 :                              object->objectId);
    5650                 : 
    5651 GIC           6 :                     systable_endscan(rcscan);
    5652               6 :                     table_close(defaclrel, AccessShareLock);
    5653               6 :                     break;
    5654                 :                 }
    5655                 : 
    5656              45 :                 defacl = (Form_pg_default_acl) GETSTRUCT(tup);
    5657                 : 
    5658 CBC          45 :                 username = GetUserNameFromId(defacl->defaclrole, false);
    5659 GIC          45 :                 appendStringInfo(&buffer,
    5660 ECB             :                                  "for role %s",
    5661                 :                                  quote_identifier(username));
    5662                 : 
    5663 CBC          45 :                 if (OidIsValid(defacl->defaclnamespace))
    5664                 :                 {
    5665              21 :                     schema = get_namespace_name_or_temp(defacl->defaclnamespace);
    5666 GIC          21 :                     appendStringInfo(&buffer,
    5667                 :                                      " in schema %s",
    5668 ECB             :                                      quote_identifier(schema));
    5669                 :                 }
    5670                 :                 else
    5671 GIC          24 :                     schema = NULL;
    5672 ECB             : 
    5673 GBC          45 :                 switch (defacl->defaclobjtype)
    5674                 :                 {
    5675 GIC          45 :                     case DEFACLOBJ_RELATION:
    5676 CBC          45 :                         appendStringInfoString(&buffer,
    5677 ECB             :                                                " on tables");
    5678 CBC          45 :                         break;
    5679 UIC           0 :                     case DEFACLOBJ_SEQUENCE:
    5680               0 :                         appendStringInfoString(&buffer,
    5681 ECB             :                                                " on sequences");
    5682 UIC           0 :                         break;
    5683 LBC           0 :                     case DEFACLOBJ_FUNCTION:
    5684               0 :                         appendStringInfoString(&buffer,
    5685                 :                                                " on functions");
    5686 UIC           0 :                         break;
    5687               0 :                     case DEFACLOBJ_TYPE:
    5688 LBC           0 :                         appendStringInfoString(&buffer,
    5689                 :                                                " on types");
    5690               0 :                         break;
    5691               0 :                     case DEFACLOBJ_NAMESPACE:
    5692 UIC           0 :                         appendStringInfoString(&buffer,
    5693                 :                                                " on schemas");
    5694               0 :                         break;
    5695                 :                 }
    5696 ECB             : 
    5697 GIC          45 :                 if (objname)
    5698 ECB             :                 {
    5699 GIC           9 :                     *objname = list_make1(username);
    5700 CBC           9 :                     if (schema)
    5701               3 :                         *objname = lappend(*objname, schema);
    5702 GIC           9 :                     *objargs = list_make1(psprintf("%c", defacl->defaclobjtype));
    5703 ECB             :                 }
    5704 EUB             : 
    5705 GBC          45 :                 systable_endscan(rcscan);
    5706 GIC          45 :                 table_close(defaclrel, AccessShareLock);
    5707 GBC          45 :                 break;
    5708 EUB             :             }
    5709                 : 
    5710 GIC          14 :         case OCLASS_EXTENSION:
    5711 EUB             :             {
    5712                 :                 char       *extname;
    5713                 : 
    5714 GIC          14 :                 extname = get_extension_name(object->objectId);
    5715 GBC          14 :                 if (!extname)
    5716 EUB             :                 {
    5717 GBC           6 :                     if (!missing_ok)
    5718 UIC           0 :                         elog(ERROR, "cache lookup failed for extension %u",
    5719 EUB             :                              object->objectId);
    5720 GIC           6 :                     break;
    5721                 :                 }
    5722 CBC           8 :                 appendStringInfoString(&buffer, quote_identifier(extname));
    5723 GIC           8 :                 if (objname)
    5724 LBC           0 :                     *objname = list_make1(extname);
    5725 CBC           8 :                 break;
    5726 ECB             :             }
    5727                 : 
    5728 GIC          24 :         case OCLASS_EVENT_TRIGGER:
    5729                 :             {
    5730 ECB             :                 HeapTuple   tup;
    5731                 :                 Form_pg_event_trigger trigForm;
    5732                 :                 char       *evtname;
    5733                 : 
    5734 GIC          24 :                 tup = SearchSysCache1(EVENTTRIGGEROID,
    5735 CBC          24 :                                       ObjectIdGetDatum(object->objectId));
    5736 GIC          24 :                 if (!HeapTupleIsValid(tup))
    5737                 :                 {
    5738               6 :                     if (!missing_ok)
    5739 LBC           0 :                         elog(ERROR, "cache lookup failed for event trigger %u",
    5740 ECB             :                              object->objectId);
    5741 GIC           6 :                     break;
    5742 ECB             :                 }
    5743 GBC          18 :                 trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
    5744 GIC          18 :                 evtname = pstrdup(NameStr(trigForm->evtname));
    5745 CBC          18 :                 appendStringInfoString(&buffer, quote_identifier(evtname));
    5746 GIC          18 :                 if (objname)
    5747 CBC           9 :                     *objname = list_make1(evtname);
    5748              18 :                 ReleaseSysCache(tup);
    5749 GBC          18 :                 break;
    5750 ECB             :             }
    5751                 : 
    5752 GIC           8 :         case OCLASS_PARAMETER_ACL:
    5753 ECB             :             {
    5754                 :                 HeapTuple   tup;
    5755                 :                 Datum       nameDatum;
    5756                 :                 char       *parname;
    5757                 : 
    5758 CBC           8 :                 tup = SearchSysCache1(PARAMETERACLOID,
    5759               8 :                                       ObjectIdGetDatum(object->objectId));
    5760               8 :                 if (!HeapTupleIsValid(tup))
    5761                 :                 {
    5762               6 :                     if (!missing_ok)
    5763 UBC           0 :                         elog(ERROR, "cache lookup failed for parameter ACL %u",
    5764                 :                              object->objectId);
    5765 CBC           6 :                     break;
    5766                 :                 }
    5767 GNC           2 :                 nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
    5768                 :                                                    Anum_pg_parameter_acl_parname);
    5769 CBC           2 :                 parname = TextDatumGetCString(nameDatum);
    5770               2 :                 appendStringInfoString(&buffer, parname);
    5771               2 :                 if (objname)
    5772 GIC           1 :                     *objname = list_make1(parname);
    5773               2 :                 ReleaseSysCache(tup);
    5774 CBC           2 :                 break;
    5775                 :             }
    5776                 : 
    5777 GIC          30 :         case OCLASS_POLICY:
    5778                 :             {
    5779                 :                 Relation    polDesc;
    5780 ECB             :                 HeapTuple   tup;
    5781                 :                 Form_pg_policy policy;
    5782                 : 
    5783 GIC          30 :                 polDesc = table_open(PolicyRelationId, AccessShareLock);
    5784 ECB             : 
    5785 GBC          30 :                 tup = get_catalog_object_by_oid(polDesc, Anum_pg_policy_oid,
    5786 GIC          30 :                                                 object->objectId);
    5787 ECB             : 
    5788 GIC          30 :                 if (!HeapTupleIsValid(tup))
    5789 ECB             :                 {
    5790 GIC           6 :                     if (!missing_ok)
    5791 LBC           0 :                         elog(ERROR, "could not find tuple for policy %u",
    5792 ECB             :                              object->objectId);
    5793                 : 
    5794 CBC           6 :                     table_close(polDesc, AccessShareLock);
    5795               6 :                     break;
    5796 ECB             :                 }
    5797                 : 
    5798 GIC          24 :                 policy = (Form_pg_policy) GETSTRUCT(tup);
    5799 ECB             : 
    5800 GIC          24 :                 appendStringInfo(&buffer, "%s on ",
    5801              24 :                                  quote_identifier(NameStr(policy->polname)));
    5802              24 :                 getRelationIdentity(&buffer, policy->polrelid, objname, false);
    5803              24 :                 if (objname)
    5804               6 :                     *objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
    5805 ECB             : 
    5806 GIC          24 :                 table_close(polDesc, AccessShareLock);
    5807 CBC          24 :                 break;
    5808 ECB             :             }
    5809                 : 
    5810 CBC          27 :         case OCLASS_PUBLICATION:
    5811                 :             {
    5812 ECB             :                 char       *pubname;
    5813 EUB             : 
    5814 GIC          27 :                 pubname = get_publication_name(object->objectId, missing_ok);
    5815              27 :                 if (pubname)
    5816 ECB             :                 {
    5817 CBC          21 :                     appendStringInfoString(&buffer,
    5818                 :                                            quote_identifier(pubname));
    5819 GIC          21 :                     if (objname)
    5820 CBC           3 :                         *objname = list_make1(pubname);
    5821                 :                 }
    5822              27 :                 break;
    5823 ECB             :             }
    5824                 : 
    5825 CBC          27 :         case OCLASS_PUBLICATION_NAMESPACE:
    5826 ECB             :             {
    5827                 :                 char       *pubname;
    5828                 :                 char       *nspname;
    5829                 : 
    5830 GIC          27 :                 if (!getPublicationSchemaInfo(object, missing_ok, &pubname,
    5831                 :                                               &nspname))
    5832 CBC           6 :                     break;
    5833 GIC          21 :                 appendStringInfo(&buffer, "%s in publication %s",
    5834                 :                                  nspname, pubname);
    5835                 : 
    5836 CBC          21 :                 if (objargs)
    5837               3 :                     *objargs = list_make1(pubname);
    5838                 :                 else
    5839              18 :                     pfree(pubname);
    5840                 : 
    5841              21 :                 if (objname)
    5842               3 :                     *objname = list_make1(nspname);
    5843                 :                 else
    5844              18 :                     pfree(nspname);
    5845                 : 
    5846 GIC          21 :                 break;
    5847 ECB             :             }
    5848                 : 
    5849 GIC          27 :         case OCLASS_PUBLICATION_REL:
    5850                 :             {
    5851                 :                 HeapTuple   tup;
    5852 ECB             :                 char       *pubname;
    5853                 :                 Form_pg_publication_rel prform;
    5854                 : 
    5855 CBC          27 :                 tup = SearchSysCache1(PUBLICATIONREL,
    5856 GIC          27 :                                       ObjectIdGetDatum(object->objectId));
    5857              27 :                 if (!HeapTupleIsValid(tup))
    5858 ECB             :                 {
    5859 CBC           6 :                     if (!missing_ok)
    5860 UIC           0 :                         elog(ERROR, "cache lookup failed for publication table %u",
    5861 ECB             :                              object->objectId);
    5862 GIC           6 :                     break;
    5863 ECB             :                 }
    5864                 : 
    5865 GIC          21 :                 prform = (Form_pg_publication_rel) GETSTRUCT(tup);
    5866 CBC          21 :                 pubname = get_publication_name(prform->prpubid, false);
    5867                 : 
    5868              21 :                 getRelationIdentity(&buffer, prform->prrelid, objname, false);
    5869 GIC          21 :                 appendStringInfo(&buffer, " in publication %s", pubname);
    5870                 : 
    5871 CBC          21 :                 if (objargs)
    5872 GIC           3 :                     *objargs = list_make1(pubname);
    5873                 : 
    5874              21 :                 ReleaseSysCache(tup);
    5875              21 :                 break;
    5876                 :             }
    5877 ECB             : 
    5878 CBC          27 :         case OCLASS_SUBSCRIPTION:
    5879 ECB             :             {
    5880                 :                 char       *subname;
    5881                 : 
    5882 GBC          27 :                 subname = get_subscription_name(object->objectId, missing_ok);
    5883 GIC          27 :                 if (subname)
    5884 ECB             :                 {
    5885 GIC          21 :                     appendStringInfoString(&buffer,
    5886                 :                                            quote_identifier(subname));
    5887 CBC          21 :                     if (objname)
    5888               3 :                         *objname = list_make1(subname);
    5889                 :                 }
    5890              27 :                 break;
    5891 ECB             :             }
    5892                 : 
    5893 CBC          29 :         case OCLASS_TRANSFORM:
    5894 ECB             :             {
    5895                 :                 Relation    transformDesc;
    5896                 :                 HeapTuple   tup;
    5897                 :                 Form_pg_transform transform;
    5898                 :                 char       *transformLang;
    5899                 :                 char       *transformType;
    5900                 : 
    5901 GIC          29 :                 transformDesc = table_open(TransformRelationId, AccessShareLock);
    5902                 : 
    5903              29 :                 tup = get_catalog_object_by_oid(transformDesc,
    5904 ECB             :                                                 Anum_pg_transform_oid,
    5905 CBC          29 :                                                 object->objectId);
    5906                 : 
    5907              29 :                 if (!HeapTupleIsValid(tup))
    5908                 :                 {
    5909               6 :                     if (!missing_ok)
    5910 LBC           0 :                         elog(ERROR, "could not find tuple for transform %u",
    5911                 :                              object->objectId);
    5912 ECB             : 
    5913 GIC           6 :                     table_close(transformDesc, AccessShareLock);
    5914               6 :                     break;
    5915 ECB             :                 }
    5916                 : 
    5917 GIC          23 :                 transform = (Form_pg_transform) GETSTRUCT(tup);
    5918                 : 
    5919              23 :                 transformType = format_type_be_qualified(transform->trftype);
    5920              23 :                 transformLang = get_language_name(transform->trflang, false);
    5921                 : 
    5922 GNC          23 :                 appendStringInfo(&buffer, "for %s language %s",
    5923 ECB             :                                  transformType,
    5924                 :                                  transformLang);
    5925 CBC          23 :                 if (objname)
    5926                 :                 {
    5927               4 :                     *objname = list_make1(transformType);
    5928 GIC           4 :                     *objargs = list_make1(pstrdup(transformLang));
    5929 ECB             :                 }
    5930                 : 
    5931 CBC          23 :                 table_close(transformDesc, AccessShareLock);
    5932 EUB             :             }
    5933 GIC          23 :             break;
    5934                 : 
    5935 ECB             :             /*
    5936                 :              * There's intentionally no default: case here; we want the
    5937                 :              * compiler to warn if a new OCLASS hasn't been handled above.
    5938                 :              */
    5939                 :     }
    5940                 : 
    5941 CBC        3016 :     if (!missing_ok)
    5942 ECB             :     {
    5943                 :         /*
    5944                 :          * If a get_object_address() representation was requested, make sure
    5945                 :          * we are providing one.  We don't check objargs, because many of the
    5946                 :          * cases above leave it as NIL.
    5947                 :          */
    5948 GIC        1420 :         if (objname && *objname == NIL)
    5949 LBC           0 :             elog(ERROR, "requested object address for unsupported object class %d: text result \"%s\"",
    5950 ECB             :                  (int) getObjectClass(object), buffer.data);
    5951                 :     }
    5952                 :     else
    5953                 :     {
    5954                 :         /* an empty buffer is equivalent to no object found */
    5955 CBC        1596 :         if (buffer.len == 0)
    5956                 :         {
    5957 GIC         255 :             Assert((objname == NULL || *objname == NIL) &&
    5958                 :                    (objargs == NULL || *objargs == NIL));
    5959             255 :             return NULL;
    5960                 :         }
    5961                 :     }
    5962                 : 
    5963 CBC        2761 :     return buffer.data;
    5964                 : }
    5965                 : 
    5966                 : static void
    5967 GIC          74 : getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
    5968                 :                     bool missing_ok)
    5969                 : {
    5970 ECB             :     HeapTuple   opfTup;
    5971 EUB             :     Form_pg_opfamily opfForm;
    5972                 :     HeapTuple   amTup;
    5973                 :     Form_pg_am  amForm;
    5974                 :     char       *schema;
    5975                 : 
    5976 GIC          74 :     opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
    5977 CBC          74 :     if (!HeapTupleIsValid(opfTup))
    5978                 :     {
    5979               6 :         if (!missing_ok)
    5980 UIC           0 :             elog(ERROR, "cache lookup failed for opfamily %u", opfid);
    5981 CBC           6 :         return;
    5982                 :     }
    5983 GIC          68 :     opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
    5984                 : 
    5985 CBC          68 :     amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
    5986 GIC          68 :     if (!HeapTupleIsValid(amTup))
    5987 UIC           0 :         elog(ERROR, "cache lookup failed for access method %u",
    5988                 :              opfForm->opfmethod);
    5989 CBC          68 :     amForm = (Form_pg_am) GETSTRUCT(amTup);
    5990                 : 
    5991 GIC          68 :     schema = get_namespace_name_or_temp(opfForm->opfnamespace);
    5992              68 :     appendStringInfo(buffer, "%s USING %s",
    5993                 :                      quote_qualified_identifier(schema,
    5994              68 :                                                 NameStr(opfForm->opfname)),
    5995              68 :                      NameStr(amForm->amname));
    5996                 : 
    5997              68 :     if (object)
    5998 CBC           9 :         *object = list_make3(pstrdup(NameStr(amForm->amname)),
    5999 ECB             :                              pstrdup(schema),
    6000                 :                              pstrdup(NameStr(opfForm->opfname)));
    6001                 : 
    6002 GBC          68 :     ReleaseSysCache(amTup);
    6003 CBC          68 :     ReleaseSysCache(opfTup);
    6004                 : }
    6005 ECB             : 
    6006                 : /*
    6007                 :  * Append the relation identity (quoted qualified name) to the given
    6008                 :  * StringInfo.
    6009 EUB             :  */
    6010                 : static void
    6011 CBC        1309 : getRelationIdentity(StringInfo buffer, Oid relid, List **object,
    6012                 :                     bool missing_ok)
    6013 ECB             : {
    6014                 :     HeapTuple   relTup;
    6015                 :     Form_pg_class relForm;
    6016                 :     char       *schema;
    6017                 : 
    6018 GIC        1309 :     relTup = SearchSysCache1(RELOID,
    6019 ECB             :                              ObjectIdGetDatum(relid));
    6020 CBC        1309 :     if (!HeapTupleIsValid(relTup))
    6021                 :     {
    6022 GIC           9 :         if (!missing_ok)
    6023 UIC           0 :             elog(ERROR, "cache lookup failed for relation %u", relid);
    6024 ECB             : 
    6025 CBC           9 :         if (object)
    6026 GIC           3 :             *object = NIL;
    6027               9 :         return;
    6028                 :     }
    6029            1300 :     relForm = (Form_pg_class) GETSTRUCT(relTup);
    6030                 : 
    6031            1300 :     schema = get_namespace_name_or_temp(relForm->relnamespace);
    6032            1300 :     appendStringInfoString(buffer,
    6033 CBC        1300 :                            quote_qualified_identifier(schema,
    6034 GIC        1300 :                                                       NameStr(relForm->relname)));
    6035            1300 :     if (object)
    6036             815 :         *object = list_make2(schema, pstrdup(NameStr(relForm->relname)));
    6037                 : 
    6038            1300 :     ReleaseSysCache(relTup);
    6039                 : }
    6040 ECB             : 
    6041                 : /*
    6042                 :  * Auxiliary function to build a TEXT array out of a list of C-strings.
    6043                 :  */
    6044                 : ArrayType *
    6045 GBC         805 : strlist_to_textarray(List *list)
    6046                 : {
    6047 ECB             :     ArrayType  *arr;
    6048                 :     Datum      *datums;
    6049                 :     bool       *nulls;
    6050 GIC         805 :     int         j = 0;
    6051 ECB             :     ListCell   *cell;
    6052                 :     MemoryContext memcxt;
    6053                 :     MemoryContext oldcxt;
    6054                 :     int         lb[1];
    6055                 : 
    6056                 :     /* Work in a temp context; easier than individually pfree'ing the Datums */
    6057 CBC         805 :     memcxt = AllocSetContextCreate(CurrentMemoryContext,
    6058 ECB             :                                    "strlist to array",
    6059                 :                                    ALLOCSET_DEFAULT_SIZES);
    6060 CBC         805 :     oldcxt = MemoryContextSwitchTo(memcxt);
    6061                 : 
    6062 GIC         805 :     datums = (Datum *) palloc(sizeof(Datum) * list_length(list));
    6063             805 :     nulls = palloc(sizeof(bool) * list_length(list));
    6064                 : 
    6065            2132 :     foreach(cell, list)
    6066                 :     {
    6067 CBC        1327 :         char       *name = lfirst(cell);
    6068                 : 
    6069 GIC        1327 :         if (name)
    6070                 :         {
    6071            1327 :             nulls[j] = false;
    6072 CBC        1327 :             datums[j++] = CStringGetTextDatum(name);
    6073                 :         }
    6074                 :         else
    6075 UIC           0 :             nulls[j] = true;
    6076                 :     }
    6077                 : 
    6078 GIC         805 :     MemoryContextSwitchTo(oldcxt);
    6079 ECB             : 
    6080 GIC         805 :     lb[0] = 1;
    6081             805 :     arr = construct_md_array(datums, nulls, 1, &j,
    6082 ECB             :                              lb, TEXTOID, -1, false, TYPALIGN_INT);
    6083                 : 
    6084 CBC         805 :     MemoryContextDelete(memcxt);
    6085 ECB             : 
    6086 GIC         805 :     return arr;
    6087 ECB             : }
    6088                 : 
    6089                 : /*
    6090                 :  * get_relkind_objtype
    6091                 :  *
    6092                 :  * Return the object type for the relkind given by the caller.
    6093                 :  *
    6094                 :  * If an unexpected relkind is passed, we say OBJECT_TABLE rather than
    6095                 :  * failing.  That's because this is mostly used for generating error messages
    6096                 :  * for failed ACL checks on relations, and we'd rather produce a generic
    6097 EUB             :  * message saying "table" than fail entirely.
    6098                 :  */
    6099                 : ObjectType
    6100 CBC         770 : get_relkind_objtype(char relkind)
    6101                 : {
    6102             770 :     switch (relkind)
    6103 ECB             :     {
    6104 GIC         609 :         case RELKIND_RELATION:
    6105                 :         case RELKIND_PARTITIONED_TABLE:
    6106 CBC         609 :             return OBJECT_TABLE;
    6107 GIC          12 :         case RELKIND_INDEX:
    6108 ECB             :         case RELKIND_PARTITIONED_INDEX:
    6109 GIC          12 :             return OBJECT_INDEX;
    6110               3 :         case RELKIND_SEQUENCE:
    6111               3 :             return OBJECT_SEQUENCE;
    6112             142 :         case RELKIND_VIEW:
    6113             142 :             return OBJECT_VIEW;
    6114 UIC           0 :         case RELKIND_MATVIEW:
    6115               0 :             return OBJECT_MATVIEW;
    6116 GIC           1 :         case RELKIND_FOREIGN_TABLE:
    6117               1 :             return OBJECT_FOREIGN_TABLE;
    6118               3 :         case RELKIND_TOASTVALUE:
    6119               3 :             return OBJECT_TABLE;
    6120 UIC           0 :         default:
    6121                 :             /* Per above, don't raise an error */
    6122 LBC           0 :             return OBJECT_TABLE;
    6123                 :     }
    6124 ECB             : }
        

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