PostgreSQL Source Code  git master
objectaddress.h File Reference
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "storage/lockdefs.h"
#include "utils/relcache.h"
Include dependency graph for objectaddress.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ObjectAddress
 

Macros

#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
 
#define ObjectAddressSet(addr, class_id, object_id)    ObjectAddressSubSet(addr, class_id, object_id, 0)
 

Typedefs

typedef struct ObjectAddress ObjectAddress
 

Functions

ObjectAddress get_object_address (ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
 
ObjectAddress get_object_address_rv (ObjectType objtype, RangeVar *rel, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
 
void check_object_ownership (Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
 
Oid get_object_namespace (const ObjectAddress *address)
 
bool is_objectclass_supported (Oid class_id)
 
const char * get_object_class_descr (Oid class_id)
 
Oid get_object_oid_index (Oid class_id)
 
int get_object_catcache_oid (Oid class_id)
 
int get_object_catcache_name (Oid class_id)
 
AttrNumber get_object_attnum_oid (Oid class_id)
 
AttrNumber get_object_attnum_name (Oid class_id)
 
AttrNumber get_object_attnum_namespace (Oid class_id)
 
AttrNumber get_object_attnum_owner (Oid class_id)
 
AttrNumber get_object_attnum_acl (Oid class_id)
 
ObjectType get_object_type (Oid class_id, Oid object_id)
 
bool get_object_namensp_unique (Oid class_id)
 
HeapTuple get_catalog_object_by_oid (Relation catalog, AttrNumber oidcol, Oid objectId)
 
char * getObjectDescription (const ObjectAddress *object, bool missing_ok)
 
char * getObjectDescriptionOids (Oid classid, Oid objid)
 
int read_objtype_from_string (const char *objtype)
 
char * getObjectTypeDescription (const ObjectAddress *object, bool missing_ok)
 
char * getObjectIdentity (const ObjectAddress *object, bool missing_ok)
 
char * getObjectIdentityParts (const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
 
struct ArrayTypestrlist_to_textarray (List *list)
 
ObjectType get_relkind_objtype (char relkind)
 

Variables

PGDLLIMPORT const ObjectAddress InvalidObjectAddress
 

Macro Definition Documentation

◆ ObjectAddressSet

#define ObjectAddressSet (   addr,
  class_id,
  object_id 
)     ObjectAddressSubSet(addr, class_id, object_id, 0)

Definition at line 40 of file objectaddress.h.

◆ ObjectAddressSubSet

#define ObjectAddressSubSet (   addr,
  class_id,
  object_id,
  object_sub_id 
)
Value:
do { \
(addr).classId = (class_id); \
(addr).objectId = (object_id); \
(addr).objectSubId = (object_sub_id); \
} while (0)

Definition at line 33 of file objectaddress.h.

Typedef Documentation

◆ ObjectAddress

typedef struct ObjectAddress ObjectAddress

Function Documentation

◆ check_object_ownership()

void check_object_ownership ( Oid  roleid,
ObjectType  objtype,
ObjectAddress  address,
Node object,
Relation  relation 
)

Definition at line 2382 of file objectaddress.c.

2384 {
2385  switch (objtype)
2386  {
2387  case OBJECT_INDEX:
2388  case OBJECT_SEQUENCE:
2389  case OBJECT_TABLE:
2390  case OBJECT_VIEW:
2391  case OBJECT_MATVIEW:
2392  case OBJECT_FOREIGN_TABLE:
2393  case OBJECT_COLUMN:
2394  case OBJECT_RULE:
2395  case OBJECT_TRIGGER:
2396  case OBJECT_POLICY:
2397  case OBJECT_TABCONSTRAINT:
2398  if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), roleid))
2400  RelationGetRelationName(relation));
2401  break;
2402  case OBJECT_TYPE:
2403  case OBJECT_DOMAIN:
2404  case OBJECT_ATTRIBUTE:
2405  if (!object_ownercheck(address.classId, address.objectId, roleid))
2407  break;
2408  case OBJECT_DOMCONSTRAINT:
2409  {
2410  HeapTuple tuple;
2411  Oid contypid;
2412 
2413  tuple = SearchSysCache1(CONSTROID,
2414  ObjectIdGetDatum(address.objectId));
2415  if (!HeapTupleIsValid(tuple))
2416  elog(ERROR, "constraint with OID %u does not exist",
2417  address.objectId);
2418 
2419  contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid;
2420 
2421  ReleaseSysCache(tuple);
2422 
2423  /*
2424  * Fallback to type ownership check in this case as this is
2425  * what domain constraints rely on.
2426  */
2427  if (!object_ownercheck(TypeRelationId, contypid, roleid))
2429  }
2430  break;
2431  case OBJECT_AGGREGATE:
2432  case OBJECT_FUNCTION:
2433  case OBJECT_PROCEDURE:
2434  case OBJECT_ROUTINE:
2435  case OBJECT_OPERATOR:
2436  if (!object_ownercheck(address.classId, address.objectId, roleid))
2438  NameListToString((castNode(ObjectWithArgs, object))->objname));
2439  break;
2440  case OBJECT_DATABASE:
2441  case OBJECT_EVENT_TRIGGER:
2442  case OBJECT_EXTENSION:
2443  case OBJECT_FDW:
2444  case OBJECT_FOREIGN_SERVER:
2445  case OBJECT_LANGUAGE:
2446  case OBJECT_PUBLICATION:
2447  case OBJECT_SCHEMA:
2448  case OBJECT_SUBSCRIPTION:
2449  case OBJECT_TABLESPACE:
2450  if (!object_ownercheck(address.classId, address.objectId, roleid))
2452  strVal(object));
2453  break;
2454  case OBJECT_COLLATION:
2455  case OBJECT_CONVERSION:
2456  case OBJECT_OPCLASS:
2457  case OBJECT_OPFAMILY:
2458  case OBJECT_STATISTIC_EXT:
2459  case OBJECT_TSDICTIONARY:
2461  if (!object_ownercheck(address.classId, address.objectId, roleid))
2463  NameListToString(castNode(List, object)));
2464  break;
2465  case OBJECT_LARGEOBJECT:
2466  if (!lo_compat_privileges &&
2467  !object_ownercheck(address.classId, address.objectId, roleid))
2468  ereport(ERROR,
2469  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2470  errmsg("must be owner of large object %u",
2471  address.objectId)));
2472  break;
2473  case OBJECT_CAST:
2474  {
2475  /* We can only check permissions on the source/target types */
2476  TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
2477  TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
2478  Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
2479  Oid targettypeid = typenameTypeId(NULL, targettype);
2480 
2481  if (!object_ownercheck(TypeRelationId, sourcetypeid, roleid)
2482  && !object_ownercheck(TypeRelationId, targettypeid, roleid))
2483  ereport(ERROR,
2484  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2485  errmsg("must be owner of type %s or type %s",
2486  format_type_be(sourcetypeid),
2487  format_type_be(targettypeid))));
2488  }
2489  break;
2490  case OBJECT_TRANSFORM:
2491  {
2492  TypeName *typename = linitial_node(TypeName, castNode(List, object));
2493  Oid typeid = typenameTypeId(NULL, typename);
2494 
2495  if (!object_ownercheck(TypeRelationId, typeid, roleid))
2497  }
2498  break;
2499  case OBJECT_ROLE:
2500 
2501  /*
2502  * We treat roles as being "owned" by those with CREATEROLE priv,
2503  * provided that they also have admin option on the role.
2504  *
2505  * However, superusers are only owned by superusers.
2506  */
2507  if (superuser_arg(address.objectId))
2508  {
2509  if (!superuser_arg(roleid))
2510  ereport(ERROR,
2511  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2512  errmsg("permission denied"),
2513  errdetail("The current user must have the %s attribute.",
2514  "SUPERUSER")));
2515  }
2516  else
2517  {
2518  if (!has_createrole_privilege(roleid))
2519  ereport(ERROR,
2520  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2521  errmsg("permission denied"),
2522  errdetail("The current user must have the %s attribute.",
2523  "CREATEROLE")));
2524  if (!is_admin_of_role(roleid, address.objectId))
2525  ereport(ERROR,
2526  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2527  errmsg("permission denied"),
2528  errdetail("The current user must have the %s option on role \"%s\".",
2529  "ADMIN",
2530  GetUserNameFromId(address.objectId,
2531  true))));
2532  }
2533  break;
2534  case OBJECT_TSPARSER:
2535  case OBJECT_TSTEMPLATE:
2536  case OBJECT_ACCESS_METHOD:
2537  case OBJECT_PARAMETER_ACL:
2538  /* We treat these object types as being owned by superusers */
2539  if (!superuser_arg(roleid))
2540  ereport(ERROR,
2541  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2542  errmsg("must be superuser")));
2543  break;
2544  case OBJECT_AMOP:
2545  case OBJECT_AMPROC:
2546  case OBJECT_DEFAULT:
2547  case OBJECT_DEFACL:
2550  case OBJECT_USER_MAPPING:
2551  /* These are currently not supported or don't make sense here. */
2552  elog(ERROR, "unsupported object type: %d", (int) objtype);
2553  break;
2554  }
2555 }
bool is_admin_of_role(Oid member, Oid role)
Definition: acl.c:5258
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2702
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4144
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3021
bool has_createrole_privilege(Oid roleid)
Definition: aclchk.c:4225
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:857
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
bool lo_compat_privileges
Definition: inv_api.c:57
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:980
char * NameListToString(const List *names)
Definition: namespace.c:3579
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:291
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2275
@ OBJECT_FDW
Definition: parsenodes.h:2277
@ OBJECT_TSPARSER
Definition: parsenodes.h:2308
@ OBJECT_COLLATION
Definition: parsenodes.h:2268
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2311
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2261
@ OBJECT_OPCLASS
Definition: parsenodes.h:2285
@ OBJECT_DEFACL
Definition: parsenodes.h:2272
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2262
@ OBJECT_MATVIEW
Definition: parsenodes.h:2284
@ OBJECT_SCHEMA
Definition: parsenodes.h:2297
@ OBJECT_POLICY
Definition: parsenodes.h:2289
@ OBJECT_OPERATOR
Definition: parsenodes.h:2286
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2279
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2306
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2287
@ OBJECT_DOMAIN
Definition: parsenodes.h:2273
@ OBJECT_COLUMN
Definition: parsenodes.h:2267
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2303
@ OBJECT_ROLE
Definition: parsenodes.h:2294
@ OBJECT_ROUTINE
Definition: parsenodes.h:2295
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2283
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2292
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2290
@ OBJECT_EXTENSION
Definition: parsenodes.h:2276
@ OBJECT_INDEX
Definition: parsenodes.h:2281
@ OBJECT_DEFAULT
Definition: parsenodes.h:2271
@ OBJECT_DATABASE
Definition: parsenodes.h:2270
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2298
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2309
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2282
@ OBJECT_AMOP
Definition: parsenodes.h:2263
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2293
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2278
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2307
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2265
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2291
@ OBJECT_RULE
Definition: parsenodes.h:2296
@ OBJECT_CONVERSION
Definition: parsenodes.h:2269
@ OBJECT_AMPROC
Definition: parsenodes.h:2264
@ OBJECT_TABLE
Definition: parsenodes.h:2302
@ OBJECT_VIEW
Definition: parsenodes.h:2312
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2288
@ OBJECT_TYPE
Definition: parsenodes.h:2310
@ OBJECT_FUNCTION
Definition: parsenodes.h:2280
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2301
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2274
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2299
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2300
@ OBJECT_CAST
Definition: parsenodes.h:2266
@ OBJECT_TRIGGER
Definition: parsenodes.h:2305
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2304
FormData_pg_constraint * Form_pg_constraint
#define linitial_node(type, l)
Definition: pg_list.h:181
#define lsecond_node(type, l)
Definition: pg_list.h:186
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationGetRelationName(relation)
Definition: rel.h:539
Definition: pg_list.h:54
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
#define strVal(v)
Definition: value.h:82

References aclcheck_error(), aclcheck_error_type(), ACLCHECK_NOT_OWNER, castNode, ObjectAddress::classId, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, format_type_be(), GETSTRUCT, GetUserNameFromId(), has_createrole_privilege(), HeapTupleIsValid, is_admin_of_role(), linitial_node, lo_compat_privileges, lsecond_node, NameListToString(), OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, object_ownercheck(), OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, OBJECT_VIEW, ObjectAddress::objectId, ObjectIdGetDatum(), RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), SearchSysCache1(), strVal, superuser_arg(), and typenameTypeId().

Referenced by CommentObject(), ExecAlterExtensionContentsStmt(), ExecAlterObjectDependsStmt(), ExecSecLabelStmt(), and RemoveObjects().

◆ get_catalog_object_by_oid()

HeapTuple get_catalog_object_by_oid ( Relation  catalog,
AttrNumber  oidcol,
Oid  objectId 
)

Definition at line 2781 of file objectaddress.c.

2782 {
2783  HeapTuple tuple;
2784  Oid classId = RelationGetRelid(catalog);
2785  int oidCacheId = get_object_catcache_oid(classId);
2786 
2787  if (oidCacheId > 0)
2788  {
2789  tuple = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId));
2790  if (!HeapTupleIsValid(tuple)) /* should not happen */
2791  return NULL;
2792  }
2793  else
2794  {
2795  Oid oidIndexId = get_object_oid_index(classId);
2796  SysScanDesc scan;
2797  ScanKeyData skey;
2798 
2799  Assert(OidIsValid(oidIndexId));
2800 
2801  ScanKeyInit(&skey,
2802  oidcol,
2803  BTEqualStrategyNumber, F_OIDEQ,
2804  ObjectIdGetDatum(objectId));
2805 
2806  scan = systable_beginscan(catalog, oidIndexId, true,
2807  NULL, 1, &skey);
2808  tuple = systable_getnext(scan);
2809  if (!HeapTupleIsValid(tuple))
2810  {
2811  systable_endscan(scan);
2812  return NULL;
2813  }
2814  tuple = heap_copytuple(tuple);
2815 
2816  systable_endscan(scan);
2817  }
2818 
2819  return tuple;
2820 }
#define Assert(condition)
Definition: c.h:858
#define OidIsValid(objectId)
Definition: c.h:775
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
int get_object_catcache_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86

References Assert, BTEqualStrategyNumber, get_object_catcache_oid(), get_object_oid_index(), heap_copytuple(), HeapTupleIsValid, ObjectIdGetDatum(), OidIsValid, RelationGetRelid, ScanKeyInit(), SearchSysCacheCopy1, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AlterObjectOwner_internal(), EventTriggerSQLDropAddObject(), getConstraintTypeDescription(), getObjectIdentityParts(), pg_event_trigger_ddl_commands(), and pg_identify_object().

◆ get_object_address()

ObjectAddress get_object_address ( ObjectType  objtype,
Node object,
Relation relp,
LOCKMODE  lockmode,
bool  missing_ok 
)

Definition at line 922 of file objectaddress.c.

924 {
925  ObjectAddress address = {InvalidOid, InvalidOid, 0};
926  ObjectAddress old_address = {InvalidOid, InvalidOid, 0};
927  Relation relation = NULL;
928  uint64 inval_count;
929 
930  /* Some kind of lock must be taken. */
931  Assert(lockmode != NoLock);
932 
933  for (;;)
934  {
935  /*
936  * Remember this value, so that, after looking up the object name and
937  * locking it, we can check whether any invalidation messages have
938  * been processed that might require a do-over.
939  */
940  inval_count = SharedInvalidMessageCounter;
941 
942  /* Look up object address. */
943  switch (objtype)
944  {
945  case OBJECT_INDEX:
946  case OBJECT_SEQUENCE:
947  case OBJECT_TABLE:
948  case OBJECT_VIEW:
949  case OBJECT_MATVIEW:
951  address =
952  get_relation_by_qualified_name(objtype, castNode(List, object),
953  &relation, lockmode,
954  missing_ok);
955  break;
956  case OBJECT_ATTRIBUTE:
957  case OBJECT_COLUMN:
958  address =
959  get_object_address_attribute(objtype, castNode(List, object),
960  &relation, lockmode,
961  missing_ok);
962  break;
963  case OBJECT_DEFAULT:
964  address =
965  get_object_address_attrdef(objtype, castNode(List, object),
966  &relation, lockmode,
967  missing_ok);
968  break;
969  case OBJECT_RULE:
970  case OBJECT_TRIGGER:
972  case OBJECT_POLICY:
973  address = get_object_address_relobject(objtype, castNode(List, object),
974  &relation, missing_ok);
975  break;
977  {
978  List *objlist;
979  ObjectAddress domaddr;
980  char *constrname;
981 
982  objlist = castNode(List, object);
984  linitial_node(TypeName, objlist),
985  missing_ok);
986  constrname = strVal(lsecond(objlist));
987 
988  address.classId = ConstraintRelationId;
989  address.objectId = get_domain_constraint_oid(domaddr.objectId,
990  constrname, missing_ok);
991  address.objectSubId = 0;
992  }
993  break;
994  case OBJECT_DATABASE:
995  case OBJECT_EXTENSION:
996  case OBJECT_TABLESPACE:
997  case OBJECT_ROLE:
998  case OBJECT_SCHEMA:
999  case OBJECT_LANGUAGE:
1000  case OBJECT_FDW:
1001  case OBJECT_FOREIGN_SERVER:
1002  case OBJECT_EVENT_TRIGGER:
1003  case OBJECT_PARAMETER_ACL:
1004  case OBJECT_ACCESS_METHOD:
1005  case OBJECT_PUBLICATION:
1006  case OBJECT_SUBSCRIPTION:
1007  address = get_object_address_unqualified(objtype,
1008  castNode(String, object), missing_ok);
1009  break;
1010  case OBJECT_TYPE:
1011  case OBJECT_DOMAIN:
1012  address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
1013  break;
1014  case OBJECT_AGGREGATE:
1015  case OBJECT_FUNCTION:
1016  case OBJECT_PROCEDURE:
1017  case OBJECT_ROUTINE:
1018  address.classId = ProcedureRelationId;
1019  address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
1020  address.objectSubId = 0;
1021  break;
1022  case OBJECT_OPERATOR:
1023  address.classId = OperatorRelationId;
1024  address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
1025  address.objectSubId = 0;
1026  break;
1027  case OBJECT_COLLATION:
1028  address.classId = CollationRelationId;
1029  address.objectId = get_collation_oid(castNode(List, object), missing_ok);
1030  address.objectSubId = 0;
1031  break;
1032  case OBJECT_CONVERSION:
1033  address.classId = ConversionRelationId;
1034  address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
1035  address.objectSubId = 0;
1036  break;
1037  case OBJECT_OPCLASS:
1038  case OBJECT_OPFAMILY:
1039  address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
1040  break;
1041  case OBJECT_AMOP:
1042  case OBJECT_AMPROC:
1043  address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
1044  break;
1045  case OBJECT_LARGEOBJECT:
1046  address.classId = LargeObjectRelationId;
1047  address.objectId = oidparse(object);
1048  address.objectSubId = 0;
1049  if (!LargeObjectExists(address.objectId))
1050  {
1051  if (!missing_ok)
1052  ereport(ERROR,
1053  (errcode(ERRCODE_UNDEFINED_OBJECT),
1054  errmsg("large object %u does not exist",
1055  address.objectId)));
1056  }
1057  break;
1058  case OBJECT_CAST:
1059  {
1060  TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
1061  TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
1062  Oid sourcetypeid;
1063  Oid targettypeid;
1064 
1065  sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
1066  targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
1067  address.classId = CastRelationId;
1068  address.objectId =
1069  get_cast_oid(sourcetypeid, targettypeid, missing_ok);
1070  address.objectSubId = 0;
1071  }
1072  break;
1073  case OBJECT_TRANSFORM:
1074  {
1075  TypeName *typename = linitial_node(TypeName, castNode(List, object));
1076  char *langname = strVal(lsecond(castNode(List, object)));
1077  Oid type_id = LookupTypeNameOid(NULL, typename, missing_ok);
1078  Oid lang_id = get_language_oid(langname, missing_ok);
1079 
1080  address.classId = TransformRelationId;
1081  address.objectId =
1082  get_transform_oid(type_id, lang_id, missing_ok);
1083  address.objectSubId = 0;
1084  }
1085  break;
1086  case OBJECT_TSPARSER:
1087  address.classId = TSParserRelationId;
1088  address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
1089  address.objectSubId = 0;
1090  break;
1091  case OBJECT_TSDICTIONARY:
1092  address.classId = TSDictionaryRelationId;
1093  address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
1094  address.objectSubId = 0;
1095  break;
1096  case OBJECT_TSTEMPLATE:
1097  address.classId = TSTemplateRelationId;
1098  address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
1099  address.objectSubId = 0;
1100  break;
1102  address.classId = TSConfigRelationId;
1103  address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
1104  address.objectSubId = 0;
1105  break;
1106  case OBJECT_USER_MAPPING:
1107  address = get_object_address_usermapping(castNode(List, object),
1108  missing_ok);
1109  break;
1112  missing_ok);
1113  break;
1116  &relation,
1117  missing_ok);
1118  break;
1119  case OBJECT_DEFACL:
1120  address = get_object_address_defacl(castNode(List, object),
1121  missing_ok);
1122  break;
1123  case OBJECT_STATISTIC_EXT:
1124  address.classId = StatisticExtRelationId;
1125  address.objectId = get_statistics_object_oid(castNode(List, object),
1126  missing_ok);
1127  address.objectSubId = 0;
1128  break;
1129  /* no default, to let compiler warn about missing case */
1130  }
1131 
1132  if (!address.classId)
1133  elog(ERROR, "unrecognized object type: %d", (int) objtype);
1134 
1135  /*
1136  * If we could not find the supplied object, return without locking.
1137  */
1138  if (!OidIsValid(address.objectId))
1139  {
1140  Assert(missing_ok);
1141  return address;
1142  }
1143 
1144  /*
1145  * If we're retrying, see if we got the same answer as last time. If
1146  * so, we're done; if not, we locked the wrong thing, so give up our
1147  * lock.
1148  */
1149  if (OidIsValid(old_address.classId))
1150  {
1151  if (old_address.classId == address.classId
1152  && old_address.objectId == address.objectId
1153  && old_address.objectSubId == address.objectSubId)
1154  break;
1155  if (old_address.classId != RelationRelationId)
1156  {
1157  if (IsSharedRelation(old_address.classId))
1158  UnlockSharedObject(old_address.classId,
1159  old_address.objectId,
1160  0, lockmode);
1161  else
1162  UnlockDatabaseObject(old_address.classId,
1163  old_address.objectId,
1164  0, lockmode);
1165  }
1166  }
1167 
1168  /*
1169  * If we're dealing with a relation or attribute, then the relation is
1170  * already locked. Otherwise, we lock it now.
1171  */
1172  if (address.classId != RelationRelationId)
1173  {
1174  if (IsSharedRelation(address.classId))
1175  LockSharedObject(address.classId, address.objectId, 0,
1176  lockmode);
1177  else
1178  LockDatabaseObject(address.classId, address.objectId, 0,
1179  lockmode);
1180  }
1181 
1182  /*
1183  * At this point, we've resolved the name to an OID and locked the
1184  * corresponding database object. However, it's possible that by the
1185  * time we acquire the lock on the object, concurrent DDL has modified
1186  * the database in such a way that the name we originally looked up no
1187  * longer resolves to that OID.
1188  *
1189  * We can be certain that this isn't an issue if (a) no shared
1190  * invalidation messages have been processed or (b) we've locked a
1191  * relation somewhere along the line. All the relation name lookups
1192  * in this module ultimately use RangeVarGetRelid() to acquire a
1193  * relation lock, and that function protects against the same kinds of
1194  * races we're worried about here. Even when operating on a
1195  * constraint, rule, or trigger, we still acquire AccessShareLock on
1196  * the relation, which is enough to freeze out any concurrent DDL.
1197  *
1198  * In all other cases, however, it's possible that the name we looked
1199  * up no longer refers to the object we locked, so we retry the lookup
1200  * and see whether we get the same answer.
1201  */
1202  if (inval_count == SharedInvalidMessageCounter || relation != NULL)
1203  break;
1204  old_address = address;
1205  }
1206 
1207  /* Return the object address and the relation. */
1208  *relp = relation;
1209  return address;
1210 }
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:243
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1083
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1004
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1142
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1063
#define NoLock
Definition: lockdefs.h:34
Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
Definition: lsyscache.c:1007
Oid get_statistics_object_oid(List *names, bool missing_ok)
Definition: namespace.c:2560
Oid get_collation_oid(List *collname, bool missing_ok)
Definition: namespace.c:3956
Oid get_conversion_oid(List *conname, bool missing_ok)
Definition: namespace.c:4010
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2846
Oid get_ts_parser_oid(List *names, bool missing_ok)
Definition: namespace.c:2701
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:3137
Oid get_ts_template_oid(List *names, bool missing_ok)
Definition: namespace.c:2992
static ObjectAddress get_object_address_publication_schema(List *object, bool missing_ok)
static ObjectAddress get_object_address_relobject(ObjectType objtype, List *object, Relation *relp, bool missing_ok)
static ObjectAddress get_object_address_defacl(List *object, bool missing_ok)
static ObjectAddress get_object_address_unqualified(ObjectType objtype, String *strval, bool missing_ok)
static ObjectAddress get_object_address_publication_rel(List *object, Relation *relp, bool missing_ok)
static ObjectAddress get_object_address_opf_member(ObjectType objtype, List *object, bool missing_ok)
static ObjectAddress get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
static ObjectAddress get_object_address_usermapping(List *object, bool missing_ok)
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
static ObjectAddress get_object_address_attribute(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static ObjectAddress get_relation_by_qualified_name(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static ObjectAddress get_object_address_attrdef(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
Oid oidparse(Node *node)
Definition: oid.c:235
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
Definition: parse_func.c:2206
Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
Definition: parse_oper.c:133
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition: parse_type.c:232
Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
bool LargeObjectExists(Oid loid)
#define lsecond(l)
Definition: pg_list.h:183
#define InvalidOid
Definition: postgres_ext.h:36
Oid get_language_oid(const char *langname, bool missing_ok)
Definition: proclang.c:226
uint64 SharedInvalidMessageCounter
Definition: sinval.c:24
Definition: value.h:64

References Assert, castNode, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, get_cast_oid(), get_collation_oid(), get_conversion_oid(), get_domain_constraint_oid(), get_language_oid(), get_object_address_attrdef(), get_object_address_attribute(), get_object_address_defacl(), get_object_address_opcf(), get_object_address_opf_member(), get_object_address_publication_rel(), get_object_address_publication_schema(), get_object_address_relobject(), get_object_address_type(), get_object_address_unqualified(), get_object_address_usermapping(), get_relation_by_qualified_name(), get_statistics_object_oid(), get_transform_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), InvalidOid, IsSharedRelation(), LargeObjectExists(), linitial_node, LockDatabaseObject(), LockSharedObject(), LookupFuncWithArgs(), LookupOperWithArgs(), LookupTypeNameOid(), lsecond, lsecond_node, NoLock, OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, OBJECT_VIEW, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, oidparse(), SharedInvalidMessageCounter, strVal, UnlockDatabaseObject(), and UnlockSharedObject().

Referenced by CommentObject(), ExecAlterExtensionContentsStmt(), ExecAlterObjectDependsStmt(), ExecAlterObjectSchemaStmt(), ExecAlterOwnerStmt(), ExecRenameStmt(), ExecSecLabelStmt(), get_object_address_rv(), pg_get_object_address(), and RemoveObjects().

◆ get_object_address_rv()

ObjectAddress get_object_address_rv ( ObjectType  objtype,
RangeVar rel,
List object,
Relation relp,
LOCKMODE  lockmode,
bool  missing_ok 
)

Definition at line 1220 of file objectaddress.c.

1223 {
1224  if (rel)
1225  {
1226  object = lcons(makeString(rel->relname), object);
1227  if (rel->schemaname)
1228  object = lcons(makeString(rel->schemaname), object);
1229  if (rel->catalogname)
1230  object = lcons(makeString(rel->catalogname), object);
1231  }
1232 
1233  return get_object_address(objtype, (Node *) object,
1234  relp, lockmode, missing_ok);
1235 }
List * lcons(void *datum, List *list)
Definition: list.c:495
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
Definition: nodes.h:129
char * relname
Definition: primnodes.h:82
char * catalogname
Definition: primnodes.h:76
char * schemaname
Definition: primnodes.h:79
String * makeString(char *str)
Definition: value.c:63

References RangeVar::catalogname, get_object_address(), lcons(), makeString(), RangeVar::relname, and RangeVar::schemaname.

Referenced by ExecAlterObjectDependsStmt().

◆ get_object_attnum_acl()

AttrNumber get_object_attnum_acl ( Oid  class_id)

Definition at line 2684 of file objectaddress.c.

2685 {
2686  const ObjectPropertyType *prop = get_object_property_data(class_id);
2687 
2688  return prop->attnum_acl;
2689 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)
AttrNumber attnum_acl

References ObjectPropertyType::attnum_acl, and get_object_property_data().

Referenced by AlterObjectOwner_internal(), ExecGrant_common(), object_aclmask_ext(), and recordExtObjInitPriv().

◆ get_object_attnum_name()

AttrNumber get_object_attnum_name ( Oid  class_id)

◆ get_object_attnum_namespace()

◆ get_object_attnum_oid()

AttrNumber get_object_attnum_oid ( Oid  class_id)

◆ get_object_attnum_owner()

◆ get_object_catcache_name()

int get_object_catcache_name ( Oid  class_id)

Definition at line 2644 of file objectaddress.c.

2645 {
2646  const ObjectPropertyType *prop = get_object_property_data(class_id);
2647 
2648  return prop->name_catcache_id;
2649 }

References get_object_property_data(), and ObjectPropertyType::name_catcache_id.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

◆ get_object_catcache_oid()

◆ get_object_class_descr()

const char* get_object_class_descr ( Oid  class_id)

◆ get_object_namensp_unique()

bool get_object_namensp_unique ( Oid  class_id)

Definition at line 2717 of file objectaddress.c.

2718 {
2719  const ObjectPropertyType *prop = get_object_property_data(class_id);
2720 
2721  return prop->is_nsp_name_unique;
2722 }

References get_object_property_data(), and ObjectPropertyType::is_nsp_name_unique.

Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().

◆ get_object_namespace()

Oid get_object_namespace ( const ObjectAddress address)

Definition at line 2564 of file objectaddress.c.

2565 {
2566  int cache;
2567  HeapTuple tuple;
2568  Oid oid;
2569  const ObjectPropertyType *property;
2570 
2571  /* If not owned by a namespace, just return InvalidOid. */
2572  property = get_object_property_data(address->classId);
2573  if (property->attnum_namespace == InvalidAttrNumber)
2574  return InvalidOid;
2575 
2576  /* Currently, we can only handle object types with system caches. */
2577  cache = property->oid_catcache_id;
2578  Assert(cache != -1);
2579 
2580  /* Fetch tuple from syscache and extract namespace attribute. */
2581  tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
2582  if (!HeapTupleIsValid(tuple))
2583  elog(ERROR, "cache lookup failed for cache %d oid %u",
2584  cache, address->objectId);
2586  tuple,
2587  property->attnum_namespace));
2588  ReleaseSysCache(tuple);
2589 
2590  return oid;
2591 }
#define InvalidAttrNumber
Definition: attnum.h:23
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:510

References Assert, ObjectPropertyType::attnum_namespace, ObjectAddress::classId, DatumGetObjectId(), elog, ERROR, get_object_property_data(), HeapTupleIsValid, InvalidAttrNumber, InvalidOid, ObjectAddress::objectId, ObjectIdGetDatum(), ReleaseSysCache(), SearchSysCache1(), and SysCacheGetAttrNotNull().

Referenced by RemoveObjects().

◆ get_object_oid_index()

Oid get_object_oid_index ( Oid  class_id)

Definition at line 2628 of file objectaddress.c.

2629 {
2630  const ObjectPropertyType *prop = get_object_property_data(class_id);
2631 
2632  return prop->oid_index_oid;
2633 }

References get_object_property_data(), and ObjectPropertyType::oid_index_oid.

Referenced by DropObjectById(), get_catalog_object_by_oid(), and object_ownercheck().

◆ get_object_type()

ObjectType get_object_type ( Oid  class_id,
Oid  object_id 
)

Definition at line 2699 of file objectaddress.c.

2700 {
2701  const ObjectPropertyType *prop = get_object_property_data(class_id);
2702 
2703  if (prop->objtype == OBJECT_TABLE)
2704  {
2705  /*
2706  * If the property data says it's a table, dig a little deeper to get
2707  * the real relation kind, so that callers can produce more precise
2708  * error messages.
2709  */
2710  return get_relkind_objtype(get_rel_relkind(object_id));
2711  }
2712  else
2713  return prop->objtype;
2714 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2003
ObjectType get_relkind_objtype(char relkind)

References get_object_property_data(), get_rel_relkind(), get_relkind_objtype(), OBJECT_TABLE, and ObjectPropertyType::objtype.

Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), ExecGrant_common(), and object_aclmask_ext().

◆ get_relkind_objtype()

ObjectType get_relkind_objtype ( char  relkind)

Definition at line 6057 of file objectaddress.c.

6058 {
6059  switch (relkind)
6060  {
6061  case RELKIND_RELATION:
6062  case RELKIND_PARTITIONED_TABLE:
6063  return OBJECT_TABLE;
6064  case RELKIND_INDEX:
6065  case RELKIND_PARTITIONED_INDEX:
6066  return OBJECT_INDEX;
6067  case RELKIND_SEQUENCE:
6068  return OBJECT_SEQUENCE;
6069  case RELKIND_VIEW:
6070  return OBJECT_VIEW;
6071  case RELKIND_MATVIEW:
6072  return OBJECT_MATVIEW;
6073  case RELKIND_FOREIGN_TABLE:
6074  return OBJECT_FOREIGN_TABLE;
6075  case RELKIND_TOASTVALUE:
6076  return OBJECT_TABLE;
6077  default:
6078  /* Per above, don't raise an error */
6079  return OBJECT_TABLE;
6080  }
6081 }

References OBJECT_FOREIGN_TABLE, OBJECT_INDEX, OBJECT_MATVIEW, OBJECT_SEQUENCE, OBJECT_TABLE, and OBJECT_VIEW.

Referenced by AlterTableMoveAll(), ATExecChangeOwner(), ATSimplePermissions(), checkFkeyPermissions(), checkPartition(), CreateStatistics(), CreateTriggerFiringOn(), currtid_internal(), DefineQueryRewrite(), EnableDisableRule(), ExecCheckPermissions(), get_object_type(), get_rel_from_relname(), heap_force_common(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), MergeAttributes(), pg_prewarm(), pgrowlocks(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackMaintainsTable(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), renameatt_check(), TargetPrivilegesCheck(), transformTableLikeClause(), and truncate_check_perms().

◆ getObjectDescription()

char* getObjectDescription ( const ObjectAddress object,
bool  missing_ok 
)

Definition at line 2878 of file objectaddress.c.

2879 {
2880  StringInfoData buffer;
2881 
2882  initStringInfo(&buffer);
2883 
2884  switch (object->classId)
2885  {
2886  case RelationRelationId:
2887  if (object->objectSubId == 0)
2888  getRelationDescription(&buffer, object->objectId, missing_ok);
2889  else
2890  {
2891  /* column, not whole relation */
2892  StringInfoData rel;
2893  char *attname = get_attname(object->objectId,
2894  object->objectSubId,
2895  missing_ok);
2896 
2897  if (!attname)
2898  break;
2899 
2900  initStringInfo(&rel);
2901  getRelationDescription(&rel, object->objectId, missing_ok);
2902  /* translator: second %s is, e.g., "table %s" */
2903  appendStringInfo(&buffer, _("column %s of %s"),
2904  attname, rel.data);
2905  pfree(rel.data);
2906  }
2907  break;
2908 
2909  case ProcedureRelationId:
2910  {
2912  char *proname = format_procedure_extended(object->objectId,
2913  flags);
2914 
2915  if (proname == NULL)
2916  break;
2917 
2918  appendStringInfo(&buffer, _("function %s"), proname);
2919  break;
2920  }
2921 
2922  case TypeRelationId:
2923  {
2925  char *typname = format_type_extended(object->objectId, -1,
2926  flags);
2927 
2928  if (typname == NULL)
2929  break;
2930 
2931  appendStringInfo(&buffer, _("type %s"), typname);
2932  break;
2933  }
2934 
2935  case CastRelationId:
2936  {
2937  Relation castDesc;
2938  ScanKeyData skey[1];
2939  SysScanDesc rcscan;
2940  HeapTuple tup;
2941  Form_pg_cast castForm;
2942 
2943  castDesc = table_open(CastRelationId, AccessShareLock);
2944 
2945  ScanKeyInit(&skey[0],
2946  Anum_pg_cast_oid,
2947  BTEqualStrategyNumber, F_OIDEQ,
2948  ObjectIdGetDatum(object->objectId));
2949 
2950  rcscan = systable_beginscan(castDesc, CastOidIndexId, true,
2951  NULL, 1, skey);
2952 
2953  tup = systable_getnext(rcscan);
2954 
2955  if (!HeapTupleIsValid(tup))
2956  {
2957  if (!missing_ok)
2958  elog(ERROR, "could not find tuple for cast %u",
2959  object->objectId);
2960 
2961  systable_endscan(rcscan);
2962  table_close(castDesc, AccessShareLock);
2963  break;
2964  }
2965 
2966  castForm = (Form_pg_cast) GETSTRUCT(tup);
2967 
2968  appendStringInfo(&buffer, _("cast from %s to %s"),
2969  format_type_be(castForm->castsource),
2970  format_type_be(castForm->casttarget));
2971 
2972  systable_endscan(rcscan);
2973  table_close(castDesc, AccessShareLock);
2974  break;
2975  }
2976 
2977  case CollationRelationId:
2978  {
2979  HeapTuple collTup;
2980  Form_pg_collation coll;
2981  char *nspname;
2982 
2983  collTup = SearchSysCache1(COLLOID,
2984  ObjectIdGetDatum(object->objectId));
2985  if (!HeapTupleIsValid(collTup))
2986  {
2987  if (!missing_ok)
2988  elog(ERROR, "cache lookup failed for collation %u",
2989  object->objectId);
2990  break;
2991  }
2992 
2993  coll = (Form_pg_collation) GETSTRUCT(collTup);
2994 
2995  /* Qualify the name if not visible in search path */
2996  if (CollationIsVisible(object->objectId))
2997  nspname = NULL;
2998  else
2999  nspname = get_namespace_name(coll->collnamespace);
3000 
3001  appendStringInfo(&buffer, _("collation %s"),
3003  NameStr(coll->collname)));
3004  ReleaseSysCache(collTup);
3005  break;
3006  }
3007 
3008  case ConstraintRelationId:
3009  {
3010  HeapTuple conTup;
3011  Form_pg_constraint con;
3012 
3013  conTup = SearchSysCache1(CONSTROID,
3014  ObjectIdGetDatum(object->objectId));
3015  if (!HeapTupleIsValid(conTup))
3016  {
3017  if (!missing_ok)
3018  elog(ERROR, "cache lookup failed for constraint %u",
3019  object->objectId);
3020  break;
3021  }
3022 
3023  con = (Form_pg_constraint) GETSTRUCT(conTup);
3024 
3025  if (OidIsValid(con->conrelid))
3026  {
3027  StringInfoData rel;
3028 
3029  initStringInfo(&rel);
3030  getRelationDescription(&rel, con->conrelid, false);
3031  /* translator: second %s is, e.g., "table %s" */
3032  appendStringInfo(&buffer, _("constraint %s on %s"),
3033  NameStr(con->conname), rel.data);
3034  pfree(rel.data);
3035  }
3036  else
3037  {
3038  appendStringInfo(&buffer, _("constraint %s"),
3039  NameStr(con->conname));
3040  }
3041 
3042  ReleaseSysCache(conTup);
3043  break;
3044  }
3045 
3046  case ConversionRelationId:
3047  {
3048  HeapTuple conTup;
3049  Form_pg_conversion conv;
3050  char *nspname;
3051 
3052  conTup = SearchSysCache1(CONVOID,
3053  ObjectIdGetDatum(object->objectId));
3054  if (!HeapTupleIsValid(conTup))
3055  {
3056  if (!missing_ok)
3057  elog(ERROR, "cache lookup failed for conversion %u",
3058  object->objectId);
3059  break;
3060  }
3061 
3062  conv = (Form_pg_conversion) GETSTRUCT(conTup);
3063 
3064  /* Qualify the name if not visible in search path */
3065  if (ConversionIsVisible(object->objectId))
3066  nspname = NULL;
3067  else
3068  nspname = get_namespace_name(conv->connamespace);
3069 
3070  appendStringInfo(&buffer, _("conversion %s"),
3072  NameStr(conv->conname)));
3073  ReleaseSysCache(conTup);
3074  break;
3075  }
3076 
3077  case AttrDefaultRelationId:
3078  {
3079  ObjectAddress colobject;
3080 
3081  colobject = GetAttrDefaultColumnAddress(object->objectId);
3082 
3083  if (!OidIsValid(colobject.objectId))
3084  {
3085  if (!missing_ok)
3086  elog(ERROR, "could not find tuple for attrdef %u",
3087  object->objectId);
3088  break;
3089  }
3090 
3091  /* translator: %s is typically "column %s of table %s" */
3092  appendStringInfo(&buffer, _("default value for %s"),
3093  getObjectDescription(&colobject, false));
3094  break;
3095  }
3096 
3097  case LanguageRelationId:
3098  {
3099  char *langname = get_language_name(object->objectId,
3100  missing_ok);
3101 
3102  if (langname)
3103  appendStringInfo(&buffer, _("language %s"),
3104  get_language_name(object->objectId, false));
3105  break;
3106  }
3107 
3108  case LargeObjectRelationId:
3109  if (!LargeObjectExists(object->objectId))
3110  break;
3111  appendStringInfo(&buffer, _("large object %u"),
3112  object->objectId);
3113  break;
3114 
3115  case OperatorRelationId:
3116  {
3118  char *oprname = format_operator_extended(object->objectId,
3119  flags);
3120 
3121  if (oprname == NULL)
3122  break;
3123 
3124  appendStringInfo(&buffer, _("operator %s"), oprname);
3125  break;
3126  }
3127 
3128  case OperatorClassRelationId:
3129  {
3130  HeapTuple opcTup;
3131  Form_pg_opclass opcForm;
3132  HeapTuple amTup;
3133  Form_pg_am amForm;
3134  char *nspname;
3135 
3136  opcTup = SearchSysCache1(CLAOID,
3137  ObjectIdGetDatum(object->objectId));
3138  if (!HeapTupleIsValid(opcTup))
3139  {
3140  if (!missing_ok)
3141  elog(ERROR, "cache lookup failed for opclass %u",
3142  object->objectId);
3143  break;
3144  }
3145 
3146  opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
3147 
3148  amTup = SearchSysCache1(AMOID,
3149  ObjectIdGetDatum(opcForm->opcmethod));
3150  if (!HeapTupleIsValid(amTup))
3151  elog(ERROR, "cache lookup failed for access method %u",
3152  opcForm->opcmethod);
3153  amForm = (Form_pg_am) GETSTRUCT(amTup);
3154 
3155  /* Qualify the name if not visible in search path */
3156  if (OpclassIsVisible(object->objectId))
3157  nspname = NULL;
3158  else
3159  nspname = get_namespace_name(opcForm->opcnamespace);
3160 
3161  appendStringInfo(&buffer, _("operator class %s for access method %s"),
3163  NameStr(opcForm->opcname)),
3164  NameStr(amForm->amname));
3165 
3166  ReleaseSysCache(amTup);
3167  ReleaseSysCache(opcTup);
3168  break;
3169  }
3170 
3171  case OperatorFamilyRelationId:
3172  getOpFamilyDescription(&buffer, object->objectId, missing_ok);
3173  break;
3174 
3175  case AccessMethodRelationId:
3176  {
3177  HeapTuple tup;
3178 
3179  tup = SearchSysCache1(AMOID,
3180  ObjectIdGetDatum(object->objectId));
3181  if (!HeapTupleIsValid(tup))
3182  {
3183  if (!missing_ok)
3184  elog(ERROR, "cache lookup failed for access method %u",
3185  object->objectId);
3186  break;
3187  }
3188 
3189  appendStringInfo(&buffer, _("access method %s"),
3190  NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
3191  ReleaseSysCache(tup);
3192  break;
3193  }
3194 
3195  case AccessMethodOperatorRelationId:
3196  {
3197  Relation amopDesc;
3198  HeapTuple tup;
3199  ScanKeyData skey[1];
3200  SysScanDesc amscan;
3201  Form_pg_amop amopForm;
3202  StringInfoData opfam;
3203 
3204  amopDesc = table_open(AccessMethodOperatorRelationId,
3205  AccessShareLock);
3206 
3207  ScanKeyInit(&skey[0],
3208  Anum_pg_amop_oid,
3209  BTEqualStrategyNumber, F_OIDEQ,
3210  ObjectIdGetDatum(object->objectId));
3211 
3212  amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
3213  NULL, 1, skey);
3214 
3215  tup = systable_getnext(amscan);
3216 
3217  if (!HeapTupleIsValid(tup))
3218  {
3219  if (!missing_ok)
3220  elog(ERROR, "could not find tuple for amop entry %u",
3221  object->objectId);
3222 
3223  systable_endscan(amscan);
3224  table_close(amopDesc, AccessShareLock);
3225  break;
3226  }
3227 
3228  amopForm = (Form_pg_amop) GETSTRUCT(tup);
3229 
3230  initStringInfo(&opfam);
3231  getOpFamilyDescription(&opfam, amopForm->amopfamily, false);
3232 
3233  /*------
3234  translator: %d is the operator strategy (a number), the
3235  first two %s's are data type names, the third %s is the
3236  description of the operator family, and the last %s is the
3237  textual form of the operator with arguments. */
3238  appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"),
3239  amopForm->amopstrategy,
3240  format_type_be(amopForm->amoplefttype),
3241  format_type_be(amopForm->amoprighttype),
3242  opfam.data,
3243  format_operator(amopForm->amopopr));
3244 
3245  pfree(opfam.data);
3246 
3247  systable_endscan(amscan);
3248  table_close(amopDesc, AccessShareLock);
3249  break;
3250  }
3251 
3252  case AccessMethodProcedureRelationId:
3253  {
3254  Relation amprocDesc;
3255  ScanKeyData skey[1];
3256  SysScanDesc amscan;
3257  HeapTuple tup;
3258  Form_pg_amproc amprocForm;
3259  StringInfoData opfam;
3260 
3261  amprocDesc = table_open(AccessMethodProcedureRelationId,
3262  AccessShareLock);
3263 
3264  ScanKeyInit(&skey[0],
3265  Anum_pg_amproc_oid,
3266  BTEqualStrategyNumber, F_OIDEQ,
3267  ObjectIdGetDatum(object->objectId));
3268 
3269  amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
3270  NULL, 1, skey);
3271 
3272  tup = systable_getnext(amscan);
3273 
3274  if (!HeapTupleIsValid(tup))
3275  {
3276  if (!missing_ok)
3277  elog(ERROR, "could not find tuple for amproc entry %u",
3278  object->objectId);
3279 
3280  systable_endscan(amscan);
3281  table_close(amprocDesc, AccessShareLock);
3282  break;
3283  }
3284 
3285  amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
3286 
3287  initStringInfo(&opfam);
3288  getOpFamilyDescription(&opfam, amprocForm->amprocfamily, false);
3289 
3290  /*------
3291  translator: %d is the function number, the first two %s's
3292  are data type names, the third %s is the description of the
3293  operator family, and the last %s is the textual form of the
3294  function with arguments. */
3295  appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"),
3296  amprocForm->amprocnum,
3297  format_type_be(amprocForm->amproclefttype),
3298  format_type_be(amprocForm->amprocrighttype),
3299  opfam.data,
3300  format_procedure(amprocForm->amproc));
3301 
3302  pfree(opfam.data);
3303 
3304  systable_endscan(amscan);
3305  table_close(amprocDesc, AccessShareLock);
3306  break;
3307  }
3308 
3309  case RewriteRelationId:
3310  {
3311  Relation ruleDesc;
3312  ScanKeyData skey[1];
3313  SysScanDesc rcscan;
3314  HeapTuple tup;
3316  StringInfoData rel;
3317 
3318  ruleDesc = table_open(RewriteRelationId, AccessShareLock);
3319 
3320  ScanKeyInit(&skey[0],
3321  Anum_pg_rewrite_oid,
3322  BTEqualStrategyNumber, F_OIDEQ,
3323  ObjectIdGetDatum(object->objectId));
3324 
3325  rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true,
3326  NULL, 1, skey);
3327 
3328  tup = systable_getnext(rcscan);
3329 
3330  if (!HeapTupleIsValid(tup))
3331  {
3332  if (!missing_ok)
3333  elog(ERROR, "could not find tuple for rule %u",
3334  object->objectId);
3335 
3336  systable_endscan(rcscan);
3337  table_close(ruleDesc, AccessShareLock);
3338  break;
3339  }
3340 
3341  rule = (Form_pg_rewrite) GETSTRUCT(tup);
3342 
3343  initStringInfo(&rel);
3344  getRelationDescription(&rel, rule->ev_class, false);
3345 
3346  /* translator: second %s is, e.g., "table %s" */
3347  appendStringInfo(&buffer, _("rule %s on %s"),
3348  NameStr(rule->rulename), rel.data);
3349  pfree(rel.data);
3350  systable_endscan(rcscan);
3351  table_close(ruleDesc, AccessShareLock);
3352  break;
3353  }
3354 
3355  case TriggerRelationId:
3356  {
3357  Relation trigDesc;
3358  ScanKeyData skey[1];
3359  SysScanDesc tgscan;
3360  HeapTuple tup;
3361  Form_pg_trigger trig;
3362  StringInfoData rel;
3363 
3364  trigDesc = table_open(TriggerRelationId, AccessShareLock);
3365 
3366  ScanKeyInit(&skey[0],
3367  Anum_pg_trigger_oid,
3368  BTEqualStrategyNumber, F_OIDEQ,
3369  ObjectIdGetDatum(object->objectId));
3370 
3371  tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true,
3372  NULL, 1, skey);
3373 
3374  tup = systable_getnext(tgscan);
3375 
3376  if (!HeapTupleIsValid(tup))
3377  {
3378  if (!missing_ok)
3379  elog(ERROR, "could not find tuple for trigger %u",
3380  object->objectId);
3381 
3382  systable_endscan(tgscan);
3383  table_close(trigDesc, AccessShareLock);
3384  break;
3385  }
3386 
3387  trig = (Form_pg_trigger) GETSTRUCT(tup);
3388 
3389  initStringInfo(&rel);
3390  getRelationDescription(&rel, trig->tgrelid, false);
3391 
3392  /* translator: second %s is, e.g., "table %s" */
3393  appendStringInfo(&buffer, _("trigger %s on %s"),
3394  NameStr(trig->tgname), rel.data);
3395  pfree(rel.data);
3396  systable_endscan(tgscan);
3397  table_close(trigDesc, AccessShareLock);
3398  break;
3399  }
3400 
3401  case NamespaceRelationId:
3402  {
3403  char *nspname;
3404 
3405  nspname = get_namespace_name(object->objectId);
3406  if (!nspname)
3407  {
3408  if (!missing_ok)
3409  elog(ERROR, "cache lookup failed for namespace %u",
3410  object->objectId);
3411  break;
3412  }
3413  appendStringInfo(&buffer, _("schema %s"), nspname);
3414  break;
3415  }
3416 
3417  case StatisticExtRelationId:
3418  {
3419  HeapTuple stxTup;
3420  Form_pg_statistic_ext stxForm;
3421  char *nspname;
3422 
3423  stxTup = SearchSysCache1(STATEXTOID,
3424  ObjectIdGetDatum(object->objectId));
3425  if (!HeapTupleIsValid(stxTup))
3426  {
3427  if (!missing_ok)
3428  elog(ERROR, "could not find tuple for statistics object %u",
3429  object->objectId);
3430  break;
3431  }
3432 
3433  stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup);
3434 
3435  /* Qualify the name if not visible in search path */
3436  if (StatisticsObjIsVisible(object->objectId))
3437  nspname = NULL;
3438  else
3439  nspname = get_namespace_name(stxForm->stxnamespace);
3440 
3441  appendStringInfo(&buffer, _("statistics object %s"),
3443  NameStr(stxForm->stxname)));
3444 
3445  ReleaseSysCache(stxTup);
3446  break;
3447  }
3448 
3449  case TSParserRelationId:
3450  {
3451  HeapTuple tup;
3452  Form_pg_ts_parser prsForm;
3453  char *nspname;
3454 
3455  tup = SearchSysCache1(TSPARSEROID,
3456  ObjectIdGetDatum(object->objectId));
3457  if (!HeapTupleIsValid(tup))
3458  {
3459  if (!missing_ok)
3460  elog(ERROR, "cache lookup failed for text search parser %u",
3461  object->objectId);
3462  break;
3463  }
3464  prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
3465 
3466  /* Qualify the name if not visible in search path */
3467  if (TSParserIsVisible(object->objectId))
3468  nspname = NULL;
3469  else
3470  nspname = get_namespace_name(prsForm->prsnamespace);
3471 
3472  appendStringInfo(&buffer, _("text search parser %s"),
3474  NameStr(prsForm->prsname)));
3475  ReleaseSysCache(tup);
3476  break;
3477  }
3478 
3479  case TSDictionaryRelationId:
3480  {
3481  HeapTuple tup;
3482  Form_pg_ts_dict dictForm;
3483  char *nspname;
3484 
3485  tup = SearchSysCache1(TSDICTOID,
3486  ObjectIdGetDatum(object->objectId));
3487  if (!HeapTupleIsValid(tup))
3488  {
3489  if (!missing_ok)
3490  elog(ERROR, "cache lookup failed for text search dictionary %u",
3491  object->objectId);
3492  break;
3493  }
3494 
3495  dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
3496 
3497  /* Qualify the name if not visible in search path */
3498  if (TSDictionaryIsVisible(object->objectId))
3499  nspname = NULL;
3500  else
3501  nspname = get_namespace_name(dictForm->dictnamespace);
3502 
3503  appendStringInfo(&buffer, _("text search dictionary %s"),
3505  NameStr(dictForm->dictname)));
3506  ReleaseSysCache(tup);
3507  break;
3508  }
3509 
3510  case TSTemplateRelationId:
3511  {
3512  HeapTuple tup;
3513  Form_pg_ts_template tmplForm;
3514  char *nspname;
3515 
3516  tup = SearchSysCache1(TSTEMPLATEOID,
3517  ObjectIdGetDatum(object->objectId));
3518  if (!HeapTupleIsValid(tup))
3519  {
3520  if (!missing_ok)
3521  elog(ERROR, "cache lookup failed for text search template %u",
3522  object->objectId);
3523  break;
3524  }
3525 
3526  tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
3527 
3528  /* Qualify the name if not visible in search path */
3529  if (TSTemplateIsVisible(object->objectId))
3530  nspname = NULL;
3531  else
3532  nspname = get_namespace_name(tmplForm->tmplnamespace);
3533 
3534  appendStringInfo(&buffer, _("text search template %s"),
3536  NameStr(tmplForm->tmplname)));
3537  ReleaseSysCache(tup);
3538  break;
3539  }
3540 
3541  case TSConfigRelationId:
3542  {
3543  HeapTuple tup;
3544  Form_pg_ts_config cfgForm;
3545  char *nspname;
3546 
3547  tup = SearchSysCache1(TSCONFIGOID,
3548  ObjectIdGetDatum(object->objectId));
3549  if (!HeapTupleIsValid(tup))
3550  {
3551  if (!missing_ok)
3552  elog(ERROR, "cache lookup failed for text search configuration %u",
3553  object->objectId);
3554  break;
3555  }
3556 
3557  cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
3558 
3559  /* Qualify the name if not visible in search path */
3560  if (TSConfigIsVisible(object->objectId))
3561  nspname = NULL;
3562  else
3563  nspname = get_namespace_name(cfgForm->cfgnamespace);
3564 
3565  appendStringInfo(&buffer, _("text search configuration %s"),
3567  NameStr(cfgForm->cfgname)));
3568  ReleaseSysCache(tup);
3569  break;
3570  }
3571 
3572  case AuthIdRelationId:
3573  {
3574  char *username = GetUserNameFromId(object->objectId,
3575  missing_ok);
3576 
3577  if (username)
3578  appendStringInfo(&buffer, _("role %s"), username);
3579  break;
3580  }
3581 
3582  case AuthMemRelationId:
3583  {
3584  Relation amDesc;
3585  ScanKeyData skey[1];
3586  SysScanDesc rcscan;
3587  HeapTuple tup;
3588  Form_pg_auth_members amForm;
3589 
3590  amDesc = table_open(AuthMemRelationId, AccessShareLock);
3591 
3592  ScanKeyInit(&skey[0],
3593  Anum_pg_auth_members_oid,
3594  BTEqualStrategyNumber, F_OIDEQ,
3595  ObjectIdGetDatum(object->objectId));
3596 
3597  rcscan = systable_beginscan(amDesc, AuthMemOidIndexId, true,
3598  NULL, 1, skey);
3599 
3600  tup = systable_getnext(rcscan);
3601 
3602  if (!HeapTupleIsValid(tup))
3603  {
3604  if (!missing_ok)
3605  elog(ERROR, "could not find tuple for role membership %u",
3606  object->objectId);
3607 
3608  systable_endscan(rcscan);
3609  table_close(amDesc, AccessShareLock);
3610  break;
3611  }
3612 
3613  amForm = (Form_pg_auth_members) GETSTRUCT(tup);
3614 
3615  appendStringInfo(&buffer, _("membership of role %s in role %s"),
3616  GetUserNameFromId(amForm->member, false),
3617  GetUserNameFromId(amForm->roleid, false));
3618 
3619  systable_endscan(rcscan);
3620  table_close(amDesc, AccessShareLock);
3621  break;
3622  }
3623 
3624  case DatabaseRelationId:
3625  {
3626  char *datname;
3627 
3628  datname = get_database_name(object->objectId);
3629  if (!datname)
3630  {
3631  if (!missing_ok)
3632  elog(ERROR, "cache lookup failed for database %u",
3633  object->objectId);
3634  break;
3635  }
3636  appendStringInfo(&buffer, _("database %s"), datname);
3637  break;
3638  }
3639 
3640  case TableSpaceRelationId:
3641  {
3642  char *tblspace;
3643 
3644  tblspace = get_tablespace_name(object->objectId);
3645  if (!tblspace)
3646  {
3647  if (!missing_ok)
3648  elog(ERROR, "cache lookup failed for tablespace %u",
3649  object->objectId);
3650  break;
3651  }
3652  appendStringInfo(&buffer, _("tablespace %s"), tblspace);
3653  break;
3654  }
3655 
3656  case ForeignDataWrapperRelationId:
3657  {
3658  ForeignDataWrapper *fdw;
3659 
3661  missing_ok);
3662  if (fdw)
3663  appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
3664  break;
3665  }
3666 
3667  case ForeignServerRelationId:
3668  {
3669  ForeignServer *srv;
3670 
3671  srv = GetForeignServerExtended(object->objectId, missing_ok);
3672  if (srv)
3673  appendStringInfo(&buffer, _("server %s"), srv->servername);
3674  break;
3675  }
3676 
3677  case UserMappingRelationId:
3678  {
3679  HeapTuple tup;
3680  Oid useid;
3681  char *usename;
3682  Form_pg_user_mapping umform;
3683  ForeignServer *srv;
3684 
3685  tup = SearchSysCache1(USERMAPPINGOID,
3686  ObjectIdGetDatum(object->objectId));
3687  if (!HeapTupleIsValid(tup))
3688  {
3689  if (!missing_ok)
3690  elog(ERROR, "cache lookup failed for user mapping %u",
3691  object->objectId);
3692  break;
3693  }
3694 
3695  umform = (Form_pg_user_mapping) GETSTRUCT(tup);
3696  useid = umform->umuser;
3697  srv = GetForeignServer(umform->umserver);
3698 
3699  ReleaseSysCache(tup);
3700 
3701  if (OidIsValid(useid))
3702  usename = GetUserNameFromId(useid, false);
3703  else
3704  usename = "public";
3705 
3706  appendStringInfo(&buffer, _("user mapping for %s on server %s"), usename,
3707  srv->servername);
3708  break;
3709  }
3710 
3711  case DefaultAclRelationId:
3712  {
3713  Relation defaclrel;
3714  ScanKeyData skey[1];
3715  SysScanDesc rcscan;
3716  HeapTuple tup;
3717  Form_pg_default_acl defacl;
3718  char *rolename;
3719  char *nspname;
3720 
3721  defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
3722 
3723  ScanKeyInit(&skey[0],
3724  Anum_pg_default_acl_oid,
3725  BTEqualStrategyNumber, F_OIDEQ,
3726  ObjectIdGetDatum(object->objectId));
3727 
3728  rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
3729  true, NULL, 1, skey);
3730 
3731  tup = systable_getnext(rcscan);
3732 
3733  if (!HeapTupleIsValid(tup))
3734  {
3735  if (!missing_ok)
3736  elog(ERROR, "could not find tuple for default ACL %u",
3737  object->objectId);
3738 
3739  systable_endscan(rcscan);
3740  table_close(defaclrel, AccessShareLock);
3741  break;
3742  }
3743 
3744  defacl = (Form_pg_default_acl) GETSTRUCT(tup);
3745 
3746  rolename = GetUserNameFromId(defacl->defaclrole, false);
3747 
3748  if (OidIsValid(defacl->defaclnamespace))
3749  nspname = get_namespace_name(defacl->defaclnamespace);
3750  else
3751  nspname = NULL;
3752 
3753  switch (defacl->defaclobjtype)
3754  {
3755  case DEFACLOBJ_RELATION:
3756  if (nspname)
3757  appendStringInfo(&buffer,
3758  _("default privileges on new relations belonging to role %s in schema %s"),
3759  rolename, nspname);
3760  else
3761  appendStringInfo(&buffer,
3762  _("default privileges on new relations belonging to role %s"),
3763  rolename);
3764  break;
3765  case DEFACLOBJ_SEQUENCE:
3766  if (nspname)
3767  appendStringInfo(&buffer,
3768  _("default privileges on new sequences belonging to role %s in schema %s"),
3769  rolename, nspname);
3770  else
3771  appendStringInfo(&buffer,
3772  _("default privileges on new sequences belonging to role %s"),
3773  rolename);
3774  break;
3775  case DEFACLOBJ_FUNCTION:
3776  if (nspname)
3777  appendStringInfo(&buffer,
3778  _("default privileges on new functions belonging to role %s in schema %s"),
3779  rolename, nspname);
3780  else
3781  appendStringInfo(&buffer,
3782  _("default privileges on new functions belonging to role %s"),
3783  rolename);
3784  break;
3785  case DEFACLOBJ_TYPE:
3786  if (nspname)
3787  appendStringInfo(&buffer,
3788  _("default privileges on new types belonging to role %s in schema %s"),
3789  rolename, nspname);
3790  else
3791  appendStringInfo(&buffer,
3792  _("default privileges on new types belonging to role %s"),
3793  rolename);
3794  break;
3795  case DEFACLOBJ_NAMESPACE:
3796  Assert(!nspname);
3797  appendStringInfo(&buffer,
3798  _("default privileges on new schemas belonging to role %s"),
3799  rolename);
3800  break;
3801  default:
3802  /* shouldn't get here */
3803  if (nspname)
3804  appendStringInfo(&buffer,
3805  _("default privileges belonging to role %s in schema %s"),
3806  rolename, nspname);
3807  else
3808  appendStringInfo(&buffer,
3809  _("default privileges belonging to role %s"),
3810  rolename);
3811  break;
3812  }
3813 
3814  systable_endscan(rcscan);
3815  table_close(defaclrel, AccessShareLock);
3816  break;
3817  }
3818 
3819  case ExtensionRelationId:
3820  {
3821  char *extname;
3822 
3823  extname = get_extension_name(object->objectId);
3824  if (!extname)
3825  {
3826  if (!missing_ok)
3827  elog(ERROR, "cache lookup failed for extension %u",
3828  object->objectId);
3829  break;
3830  }
3831  appendStringInfo(&buffer, _("extension %s"), extname);
3832  break;
3833  }
3834 
3835  case EventTriggerRelationId:
3836  {
3837  HeapTuple tup;
3838 
3839  tup = SearchSysCache1(EVENTTRIGGEROID,
3840  ObjectIdGetDatum(object->objectId));
3841  if (!HeapTupleIsValid(tup))
3842  {
3843  if (!missing_ok)
3844  elog(ERROR, "cache lookup failed for event trigger %u",
3845  object->objectId);
3846  break;
3847  }
3848  appendStringInfo(&buffer, _("event trigger %s"),
3849  NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname));
3850  ReleaseSysCache(tup);
3851  break;
3852  }
3853 
3854  case ParameterAclRelationId:
3855  {
3856  HeapTuple tup;
3857  Datum nameDatum;
3858  char *parname;
3859 
3860  tup = SearchSysCache1(PARAMETERACLOID,
3861  ObjectIdGetDatum(object->objectId));
3862  if (!HeapTupleIsValid(tup))
3863  {
3864  if (!missing_ok)
3865  elog(ERROR, "cache lookup failed for parameter ACL %u",
3866  object->objectId);
3867  break;
3868  }
3869  nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
3870  Anum_pg_parameter_acl_parname);
3871  parname = TextDatumGetCString(nameDatum);
3872  appendStringInfo(&buffer, _("parameter %s"), parname);
3873  ReleaseSysCache(tup);
3874  break;
3875  }
3876 
3877  case PolicyRelationId:
3878  {
3879  Relation policy_rel;
3880  ScanKeyData skey[1];
3881  SysScanDesc sscan;
3882  HeapTuple tuple;
3883  Form_pg_policy form_policy;
3884  StringInfoData rel;
3885 
3886  policy_rel = table_open(PolicyRelationId, AccessShareLock);
3887 
3888  ScanKeyInit(&skey[0],
3889  Anum_pg_policy_oid,
3890  BTEqualStrategyNumber, F_OIDEQ,
3891  ObjectIdGetDatum(object->objectId));
3892 
3893  sscan = systable_beginscan(policy_rel, PolicyOidIndexId,
3894  true, NULL, 1, skey);
3895 
3896  tuple = systable_getnext(sscan);
3897 
3898  if (!HeapTupleIsValid(tuple))
3899  {
3900  if (!missing_ok)
3901  elog(ERROR, "could not find tuple for policy %u",
3902  object->objectId);
3903 
3904  systable_endscan(sscan);
3905  table_close(policy_rel, AccessShareLock);
3906  break;
3907  }
3908 
3909  form_policy = (Form_pg_policy) GETSTRUCT(tuple);
3910 
3911  initStringInfo(&rel);
3912  getRelationDescription(&rel, form_policy->polrelid, false);
3913 
3914  /* translator: second %s is, e.g., "table %s" */
3915  appendStringInfo(&buffer, _("policy %s on %s"),
3916  NameStr(form_policy->polname), rel.data);
3917  pfree(rel.data);
3918  systable_endscan(sscan);
3919  table_close(policy_rel, AccessShareLock);
3920  break;
3921  }
3922 
3923  case PublicationRelationId:
3924  {
3925  char *pubname = get_publication_name(object->objectId,
3926  missing_ok);
3927 
3928  if (pubname)
3929  appendStringInfo(&buffer, _("publication %s"), pubname);
3930  break;
3931  }
3932 
3933  case PublicationNamespaceRelationId:
3934  {
3935  char *pubname;
3936  char *nspname;
3937 
3938  if (!getPublicationSchemaInfo(object, missing_ok,
3939  &pubname, &nspname))
3940  break;
3941 
3942  appendStringInfo(&buffer, _("publication of schema %s in publication %s"),
3943  nspname, pubname);
3944  pfree(pubname);
3945  pfree(nspname);
3946  break;
3947  }
3948 
3949  case PublicationRelRelationId:
3950  {
3951  HeapTuple tup;
3952  char *pubname;
3953  Form_pg_publication_rel prform;
3954  StringInfoData rel;
3955 
3956  tup = SearchSysCache1(PUBLICATIONREL,
3957  ObjectIdGetDatum(object->objectId));
3958  if (!HeapTupleIsValid(tup))
3959  {
3960  if (!missing_ok)
3961  elog(ERROR, "cache lookup failed for publication table %u",
3962  object->objectId);
3963  break;
3964  }
3965 
3966  prform = (Form_pg_publication_rel) GETSTRUCT(tup);
3967  pubname = get_publication_name(prform->prpubid, false);
3968 
3969  initStringInfo(&rel);
3970  getRelationDescription(&rel, prform->prrelid, false);
3971 
3972  /* translator: first %s is, e.g., "table %s" */
3973  appendStringInfo(&buffer, _("publication of %s in publication %s"),
3974  rel.data, pubname);
3975  pfree(rel.data);
3976  ReleaseSysCache(tup);
3977  break;
3978  }
3979 
3980  case SubscriptionRelationId:
3981  {
3982  char *subname = get_subscription_name(object->objectId,
3983  missing_ok);
3984 
3985  if (subname)
3986  appendStringInfo(&buffer, _("subscription %s"), subname);
3987  break;
3988  }
3989 
3990  case TransformRelationId:
3991  {
3992  HeapTuple trfTup;
3993  Form_pg_transform trfForm;
3994 
3995  trfTup = SearchSysCache1(TRFOID,
3996  ObjectIdGetDatum(object->objectId));
3997  if (!HeapTupleIsValid(trfTup))
3998  {
3999  if (!missing_ok)
4000  elog(ERROR, "could not find tuple for transform %u",
4001  object->objectId);
4002  break;
4003  }
4004 
4005  trfForm = (Form_pg_transform) GETSTRUCT(trfTup);
4006 
4007  appendStringInfo(&buffer, _("transform for %s language %s"),
4008  format_type_be(trfForm->trftype),
4009  get_language_name(trfForm->trflang, false));
4010 
4011  ReleaseSysCache(trfTup);
4012  break;
4013  }
4014 
4015  default:
4016  elog(ERROR, "unsupported object class: %u", object->classId);
4017  }
4018 
4019  /* an empty buffer is equivalent to no object found */
4020  if (buffer.len == 0)
4021  return NULL;
4022 
4023  return buffer.data;
4024 }
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1472
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define FORMAT_TYPE_INVALID_AS_NULL
Definition: builtins.h:127
#define NameStr(name)
Definition: c.h:746
uint16 bits16
Definition: c.h:514
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3154
#define _(x)
Definition: elog.c:90
char * get_extension_name(Oid ext_oid)
Definition: extension.c:190
ForeignServer * GetForeignServerExtended(Oid serverid, bits16 flags)
Definition: foreign.c:122
ForeignDataWrapper * GetForeignDataWrapperExtended(Oid fdwid, bits16 flags)
Definition: foreign.c:48
ForeignServer * GetForeignServer(Oid serverid)
Definition: foreign.c:110
char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
Definition: format_type.c:112
#define AccessShareLock
Definition: lockdefs.h:36
char * get_language_name(Oid langoid, bool missing_ok)
Definition: lsyscache.c:1161
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
char * get_publication_name(Oid pubid, bool missing_ok)
Definition: lsyscache.c:3645
char * get_subscription_name(Oid subid, bool missing_ok)
Definition: lsyscache.c:3695
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:827
void pfree(void *pointer)
Definition: mcxt.c:1520
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:3050
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2392
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2494
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:2139
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2759
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:3195
bool StatisticsObjIsVisible(Oid stxid)
Definition: namespace.c:2617
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2904
static void getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
static bool getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok, char **pubname, char **nspname)
static void getOpFamilyDescription(StringInfo buffer, Oid opfid, bool missing_ok)
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid)
Definition: pg_attrdef.c:381
NameData attname
Definition: pg_attribute.h:41
FormData_pg_auth_members * Form_pg_auth_members
FormData_pg_cast * Form_pg_cast
Definition: pg_cast.h:57
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:58
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
NameData datname
Definition: pg_database.h:35
FormData_pg_default_acl * Form_pg_default_acl
FormData_pg_event_trigger * Form_pg_event_trigger
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:51
NameData proname
Definition: pg_proc.h:35
FormData_pg_publication_rel * Form_pg_publication_rel
FormData_pg_rewrite * Form_pg_rewrite
Definition: pg_rewrite.h:52
FormData_pg_statistic_ext * Form_pg_statistic_ext
NameData subname
FormData_pg_transform * Form_pg_transform
Definition: pg_transform.h:43
FormData_pg_trigger * Form_pg_trigger
Definition: pg_trigger.h:80
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
FormData_pg_ts_template * Form_pg_ts_template
NameData typname
Definition: pg_type.h:41
FormData_pg_user_mapping * Form_pg_user_mapping
const char * username
Definition: pgbench.c:296
uintptr_t Datum
Definition: postgres.h:64
char * format_operator(Oid operator_oid)
Definition: regproc.c:793
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:299
char * format_operator_extended(Oid operator_oid, bits16 flags)
Definition: regproc.c:722
char * format_procedure_extended(Oid procedure_oid, bits16 flags)
Definition: regproc.c:326
#define FORMAT_OPERATOR_INVALID_AS_NULL
Definition: regproc.h:24
#define FORMAT_PROC_INVALID_AS_NULL
Definition: regproc.h:19
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:12680
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * fdwname
Definition: foreign.h:28
char * servername
Definition: foreign.h:39
Definition: localtime.c:73
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References _, AccessShareLock, appendStringInfo(), Assert, attname, BTEqualStrategyNumber, ObjectAddress::classId, CollationIsVisible(), ConversionIsVisible(), StringInfoData::data, datname, elog, ERROR, ForeignDataWrapper::fdwname, format_operator(), format_operator_extended(), FORMAT_OPERATOR_INVALID_AS_NULL, FORMAT_PROC_INVALID_AS_NULL, format_procedure(), format_procedure_extended(), format_type_be(), format_type_extended(), FORMAT_TYPE_INVALID_AS_NULL, get_attname(), get_database_name(), get_extension_name(), get_language_name(), get_namespace_name(), get_publication_name(), get_subscription_name(), get_tablespace_name(), GetAttrDefaultColumnAddress(), GetForeignDataWrapperExtended(), GetForeignServer(), GetForeignServerExtended(), getOpFamilyDescription(), getPublicationSchemaInfo(), getRelationDescription(), GETSTRUCT, GetUserNameFromId(), HeapTupleIsValid, initStringInfo(), LargeObjectExists(), StringInfoData::len, NameStr, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, OidIsValid, OpclassIsVisible(), pfree(), proname, quote_qualified_identifier(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, StatisticsObjIsVisible(), subname, SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TextDatumGetCString, TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), TSTemplateIsVisible(), typname, and username.

Referenced by AlterExtensionNamespace(), ATExecAlterColumnType(), changeDependenciesOn(), check_relation_privileges(), checkMembershipInCurrentExtension(), checkSharedDependencies(), ExecAlterExtensionContentsRecurse(), findDependentObjects(), get_altertable_subcmdinfo(), get_object_address_opf_member(), getObjectDescriptionOids(), pg_describe_object(), recordDependencyOnCurrentExtension(), RememberAllDependentForRebuilding(), reportDependentObjects(), sepgsql_fmgr_hook(), shdepDropOwned(), shdepReassignOwned(), and storeObjectDescription().

◆ getObjectDescriptionOids()

char* getObjectDescriptionOids ( Oid  classid,
Oid  objid 
)

Definition at line 4030 of file objectaddress.c.

4031 {
4032  ObjectAddress address;
4033 
4034  address.classId = classid;
4035  address.objectId = objid;
4036  address.objectSubId = 0;
4037 
4038  return getObjectDescription(&address, false);
4039 }

References ObjectAddress::classId, getObjectDescription(), ObjectAddress::objectId, and ObjectAddress::objectSubId.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

◆ getObjectIdentity()

◆ getObjectIdentityParts()

char* getObjectIdentityParts ( const ObjectAddress object,
List **  objname,
List **  objargs,
bool  missing_ok 
)

Definition at line 4714 of file objectaddress.c.

4717 {
4718  StringInfoData buffer;
4719 
4720  initStringInfo(&buffer);
4721 
4722  /*
4723  * Make sure that both objname and objargs were passed, or none was; and
4724  * initialize them to empty lists. For objname this is useless because it
4725  * will be initialized in all cases inside the switch; but we do it anyway
4726  * so that we can test below that no branch leaves it unset.
4727  */
4728  Assert(PointerIsValid(objname) == PointerIsValid(objargs));
4729  if (objname)
4730  {
4731  *objname = NIL;
4732  *objargs = NIL;
4733  }
4734 
4735  switch (object->classId)
4736  {
4737  case RelationRelationId:
4738  {
4739  char *attr = NULL;
4740 
4741  /*
4742  * Check for the attribute first, so as if it is missing we
4743  * can skip the entire relation description.
4744  */
4745  if (object->objectSubId != 0)
4746  {
4747  attr = get_attname(object->objectId,
4748  object->objectSubId,
4749  missing_ok);
4750 
4751  if (missing_ok && attr == NULL)
4752  break;
4753  }
4754 
4755  getRelationIdentity(&buffer, object->objectId, objname,
4756  missing_ok);
4757  if (objname && *objname == NIL)
4758  break;
4759 
4760  if (attr)
4761  {
4762  appendStringInfo(&buffer, ".%s",
4763  quote_identifier(attr));
4764  if (objname)
4765  *objname = lappend(*objname, attr);
4766  }
4767  }
4768  break;
4769 
4770  case ProcedureRelationId:
4771  {
4773  char *proname = format_procedure_extended(object->objectId,
4774  flags);
4775 
4776  if (proname == NULL)
4777  break;
4778 
4779  appendStringInfoString(&buffer, proname);
4780  if (objname)
4781  format_procedure_parts(object->objectId, objname, objargs,
4782  missing_ok);
4783  break;
4784  }
4785 
4786  case TypeRelationId:
4787  {
4789  char *typeout;
4790 
4791  typeout = format_type_extended(object->objectId, -1, flags);
4792 
4793  if (typeout == NULL)
4794  break;
4795 
4796  appendStringInfoString(&buffer, typeout);
4797  if (objname)
4798  *objname = list_make1(typeout);
4799  }
4800  break;
4801 
4802  case CastRelationId:
4803  {
4804  Relation castRel;
4805  HeapTuple tup;
4806  Form_pg_cast castForm;
4807 
4808  castRel = table_open(CastRelationId, AccessShareLock);
4809 
4810  tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid,
4811  object->objectId);
4812 
4813  if (!HeapTupleIsValid(tup))
4814  {
4815  if (!missing_ok)
4816  elog(ERROR, "could not find tuple for cast %u",
4817  object->objectId);
4818 
4819  table_close(castRel, AccessShareLock);
4820  break;
4821  }
4822 
4823  castForm = (Form_pg_cast) GETSTRUCT(tup);
4824 
4825  appendStringInfo(&buffer, "(%s AS %s)",
4826  format_type_be_qualified(castForm->castsource),
4827  format_type_be_qualified(castForm->casttarget));
4828 
4829  if (objname)
4830  {
4831  *objname = list_make1(format_type_be_qualified(castForm->castsource));
4832  *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
4833  }
4834 
4835  table_close(castRel, AccessShareLock);
4836  break;
4837  }
4838 
4839  case CollationRelationId:
4840  {
4841  HeapTuple collTup;
4842  Form_pg_collation coll;
4843  char *schema;
4844 
4845  collTup = SearchSysCache1(COLLOID,
4846  ObjectIdGetDatum(object->objectId));
4847  if (!HeapTupleIsValid(collTup))
4848  {
4849  if (!missing_ok)
4850  elog(ERROR, "cache lookup failed for collation %u",
4851  object->objectId);
4852  break;
4853  }
4854  coll = (Form_pg_collation) GETSTRUCT(collTup);
4855  schema = get_namespace_name_or_temp(coll->collnamespace);
4856  appendStringInfoString(&buffer,
4858  NameStr(coll->collname)));
4859  if (objname)
4860  *objname = list_make2(schema,
4861  pstrdup(NameStr(coll->collname)));
4862  ReleaseSysCache(collTup);
4863  break;
4864  }
4865 
4866  case ConstraintRelationId:
4867  {
4868  HeapTuple conTup;
4869  Form_pg_constraint con;
4870 
4871  conTup = SearchSysCache1(CONSTROID,
4872  ObjectIdGetDatum(object->objectId));
4873  if (!HeapTupleIsValid(conTup))
4874  {
4875  if (!missing_ok)
4876  elog(ERROR, "cache lookup failed for constraint %u",
4877  object->objectId);
4878  break;
4879  }
4880  con = (Form_pg_constraint) GETSTRUCT(conTup);
4881 
4882  if (OidIsValid(con->conrelid))
4883  {
4884  appendStringInfo(&buffer, "%s on ",
4885  quote_identifier(NameStr(con->conname)));
4886  getRelationIdentity(&buffer, con->conrelid, objname,
4887  false);
4888  if (objname)
4889  *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
4890  }
4891  else
4892  {
4893  ObjectAddress domain;
4894 
4895  Assert(OidIsValid(con->contypid));
4896  domain.classId = TypeRelationId;
4897  domain.objectId = con->contypid;
4898  domain.objectSubId = 0;
4899 
4900  appendStringInfo(&buffer, "%s on %s",
4901  quote_identifier(NameStr(con->conname)),
4902  getObjectIdentityParts(&domain, objname,
4903  objargs, false));
4904 
4905  if (objname)
4906  *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
4907  }
4908 
4909  ReleaseSysCache(conTup);
4910  break;
4911  }
4912 
4913  case ConversionRelationId:
4914  {
4915  HeapTuple conTup;
4916  Form_pg_conversion conForm;
4917  char *schema;
4918 
4919  conTup = SearchSysCache1(CONVOID,
4920  ObjectIdGetDatum(object->objectId));
4921  if (!HeapTupleIsValid(conTup))
4922  {
4923  if (!missing_ok)
4924  elog(ERROR, "cache lookup failed for conversion %u",
4925  object->objectId);
4926  break;
4927  }
4928  conForm = (Form_pg_conversion) GETSTRUCT(conTup);
4929  schema = get_namespace_name_or_temp(conForm->connamespace);
4930  appendStringInfoString(&buffer,
4932  NameStr(conForm->conname)));
4933  if (objname)
4934  *objname = list_make2(schema,
4935  pstrdup(NameStr(conForm->conname)));
4936  ReleaseSysCache(conTup);
4937  break;
4938  }
4939 
4940  case AttrDefaultRelationId:
4941  {
4942  ObjectAddress colobject;
4943 
4944  colobject = GetAttrDefaultColumnAddress(object->objectId);
4945 
4946  if (!OidIsValid(colobject.objectId))
4947  {
4948  if (!missing_ok)
4949  elog(ERROR, "could not find tuple for attrdef %u",
4950  object->objectId);
4951  break;
4952  }
4953 
4954  appendStringInfo(&buffer, "for %s",
4955  getObjectIdentityParts(&colobject,
4956  objname, objargs,
4957  false));
4958  break;
4959  }
4960 
4961  case LanguageRelationId:
4962  {
4963  HeapTuple langTup;
4964  Form_pg_language langForm;
4965 
4966  langTup = SearchSysCache1(LANGOID,
4967  ObjectIdGetDatum(object->objectId));
4968  if (!HeapTupleIsValid(langTup))
4969  {
4970  if (!missing_ok)
4971  elog(ERROR, "cache lookup failed for language %u",
4972  object->objectId);
4973  break;
4974  }
4975  langForm = (Form_pg_language) GETSTRUCT(langTup);
4976  appendStringInfoString(&buffer,
4977  quote_identifier(NameStr(langForm->lanname)));
4978  if (objname)
4979  *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
4980  ReleaseSysCache(langTup);
4981  break;
4982  }
4983 
4984  case LargeObjectRelationId:
4985  if (!LargeObjectExists(object->objectId))
4986  break;
4987  appendStringInfo(&buffer, "%u",
4988  object->objectId);
4989  if (objname)
4990  *objname = list_make1(psprintf("%u", object->objectId));
4991  break;
4992 
4993  case OperatorRelationId:
4994  {
4996  char *oprname = format_operator_extended(object->objectId,
4997  flags);
4998 
4999  if (oprname == NULL)
5000  break;
5001 
5002  appendStringInfoString(&buffer, oprname);
5003  if (objname)
5004  format_operator_parts(object->objectId, objname, objargs, missing_ok);
5005  break;
5006  }
5007 
5008  case OperatorClassRelationId:
5009  {
5010  HeapTuple opcTup;
5011  Form_pg_opclass opcForm;
5012  HeapTuple amTup;
5013  Form_pg_am amForm;
5014  char *schema;
5015 
5016  opcTup = SearchSysCache1(CLAOID,
5017  ObjectIdGetDatum(object->objectId));
5018  if (!HeapTupleIsValid(opcTup))
5019  {
5020  if (!missing_ok)
5021  elog(ERROR, "cache lookup failed for opclass %u",
5022  object->objectId);
5023  break;
5024  }
5025  opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
5026  schema = get_namespace_name_or_temp(opcForm->opcnamespace);
5027 
5028  amTup = SearchSysCache1(AMOID,
5029  ObjectIdGetDatum(opcForm->opcmethod));
5030  if (!HeapTupleIsValid(amTup))
5031  elog(ERROR, "cache lookup failed for access method %u",
5032  opcForm->opcmethod);
5033  amForm = (Form_pg_am) GETSTRUCT(amTup);
5034 
5035  appendStringInfo(&buffer, "%s USING %s",
5037  NameStr(opcForm->opcname)),
5038  quote_identifier(NameStr(amForm->amname)));
5039  if (objname)
5040  *objname = list_make3(pstrdup(NameStr(amForm->amname)),
5041  schema,
5042  pstrdup(NameStr(opcForm->opcname)));
5043 
5044  ReleaseSysCache(amTup);
5045  ReleaseSysCache(opcTup);
5046  break;
5047  }
5048 
5049  case OperatorFamilyRelationId:
5050  getOpFamilyIdentity(&buffer, object->objectId, objname,
5051  missing_ok);
5052  break;
5053 
5054  case AccessMethodRelationId:
5055  {
5056  char *amname;
5057 
5058  amname = get_am_name(object->objectId);
5059  if (!amname)
5060  {
5061  if (!missing_ok)
5062  elog(ERROR, "cache lookup failed for access method %u",
5063  object->objectId);
5064  break;
5065  }
5066  appendStringInfoString(&buffer, quote_identifier(amname));
5067  if (objname)
5068  *objname = list_make1(amname);
5069  }
5070  break;
5071 
5072  case AccessMethodOperatorRelationId:
5073  {
5074  Relation amopDesc;
5075  HeapTuple tup;
5076  ScanKeyData skey[1];
5077  SysScanDesc amscan;
5078  Form_pg_amop amopForm;
5079  StringInfoData opfam;
5080  char *ltype;
5081  char *rtype;
5082 
5083  amopDesc = table_open(AccessMethodOperatorRelationId,
5084  AccessShareLock);
5085 
5086  ScanKeyInit(&skey[0],
5087  Anum_pg_amop_oid,
5088  BTEqualStrategyNumber, F_OIDEQ,
5089  ObjectIdGetDatum(object->objectId));
5090 
5091  amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
5092  NULL, 1, skey);
5093 
5094  tup = systable_getnext(amscan);
5095 
5096  if (!HeapTupleIsValid(tup))
5097  {
5098  if (!missing_ok)
5099  elog(ERROR, "could not find tuple for amop entry %u",
5100  object->objectId);
5101 
5102  systable_endscan(amscan);
5103  table_close(amopDesc, AccessShareLock);
5104  break;
5105  }
5106 
5107  amopForm = (Form_pg_amop) GETSTRUCT(tup);
5108 
5109  initStringInfo(&opfam);
5110  getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
5111  false);
5112 
5113  ltype = format_type_be_qualified(amopForm->amoplefttype);
5114  rtype = format_type_be_qualified(amopForm->amoprighttype);
5115 
5116  if (objname)
5117  {
5118  *objname = lappend(*objname,
5119  psprintf("%d", amopForm->amopstrategy));
5120  *objargs = list_make2(ltype, rtype);
5121  }
5122 
5123  appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
5124  amopForm->amopstrategy,
5125  ltype, rtype, opfam.data);
5126 
5127  pfree(opfam.data);
5128 
5129  systable_endscan(amscan);
5130  table_close(amopDesc, AccessShareLock);
5131  break;
5132  }
5133 
5134  case AccessMethodProcedureRelationId:
5135  {
5136  Relation amprocDesc;
5137  ScanKeyData skey[1];
5138  SysScanDesc amscan;
5139  HeapTuple tup;
5140  Form_pg_amproc amprocForm;
5141  StringInfoData opfam;
5142  char *ltype;
5143  char *rtype;
5144 
5145  amprocDesc = table_open(AccessMethodProcedureRelationId,
5146  AccessShareLock);
5147 
5148  ScanKeyInit(&skey[0],
5149  Anum_pg_amproc_oid,
5150  BTEqualStrategyNumber, F_OIDEQ,
5151  ObjectIdGetDatum(object->objectId));
5152 
5153  amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
5154  NULL, 1, skey);
5155 
5156  tup = systable_getnext(amscan);
5157 
5158  if (!HeapTupleIsValid(tup))
5159  {
5160  if (!missing_ok)
5161  elog(ERROR, "could not find tuple for amproc entry %u",
5162  object->objectId);
5163 
5164  systable_endscan(amscan);
5165  table_close(amprocDesc, AccessShareLock);
5166  break;
5167  }
5168 
5169  amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
5170 
5171  initStringInfo(&opfam);
5172  getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
5173  false);
5174 
5175  ltype = format_type_be_qualified(amprocForm->amproclefttype);
5176  rtype = format_type_be_qualified(amprocForm->amprocrighttype);
5177 
5178  if (objname)
5179  {
5180  *objname = lappend(*objname,
5181  psprintf("%d", amprocForm->amprocnum));
5182  *objargs = list_make2(ltype, rtype);
5183  }
5184 
5185  appendStringInfo(&buffer, "function %d (%s, %s) of %s",
5186  amprocForm->amprocnum,
5187  ltype, rtype, opfam.data);
5188 
5189  pfree(opfam.data);
5190 
5191  systable_endscan(amscan);
5192  table_close(amprocDesc, AccessShareLock);
5193  break;
5194  }
5195 
5196  case RewriteRelationId:
5197  {
5198  Relation ruleDesc;
5199  HeapTuple tup;
5201 
5202  ruleDesc = table_open(RewriteRelationId, AccessShareLock);
5203 
5204  tup = get_catalog_object_by_oid(ruleDesc, Anum_pg_rewrite_oid,
5205  object->objectId);
5206 
5207  if (!HeapTupleIsValid(tup))
5208  {
5209  if (!missing_ok)
5210  elog(ERROR, "could not find tuple for rule %u",
5211  object->objectId);
5212 
5213  table_close(ruleDesc, AccessShareLock);
5214  break;
5215  }
5216 
5217  rule = (Form_pg_rewrite) GETSTRUCT(tup);
5218 
5219  appendStringInfo(&buffer, "%s on ",
5220  quote_identifier(NameStr(rule->rulename)));
5221  getRelationIdentity(&buffer, rule->ev_class, objname, false);
5222  if (objname)
5223  *objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
5224 
5225  table_close(ruleDesc, AccessShareLock);
5226  break;
5227  }
5228 
5229  case TriggerRelationId:
5230  {
5231  Relation trigDesc;
5232  HeapTuple tup;
5233  Form_pg_trigger trig;
5234 
5235  trigDesc = table_open(TriggerRelationId, AccessShareLock);
5236 
5237  tup = get_catalog_object_by_oid(trigDesc, Anum_pg_trigger_oid,
5238  object->objectId);
5239 
5240  if (!HeapTupleIsValid(tup))
5241  {
5242  if (!missing_ok)
5243  elog(ERROR, "could not find tuple for trigger %u",
5244  object->objectId);
5245 
5246  table_close(trigDesc, AccessShareLock);
5247  break;
5248  }
5249 
5250  trig = (Form_pg_trigger) GETSTRUCT(tup);
5251 
5252  appendStringInfo(&buffer, "%s on ",
5253  quote_identifier(NameStr(trig->tgname)));
5254  getRelationIdentity(&buffer, trig->tgrelid, objname, false);
5255  if (objname)
5256  *objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
5257 
5258  table_close(trigDesc, AccessShareLock);
5259  break;
5260  }
5261 
5262  case NamespaceRelationId:
5263  {
5264  char *nspname;
5265 
5266  nspname = get_namespace_name_or_temp(object->objectId);
5267  if (!nspname)
5268  {
5269  if (!missing_ok)
5270  elog(ERROR, "cache lookup failed for namespace %u",
5271  object->objectId);
5272  break;
5273  }
5274  appendStringInfoString(&buffer,
5275  quote_identifier(nspname));
5276  if (objname)
5277  *objname = list_make1(nspname);
5278  break;
5279  }
5280 
5281  case StatisticExtRelationId:
5282  {
5283  HeapTuple tup;
5284  Form_pg_statistic_ext formStatistic;
5285  char *schema;
5286 
5287  tup = SearchSysCache1(STATEXTOID,
5288  ObjectIdGetDatum(object->objectId));
5289  if (!HeapTupleIsValid(tup))
5290  {
5291  if (!missing_ok)
5292  elog(ERROR, "cache lookup failed for statistics object %u",
5293  object->objectId);
5294  break;
5295  }
5296  formStatistic = (Form_pg_statistic_ext) GETSTRUCT(tup);
5297  schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
5298  appendStringInfoString(&buffer,
5300  NameStr(formStatistic->stxname)));
5301  if (objname)
5302  *objname = list_make2(schema,
5303  pstrdup(NameStr(formStatistic->stxname)));
5304  ReleaseSysCache(tup);
5305  }
5306  break;
5307 
5308  case TSParserRelationId:
5309  {
5310  HeapTuple tup;
5311  Form_pg_ts_parser formParser;
5312  char *schema;
5313 
5314  tup = SearchSysCache1(TSPARSEROID,
5315  ObjectIdGetDatum(object->objectId));
5316  if (!HeapTupleIsValid(tup))
5317  {
5318  if (!missing_ok)
5319  elog(ERROR, "cache lookup failed for text search parser %u",
5320  object->objectId);
5321  break;
5322  }
5323  formParser = (Form_pg_ts_parser) GETSTRUCT(tup);
5324  schema = get_namespace_name_or_temp(formParser->prsnamespace);
5325  appendStringInfoString(&buffer,
5327  NameStr(formParser->prsname)));
5328  if (objname)
5329  *objname = list_make2(schema,
5330  pstrdup(NameStr(formParser->prsname)));
5331  ReleaseSysCache(tup);
5332  break;
5333  }
5334 
5335  case TSDictionaryRelationId:
5336  {
5337  HeapTuple tup;
5338  Form_pg_ts_dict formDict;
5339  char *schema;
5340 
5341  tup = SearchSysCache1(TSDICTOID,
5342  ObjectIdGetDatum(object->objectId));
5343  if (!HeapTupleIsValid(tup))
5344  {
5345  if (!missing_ok)
5346  elog(ERROR, "cache lookup failed for text search dictionary %u",
5347  object->objectId);
5348  break;
5349  }
5350  formDict = (Form_pg_ts_dict) GETSTRUCT(tup);
5351  schema = get_namespace_name_or_temp(formDict->dictnamespace);
5352  appendStringInfoString(&buffer,
5354  NameStr(formDict->dictname)));
5355  if (objname)
5356  *objname = list_make2(schema,
5357  pstrdup(NameStr(formDict->dictname)));
5358  ReleaseSysCache(tup);
5359  break;
5360  }
5361 
5362  case TSTemplateRelationId:
5363  {
5364  HeapTuple tup;
5365  Form_pg_ts_template formTmpl;
5366  char *schema;
5367 
5368  tup = SearchSysCache1(TSTEMPLATEOID,
5369  ObjectIdGetDatum(object->objectId));
5370  if (!HeapTupleIsValid(tup))
5371  {
5372  if (!missing_ok)
5373  elog(ERROR, "cache lookup failed for text search template %u",
5374  object->objectId);
5375  break;
5376  }
5377  formTmpl = (Form_pg_ts_template) GETSTRUCT(tup);
5378  schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
5379  appendStringInfoString(&buffer,
5381  NameStr(formTmpl->tmplname)));
5382  if (objname)
5383  *objname = list_make2(schema,
5384  pstrdup(NameStr(formTmpl->tmplname)));
5385  ReleaseSysCache(tup);
5386  break;
5387  }
5388 
5389  case TSConfigRelationId:
5390  {
5391  HeapTuple tup;
5392  Form_pg_ts_config formCfg;
5393  char *schema;
5394 
5395  tup = SearchSysCache1(TSCONFIGOID,
5396  ObjectIdGetDatum(object->objectId));
5397  if (!HeapTupleIsValid(tup))
5398  {
5399  if (!missing_ok)
5400  elog(ERROR, "cache lookup failed for text search configuration %u",
5401  object->objectId);
5402  break;
5403  }
5404  formCfg = (Form_pg_ts_config) GETSTRUCT(tup);
5405  schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
5406  appendStringInfoString(&buffer,
5408  NameStr(formCfg->cfgname)));
5409  if (objname)
5410  *objname = list_make2(schema,
5411  pstrdup(NameStr(formCfg->cfgname)));
5412  ReleaseSysCache(tup);
5413  break;
5414  }
5415 
5416  case AuthIdRelationId:
5417  {
5418  char *username;
5419 
5420  username = GetUserNameFromId(object->objectId, missing_ok);
5421  if (!username)
5422  break;
5423  if (objname)
5424  *objname = list_make1(username);
5425  appendStringInfoString(&buffer,
5427  break;
5428  }
5429 
5430  case AuthMemRelationId:
5431  {
5432  Relation authMemDesc;
5433  ScanKeyData skey[1];
5434  SysScanDesc amscan;
5435  HeapTuple tup;
5436  Form_pg_auth_members amForm;
5437 
5438  authMemDesc = table_open(AuthMemRelationId,
5439  AccessShareLock);
5440 
5441  ScanKeyInit(&skey[0],
5442  Anum_pg_auth_members_oid,
5443  BTEqualStrategyNumber, F_OIDEQ,
5444  ObjectIdGetDatum(object->objectId));
5445 
5446  amscan = systable_beginscan(authMemDesc, AuthMemOidIndexId, true,
5447  NULL, 1, skey);
5448 
5449  tup = systable_getnext(amscan);
5450 
5451  if (!HeapTupleIsValid(tup))
5452  {
5453  if (!missing_ok)
5454  elog(ERROR, "could not find tuple for pg_auth_members entry %u",
5455  object->objectId);
5456 
5457  systable_endscan(amscan);
5458  table_close(authMemDesc, AccessShareLock);
5459  break;
5460  }
5461 
5462  amForm = (Form_pg_auth_members) GETSTRUCT(tup);
5463 
5464  appendStringInfo(&buffer, _("membership of role %s in role %s"),
5465  GetUserNameFromId(amForm->member, false),
5466  GetUserNameFromId(amForm->roleid, false));
5467 
5468  systable_endscan(amscan);
5469  table_close(authMemDesc, AccessShareLock);
5470  break;
5471  }
5472 
5473  case DatabaseRelationId:
5474  {
5475  char *datname;
5476 
5477  datname = get_database_name(object->objectId);
5478  if (!datname)
5479  {
5480  if (!missing_ok)
5481  elog(ERROR, "cache lookup failed for database %u",
5482  object->objectId);
5483  break;
5484  }
5485  if (objname)
5486  *objname = list_make1(datname);
5487  appendStringInfoString(&buffer,
5489  break;
5490  }
5491 
5492  case TableSpaceRelationId:
5493  {
5494  char *tblspace;
5495 
5496  tblspace = get_tablespace_name(object->objectId);
5497  if (!tblspace)
5498  {
5499  if (!missing_ok)
5500  elog(ERROR, "cache lookup failed for tablespace %u",
5501  object->objectId);
5502  break;
5503  }
5504  if (objname)
5505  *objname = list_make1(tblspace);
5506  appendStringInfoString(&buffer,
5507  quote_identifier(tblspace));
5508  break;
5509  }
5510 
5511  case ForeignDataWrapperRelationId:
5512  {
5513  ForeignDataWrapper *fdw;
5514 
5516  missing_ok);
5517  if (fdw)
5518  {
5520  if (objname)
5521  *objname = list_make1(pstrdup(fdw->fdwname));
5522  }
5523  break;
5524  }
5525 
5526  case ForeignServerRelationId:
5527  {
5528  ForeignServer *srv;
5529 
5530  srv = GetForeignServerExtended(object->objectId,
5531  missing_ok);
5532  if (srv)
5533  {
5534  appendStringInfoString(&buffer,
5536  if (objname)
5537  *objname = list_make1(pstrdup(srv->servername));
5538  }
5539  break;
5540  }
5541 
5542  case UserMappingRelationId:
5543  {
5544  HeapTuple tup;
5545  Oid useid;
5546  Form_pg_user_mapping umform;
5547  ForeignServer *srv;
5548  const char *usename;
5549 
5550  tup = SearchSysCache1(USERMAPPINGOID,
5551  ObjectIdGetDatum(object->objectId));
5552  if (!HeapTupleIsValid(tup))
5553  {
5554  if (!missing_ok)
5555  elog(ERROR, "cache lookup failed for user mapping %u",
5556  object->objectId);
5557  break;
5558  }
5559  umform = (Form_pg_user_mapping) GETSTRUCT(tup);
5560  useid = umform->umuser;
5561  srv = GetForeignServer(umform->umserver);
5562 
5563  ReleaseSysCache(tup);
5564 
5565  if (OidIsValid(useid))
5566  usename = GetUserNameFromId(useid, false);
5567  else
5568  usename = "public";
5569 
5570  if (objname)
5571  {
5572  *objname = list_make1(pstrdup(usename));
5573  *objargs = list_make1(pstrdup(srv->servername));
5574  }
5575 
5576  appendStringInfo(&buffer, "%s on server %s",
5577  quote_identifier(usename),
5578  srv->servername);
5579  break;
5580  }
5581 
5582  case DefaultAclRelationId:
5583  {
5584  Relation defaclrel;
5585  ScanKeyData skey[1];
5586  SysScanDesc rcscan;
5587  HeapTuple tup;
5588  Form_pg_default_acl defacl;
5589  char *schema;
5590  char *username;
5591 
5592  defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
5593 
5594  ScanKeyInit(&skey[0],
5595  Anum_pg_default_acl_oid,
5596  BTEqualStrategyNumber, F_OIDEQ,
5597  ObjectIdGetDatum(object->objectId));
5598 
5599  rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
5600  true, NULL, 1, skey);
5601 
5602  tup = systable_getnext(rcscan);
5603 
5604  if (!HeapTupleIsValid(tup))
5605  {
5606  if (!missing_ok)
5607  elog(ERROR, "could not find tuple for default ACL %u",
5608  object->objectId);
5609 
5610  systable_endscan(rcscan);
5611  table_close(defaclrel, AccessShareLock);
5612  break;
5613  }
5614 
5615  defacl = (Form_pg_default_acl) GETSTRUCT(tup);
5616 
5617  username = GetUserNameFromId(defacl->defaclrole, false);
5618  appendStringInfo(&buffer,
5619  "for role %s",
5621 
5622  if (OidIsValid(defacl->defaclnamespace))
5623  {
5624  schema = get_namespace_name_or_temp(defacl->defaclnamespace);
5625  appendStringInfo(&buffer,
5626  " in schema %s",
5627  quote_identifier(schema));
5628  }
5629  else
5630  schema = NULL;
5631 
5632  switch (defacl->defaclobjtype)
5633  {
5634  case DEFACLOBJ_RELATION:
5635  appendStringInfoString(&buffer,
5636  " on tables");
5637  break;
5638  case DEFACLOBJ_SEQUENCE:
5639  appendStringInfoString(&buffer,
5640  " on sequences");
5641  break;
5642  case DEFACLOBJ_FUNCTION:
5643  appendStringInfoString(&buffer,
5644  " on functions");
5645  break;
5646  case DEFACLOBJ_TYPE:
5647  appendStringInfoString(&buffer,
5648  " on types");
5649  break;
5650  case DEFACLOBJ_NAMESPACE:
5651  appendStringInfoString(&buffer,
5652  " on schemas");
5653  break;
5654  }
5655 
5656  if (objname)
5657  {
5658  *objname = list_make1(username);
5659  if (schema)
5660  *objname = lappend(*objname, schema);
5661  *objargs = list_make1(psprintf("%c", defacl->defaclobjtype));
5662  }
5663 
5664  systable_endscan(rcscan);
5665  table_close(defaclrel, AccessShareLock);
5666  break;
5667  }
5668 
5669  case ExtensionRelationId:
5670  {
5671  char *extname;
5672 
5673  extname = get_extension_name(object->objectId);
5674  if (!extname)
5675  {
5676  if (!missing_ok)
5677  elog(ERROR, "cache lookup failed for extension %u",
5678  object->objectId);
5679  break;
5680  }
5681  appendStringInfoString(&buffer, quote_identifier(extname));
5682  if (objname)
5683  *objname = list_make1(extname);
5684  break;
5685  }
5686 
5687  case EventTriggerRelationId:
5688  {
5689  HeapTuple tup;
5690  Form_pg_event_trigger trigForm;
5691  char *evtname;
5692 
5693  tup = SearchSysCache1(EVENTTRIGGEROID,
5694  ObjectIdGetDatum(object->objectId));
5695  if (!HeapTupleIsValid(tup))
5696  {
5697  if (!missing_ok)
5698  elog(ERROR, "cache lookup failed for event trigger %u",
5699  object->objectId);
5700  break;
5701  }
5702  trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
5703  evtname = pstrdup(NameStr(trigForm->evtname));
5704  appendStringInfoString(&buffer, quote_identifier(evtname));
5705  if (objname)
5706  *objname = list_make1(evtname);
5707  ReleaseSysCache(tup);
5708  break;
5709  }
5710 
5711  case ParameterAclRelationId:
5712  {
5713  HeapTuple tup;
5714  Datum nameDatum;
5715  char *parname;
5716 
5717  tup = SearchSysCache1(PARAMETERACLOID,
5718  ObjectIdGetDatum(object->objectId));
5719  if (!HeapTupleIsValid(tup))
5720  {
5721  if (!missing_ok)
5722  elog(ERROR, "cache lookup failed for parameter ACL %u",
5723  object->objectId);
5724  break;
5725  }
5726  nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
5727  Anum_pg_parameter_acl_parname);
5728  parname = TextDatumGetCString(nameDatum);
5729  appendStringInfoString(&buffer, parname);
5730  if (objname)
5731  *objname = list_make1(parname);
5732  ReleaseSysCache(tup);
5733  break;
5734  }
5735 
5736  case PolicyRelationId:
5737  {
5738  Relation polDesc;
5739  HeapTuple tup;
5740  Form_pg_policy policy;
5741 
5742  polDesc = table_open(PolicyRelationId, AccessShareLock);
5743 
5744  tup = get_catalog_object_by_oid(polDesc, Anum_pg_policy_oid,
5745  object->objectId);
5746 
5747  if (!HeapTupleIsValid(tup))
5748  {
5749  if (!missing_ok)
5750  elog(ERROR, "could not find tuple for policy %u",
5751  object->objectId);
5752 
5753  table_close(polDesc, AccessShareLock);
5754  break;
5755  }
5756 
5757  policy = (Form_pg_policy) GETSTRUCT(tup);
5758 
5759  appendStringInfo(&buffer, "%s on ",
5760  quote_identifier(NameStr(policy->polname)));
5761  getRelationIdentity(&buffer, policy->polrelid, objname, false);
5762  if (objname)
5763  *objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
5764 
5765  table_close(polDesc, AccessShareLock);
5766  break;
5767  }
5768 
5769  case PublicationRelationId:
5770  {
5771  char *pubname;
5772 
5773  pubname = get_publication_name(object->objectId, missing_ok);
5774  if (pubname)
5775  {
5776  appendStringInfoString(&buffer,
5777  quote_identifier(pubname));
5778  if (objname)
5779  *objname = list_make1(pubname);
5780  }
5781  break;
5782  }
5783 
5784  case PublicationNamespaceRelationId:
5785  {
5786  char *pubname;
5787  char *nspname;
5788 
5789  if (!getPublicationSchemaInfo(object, missing_ok, &pubname,
5790  &nspname))
5791  break;
5792  appendStringInfo(&buffer, "%s in publication %s",
5793  nspname, pubname);
5794 
5795  if (objargs)
5796  *objargs = list_make1(pubname);
5797  else
5798  pfree(pubname);
5799 
5800  if (objname)
5801  *objname = list_make1(nspname);
5802  else
5803  pfree(nspname);
5804 
5805  break;
5806  }
5807 
5808  case PublicationRelRelationId:
5809  {
5810  HeapTuple tup;
5811  char *pubname;
5812  Form_pg_publication_rel prform;
5813 
5814  tup = SearchSysCache1(PUBLICATIONREL,
5815  ObjectIdGetDatum(object->objectId));
5816  if (!HeapTupleIsValid(tup))
5817  {
5818  if (!missing_ok)
5819  elog(ERROR, "cache lookup failed for publication table %u",
5820  object->objectId);
5821  break;
5822  }
5823 
5824  prform = (Form_pg_publication_rel) GETSTRUCT(tup);
5825  pubname = get_publication_name(prform->prpubid, false);
5826 
5827  getRelationIdentity(&buffer, prform->prrelid, objname, false);
5828  appendStringInfo(&buffer, " in publication %s", pubname);
5829 
5830  if (objargs)
5831  *objargs = list_make1(pubname);
5832 
5833  ReleaseSysCache(tup);
5834  break;
5835  }
5836 
5837  case SubscriptionRelationId:
5838  {
5839  char *subname;
5840 
5841  subname = get_subscription_name(object->objectId, missing_ok);
5842  if (subname)
5843  {
5844  appendStringInfoString(&buffer,
5846  if (objname)
5847  *objname = list_make1(subname);
5848  }
5849  break;
5850  }
5851 
5852  case TransformRelationId:
5853  {
5854  Relation transformDesc;
5855  HeapTuple tup;
5856  Form_pg_transform transform;
5857  char *transformLang;
5858  char *transformType;
5859 
5860  transformDesc = table_open(TransformRelationId, AccessShareLock);
5861 
5862  tup = get_catalog_object_by_oid(transformDesc,
5863  Anum_pg_transform_oid,
5864  object->objectId);
5865 
5866  if (!HeapTupleIsValid(tup))
5867  {
5868  if (!missing_ok)
5869  elog(ERROR, "could not find tuple for transform %u",
5870  object->objectId);
5871 
5872  table_close(transformDesc, AccessShareLock);
5873  break;
5874  }
5875 
5876  transform = (Form_pg_transform) GETSTRUCT(tup);
5877 
5878  transformType = format_type_be_qualified(transform->trftype);
5879  transformLang = get_language_name(transform->trflang, false);
5880 
5881  appendStringInfo(&buffer, "for %s language %s",
5882  transformType,
5883  transformLang);
5884  if (objname)
5885  {
5886  *objname = list_make1(transformType);
5887  *objargs = list_make1(pstrdup(transformLang));
5888  }
5889 
5890  table_close(transformDesc, AccessShareLock);
5891  }
5892  break;
5893 
5894  default:
5895  elog(ERROR, "unsupported object class: %u", object->classId);
5896  }
5897 
5898  if (!missing_ok)
5899  {
5900  /*
5901  * If a get_object_address() representation was requested, make sure
5902  * we are providing one. We don't check objargs, because many of the
5903  * cases above leave it as NIL.
5904  */
5905  if (objname && *objname == NIL)
5906  elog(ERROR, "requested object address for unsupported object class %u: text result \"%s\"",
5907  object->classId, buffer.data);
5908  }
5909  else
5910  {
5911  /* an empty buffer is equivalent to no object found */
5912  if (buffer.len == 0)
5913  {
5914  Assert((objname == NULL || *objname == NIL) &&
5915  (objargs == NULL || *objargs == NIL));
5916  return NULL;
5917  }
5918  }
5919 
5920  return buffer.data;
5921 }
char * get_am_name(Oid amOid)
Definition: amcmds.c:192
#define FORMAT_TYPE_FORCE_QUALIFY
Definition: builtins.h:126
#define PointerIsValid(pointer)
Definition: c.h:763
char * format_type_be_qualified(Oid type_oid)
Definition: format_type.c:353
List * lappend(List *list, void *datum)
Definition: list.c:339
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3390
char * pstrdup(const char *in)
Definition: mcxt.c:1695
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object, bool missing_ok)
static void getRelationIdentity(StringInfo buffer, Oid relid, List **object, bool missing_ok)
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
#define NIL
Definition: pg_list.h:68
#define list_make1(x1)
Definition: pg_list.h:212
#define list_make3(x1, x2, x3)
Definition: pg_list.h:216
#define list_make2(x1, x2)
Definition: pg_list.h:214
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void format_operator_parts(Oid operator_oid, List **objnames, List **objargs, bool missing_ok)
Definition: regproc.c:806
void format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs, bool missing_ok)
Definition: regproc.c:398
#define FORMAT_OPERATOR_FORCE_QUALIFY
Definition: regproc.h:25
#define FORMAT_PROC_FORCE_QUALIFY
Definition: regproc.h:20
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12596
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182

References _, AccessShareLock, appendStringInfo(), appendStringInfoString(), Assert, BTEqualStrategyNumber, ObjectAddress::classId, StringInfoData::data, datname, elog, ERROR, ForeignDataWrapper::fdwname, format_operator_extended(), FORMAT_OPERATOR_FORCE_QUALIFY, FORMAT_OPERATOR_INVALID_AS_NULL, format_operator_parts(), FORMAT_PROC_FORCE_QUALIFY, FORMAT_PROC_INVALID_AS_NULL, format_procedure_extended(), format_procedure_parts(), format_type_be_qualified(), format_type_extended(), FORMAT_TYPE_FORCE_QUALIFY, FORMAT_TYPE_INVALID_AS_NULL, get_am_name(), get_attname(), get_catalog_object_by_oid(), get_database_name(), get_extension_name(), get_language_name(), get_namespace_name_or_temp(), get_publication_name(), get_subscription_name(), get_tablespace_name(), GetAttrDefaultColumnAddress(), GetForeignDataWrapperExtended(), GetForeignServer(), GetForeignServerExtended(), getOpFamilyIdentity(), getPublicationSchemaInfo(), getRelationIdentity(), GETSTRUCT, GetUserNameFromId(), HeapTupleIsValid, initStringInfo(), lappend(), LargeObjectExists(), StringInfoData::len, list_make1, list_make2, list_make3, NameStr, NIL, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, OidIsValid, pfree(), PointerIsValid, proname, psprintf(), pstrdup(), quote_identifier(), quote_qualified_identifier(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, subname, SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TextDatumGetCString, and username.

Referenced by EventTriggerSQLDropAddObject(), getObjectIdentity(), and pg_identify_object_as_address().

◆ getObjectTypeDescription()

char* getObjectTypeDescription ( const ObjectAddress object,
bool  missing_ok 
)

Definition at line 4372 of file objectaddress.c.

4373 {
4374  StringInfoData buffer;
4375 
4376  initStringInfo(&buffer);
4377 
4378  switch (object->classId)
4379  {
4380  case RelationRelationId:
4381  getRelationTypeDescription(&buffer, object->objectId,
4382  object->objectSubId,
4383  missing_ok);
4384  break;
4385 
4386  case ProcedureRelationId:
4387  getProcedureTypeDescription(&buffer, object->objectId,
4388  missing_ok);
4389  break;
4390 
4391  case TypeRelationId:
4392  appendStringInfoString(&buffer, "type");
4393  break;
4394 
4395  case CastRelationId:
4396  appendStringInfoString(&buffer, "cast");
4397  break;
4398 
4399  case CollationRelationId:
4400  appendStringInfoString(&buffer, "collation");
4401  break;
4402 
4403  case ConstraintRelationId:
4404  getConstraintTypeDescription(&buffer, object->objectId,
4405  missing_ok);
4406  break;
4407 
4408  case ConversionRelationId:
4409  appendStringInfoString(&buffer, "conversion");
4410  break;
4411 
4412  case AttrDefaultRelationId:
4413  appendStringInfoString(&buffer, "default value");
4414  break;
4415 
4416  case LanguageRelationId:
4417  appendStringInfoString(&buffer, "language");
4418  break;
4419 
4420  case LargeObjectRelationId:
4421  appendStringInfoString(&buffer, "large object");
4422  break;
4423 
4424  case OperatorRelationId:
4425  appendStringInfoString(&buffer, "operator");
4426  break;
4427 
4428  case OperatorClassRelationId:
4429  appendStringInfoString(&buffer, "operator class");
4430  break;
4431 
4432  case OperatorFamilyRelationId:
4433  appendStringInfoString(&buffer, "operator family");
4434  break;
4435 
4436  case AccessMethodRelationId:
4437  appendStringInfoString(&buffer, "access method");
4438  break;
4439 
4440  case AccessMethodOperatorRelationId:
4441  appendStringInfoString(&buffer, "operator of access method");
4442  break;
4443 
4444  case AccessMethodProcedureRelationId:
4445  appendStringInfoString(&buffer, "function of access method");
4446  break;
4447 
4448  case RewriteRelationId:
4449  appendStringInfoString(&buffer, "rule");
4450  break;
4451 
4452  case TriggerRelationId:
4453  appendStringInfoString(&buffer, "trigger");
4454  break;
4455 
4456  case NamespaceRelationId:
4457  appendStringInfoString(&buffer, "schema");
4458  break;
4459 
4460  case StatisticExtRelationId:
4461  appendStringInfoString(&buffer, "statistics object");
4462  break;
4463 
4464  case TSParserRelationId:
4465  appendStringInfoString(&buffer, "text search parser");
4466  break;
4467 
4468  case TSDictionaryRelationId:
4469  appendStringInfoString(&buffer, "text search dictionary");
4470  break;
4471 
4472  case TSTemplateRelationId:
4473  appendStringInfoString(&buffer, "text search template");
4474  break;
4475 
4476  case TSConfigRelationId:
4477  appendStringInfoString(&buffer, "text search configuration");
4478  break;
4479 
4480  case AuthIdRelationId:
4481  appendStringInfoString(&buffer, "role");
4482  break;
4483 
4484  case AuthMemRelationId:
4485  appendStringInfoString(&buffer, "role membership");
4486  break;
4487 
4488  case DatabaseRelationId:
4489  appendStringInfoString(&buffer, "database");
4490  break;
4491 
4492  case TableSpaceRelationId:
4493  appendStringInfoString(&buffer, "tablespace");
4494  break;
4495 
4496  case ForeignDataWrapperRelationId:
4497  appendStringInfoString(&buffer, "foreign-data wrapper");
4498  break;
4499 
4500  case ForeignServerRelationId:
4501  appendStringInfoString(&buffer, "server");
4502  break;
4503 
4504  case UserMappingRelationId:
4505  appendStringInfoString(&buffer, "user mapping");
4506  break;
4507 
4508  case DefaultAclRelationId:
4509  appendStringInfoString(&buffer, "default acl");
4510  break;
4511 
4512  case ExtensionRelationId:
4513  appendStringInfoString(&buffer, "extension");
4514  break;
4515 
4516  case EventTriggerRelationId:
4517  appendStringInfoString(&buffer, "event trigger");
4518  break;
4519 
4520  case ParameterAclRelationId:
4521  appendStringInfoString(&buffer, "parameter ACL");
4522  break;
4523 
4524  case PolicyRelationId:
4525  appendStringInfoString(&buffer, "policy");
4526  break;
4527 
4528  case PublicationRelationId:
4529  appendStringInfoString(&buffer, "publication");
4530  break;
4531 
4532  case PublicationNamespaceRelationId:
4533  appendStringInfoString(&buffer, "publication namespace");
4534  break;
4535 
4536  case PublicationRelRelationId:
4537  appendStringInfoString(&buffer, "publication relation");
4538  break;
4539 
4540  case SubscriptionRelationId:
4541  appendStringInfoString(&buffer, "subscription");
4542  break;
4543 
4544  case TransformRelationId:
4545  appendStringInfoString(&buffer, "transform");
4546  break;
4547 
4548  default:
4549  elog(ERROR, "unsupported object class: %u", object->classId);
4550  }
4551 
4552  /* the result can never be empty */
4553  Assert(buffer.len > 0);
4554 
4555  return buffer.data;
4556 }
static void getConstraintTypeDescription(StringInfo buffer, Oid constroid, bool missing_ok)
static void getProcedureTypeDescription(StringInfo buffer, Oid procid, bool missing_ok)
static void getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId, bool missing_ok)

References appendStringInfoString(), Assert, ObjectAddress::classId, StringInfoData::data, elog, ERROR, getConstraintTypeDescription(), getProcedureTypeDescription(), getRelationTypeDescription(), initStringInfo(), StringInfoData::len, ObjectAddress::objectId, and ObjectAddress::objectSubId.

Referenced by EventTriggerSQLDropAddObject(), pg_event_trigger_ddl_commands(), pg_identify_object(), pg_identify_object_as_address(), and sepgsql_object_relabel().

◆ is_objectclass_supported()

bool is_objectclass_supported ( Oid  class_id)

Definition at line 2729 of file objectaddress.c.

2730 {
2731  int index;
2732 
2733  for (index = 0; index < lengthof(ObjectProperty); index++)
2734  {
2735  if (ObjectProperty[index].class_oid == class_id)
2736  return true;
2737  }
2738 
2739  return false;
2740 }
#define lengthof(array)
Definition: c.h:788
static const ObjectPropertyType ObjectProperty[]
Definition: type.h:95

References lengthof, and ObjectProperty.

Referenced by EventTriggerSQLDropAddObject(), pg_event_trigger_ddl_commands(), and pg_identify_object().

◆ read_objtype_from_string()

int read_objtype_from_string ( const char *  objtype)

Definition at line 2600 of file objectaddress.c.

2601 {
2602  int i;
2603 
2604  for (i = 0; i < lengthof(ObjectTypeMap); i++)
2605  {
2606  if (strcmp(ObjectTypeMap[i].tm_name, objtype) == 0)
2607  return ObjectTypeMap[i].tm_type;
2608  }
2609  ereport(ERROR,
2610  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2611  errmsg("unrecognized object type \"%s\"", objtype)));
2612 
2613  return -1; /* keep compiler quiet */
2614 }
int i
Definition: isn.c:73
static const struct object_type_map ObjectTypeMap[]

References ereport, errcode(), errmsg(), ERROR, i, lengthof, and ObjectTypeMap.

Referenced by pg_get_object_address().

◆ strlist_to_textarray()

struct ArrayType* strlist_to_textarray ( List list)

Definition at line 6002 of file objectaddress.c.

6003 {
6004  ArrayType *arr;
6005  Datum *datums;
6006  bool *nulls;
6007  int j = 0;
6008  ListCell *cell;
6009  MemoryContext memcxt;
6010  MemoryContext oldcxt;
6011  int lb[1];
6012 
6013  /* Work in a temp context; easier than individually pfree'ing the Datums */
6015  "strlist to array",
6017  oldcxt = MemoryContextSwitchTo(memcxt);
6018 
6019  datums = (Datum *) palloc(sizeof(Datum) * list_length(list));
6020  nulls = palloc(sizeof(bool) * list_length(list));
6021 
6022  foreach(cell, list)
6023  {
6024  char *name = lfirst(cell);
6025 
6026  if (name)
6027  {
6028  nulls[j] = false;
6029  datums[j++] = CStringGetTextDatum(name);
6030  }
6031  else
6032  nulls[j] = true;
6033  }
6034 
6035  MemoryContextSwitchTo(oldcxt);
6036 
6037  lb[0] = 1;
6038  arr = construct_md_array(datums, nulls, 1, &j,
6039  lb, TEXTOID, -1, false, TYPALIGN_INT);
6040 
6041  MemoryContextDelete(memcxt);
6042 
6043  return arr;
6044 }
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3475
#define CStringGetTextDatum(s)
Definition: builtins.h:97
int j
Definition: isn.c:74
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void * palloc(Size size)
Definition: mcxt.c:1316
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
MemoryContextSwitchTo(old_ctx)
const char * name

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, construct_md_array(), CStringGetTextDatum, CurrentMemoryContext, j, lfirst, sort-test::list, list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), name, and palloc().

Referenced by fill_hba_line(), pg_event_trigger_dropped_objects(), and pg_identify_object_as_address().

Variable Documentation

◆ InvalidObjectAddress