PostgreSQL Source Code  git master
objectaddress.h File Reference
#include "nodes/pg_list.h"
#include "storage/lockdefs.h"
#include "utils/acl.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)
 
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_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, Oid objectId)
 
char * getObjectDescription (const ObjectAddress *object)
 
char * getObjectDescriptionOids (Oid classid, Oid objid)
 
int read_objtype_from_string (const char *objtype)
 
char * getObjectTypeDescription (const ObjectAddress *object)
 
char * getObjectIdentity (const ObjectAddress *address)
 
char * getObjectIdentityParts (const ObjectAddress *address, List **objname, List **objargs)
 
ArrayTypestrlist_to_textarray (List *list)
 
ObjectType get_relkind_objtype (char relkind)
 

Variables

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.

Referenced by AlterCollation(), AlterDatabaseOwner(), AlterDomainAddConstraint(), AlterDomainDefault(), AlterDomainDropConstraint(), AlterDomainNotNull(), AlterDomainValidateConstraint(), AlterEnum(), AlterEventTriggerOwner(), AlterExtensionNamespace(), AlterForeignDataWrapper(), AlterForeignDataWrapperOwner(), AlterForeignServer(), AlterForeignServerOwner(), AlterFunction(), AlterPublicationOptions(), AlterPublicationOwner(), AlterSchemaOwner(), AlterSequence(), AlterSubscription(), AlterSubscriptionOwner(), AlterTableNamespace(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeNamespace(), AlterTypeOwner(), AlterUserMapping(), ATAddCheckConstraint(), ATAddForeignKeyConstraint(), ATExecAddInherit(), ATExecAlterConstraint(), ATExecAttachPartition(), ATExecAttachPartitionIdx(), ATExecClusterOn(), ATExecDetachPartition(), ATExecDropInherit(), ATExecValidateConstraint(), CloneForeignKeyConstraints(), ConstraintSetParentConstraint(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTrigger(), DefineCollation(), DefineIndex(), DefineQueryRewrite(), DefineRelation(), DefineTSConfiguration(), DefineVirtualRelation(), domainAddConstraint(), DropSubscription(), EventTriggerCollectAlterOpFam(), EventTriggerCollectAlterTSConfig(), EventTriggerCollectCreateOpClass(), ExecAlterExtensionStmt(), ExecAlterObjectSchemaStmt(), ExecRefreshMatView(), get_object_address_defacl(), get_object_address_opf_member(), get_object_address_publication_rel(), get_object_address_usermapping(), index_constraint_create(), IndexSetParentIndex(), pg_event_trigger_ddl_commands(), publication_add_relation(), PublicationDropTables(), rename_constraint_internal(), rename_policy(), RenameDatabase(), RenameRelation(), RenameRewriteRule(), RenameRole(), RenameSchema(), RenameTableSpace(), renametrig(), RenameType(), SetFunctionArgType(), SetFunctionReturnType(), TypeCreate(), and TypeShellMake().

◆ 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.

Referenced by ATExecAddColumn(), ATExecAddIdentity(), ATExecAlterColumnGenericOptions(), ATExecAlterColumnType(), ATExecColumnDefault(), ATExecDropIdentity(), ATExecDropNotNull(), ATExecSetIdentity(), ATExecSetNotNull(), ATExecSetOptions(), ATExecSetStatistics(), ATExecSetStorage(), CreateStatistics(), and renameatt().

Typedef Documentation

◆ ObjectAddress

Function Documentation

◆ check_object_ownership()

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

Definition at line 2230 of file objectaddress.c.

References aclcheck_error(), aclcheck_error_type(), ACLCHECK_NOT_OWNER, castNode, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), has_createrole_privilege(), linitial_node, lo_compat_privileges, lsecond_node, NameListToString(), OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, 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_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, 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_VIEW, ObjectAddress::objectId, pg_class_ownercheck(), pg_collation_ownercheck(), pg_conversion_ownercheck(), pg_database_ownercheck(), pg_event_trigger_ownercheck(), pg_extension_ownercheck(), pg_foreign_data_wrapper_ownercheck(), pg_foreign_server_ownercheck(), pg_language_ownercheck(), pg_largeobject_ownercheck(), pg_namespace_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_publication_ownercheck(), pg_statistics_object_ownercheck(), pg_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), RelationGetRelationName, RelationGetRelid, strVal, superuser_arg(), and typenameTypeId().

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

2232 {
2233  switch (objtype)
2234  {
2235  case OBJECT_INDEX:
2236  case OBJECT_SEQUENCE:
2237  case OBJECT_TABLE:
2238  case OBJECT_VIEW:
2239  case OBJECT_MATVIEW:
2240  case OBJECT_FOREIGN_TABLE:
2241  case OBJECT_COLUMN:
2242  case OBJECT_RULE:
2243  case OBJECT_TRIGGER:
2244  case OBJECT_POLICY:
2245  case OBJECT_TABCONSTRAINT:
2246  if (!pg_class_ownercheck(RelationGetRelid(relation), roleid))
2248  RelationGetRelationName(relation));
2249  break;
2250  case OBJECT_DATABASE:
2251  if (!pg_database_ownercheck(address.objectId, roleid))
2253  strVal((Value *) object));
2254  break;
2255  case OBJECT_TYPE:
2256  case OBJECT_DOMAIN:
2257  case OBJECT_ATTRIBUTE:
2258  case OBJECT_DOMCONSTRAINT:
2259  if (!pg_type_ownercheck(address.objectId, roleid))
2261  break;
2262  case OBJECT_AGGREGATE:
2263  case OBJECT_FUNCTION:
2264  case OBJECT_PROCEDURE:
2265  case OBJECT_ROUTINE:
2266  if (!pg_proc_ownercheck(address.objectId, roleid))
2268  NameListToString((castNode(ObjectWithArgs, object))->objname));
2269  break;
2270  case OBJECT_OPERATOR:
2271  if (!pg_oper_ownercheck(address.objectId, roleid))
2273  NameListToString((castNode(ObjectWithArgs, object))->objname));
2274  break;
2275  case OBJECT_SCHEMA:
2276  if (!pg_namespace_ownercheck(address.objectId, roleid))
2278  strVal((Value *) object));
2279  break;
2280  case OBJECT_COLLATION:
2281  if (!pg_collation_ownercheck(address.objectId, roleid))
2283  NameListToString(castNode(List, object)));
2284  break;
2285  case OBJECT_CONVERSION:
2286  if (!pg_conversion_ownercheck(address.objectId, roleid))
2288  NameListToString(castNode(List, object)));
2289  break;
2290  case OBJECT_EXTENSION:
2291  if (!pg_extension_ownercheck(address.objectId, roleid))
2293  strVal((Value *) object));
2294  break;
2295  case OBJECT_FDW:
2296  if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid))
2298  strVal((Value *) object));
2299  break;
2300  case OBJECT_FOREIGN_SERVER:
2301  if (!pg_foreign_server_ownercheck(address.objectId, roleid))
2303  strVal((Value *) object));
2304  break;
2305  case OBJECT_EVENT_TRIGGER:
2306  if (!pg_event_trigger_ownercheck(address.objectId, roleid))
2308  strVal((Value *) object));
2309  break;
2310  case OBJECT_LANGUAGE:
2311  if (!pg_language_ownercheck(address.objectId, roleid))
2313  strVal((Value *) object));
2314  break;
2315  case OBJECT_OPCLASS:
2316  if (!pg_opclass_ownercheck(address.objectId, roleid))
2318  NameListToString(castNode(List, object)));
2319  break;
2320  case OBJECT_OPFAMILY:
2321  if (!pg_opfamily_ownercheck(address.objectId, roleid))
2323  NameListToString(castNode(List, object)));
2324  break;
2325  case OBJECT_LARGEOBJECT:
2326  if (!lo_compat_privileges &&
2327  !pg_largeobject_ownercheck(address.objectId, roleid))
2328  ereport(ERROR,
2329  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2330  errmsg("must be owner of large object %u",
2331  address.objectId)));
2332  break;
2333  case OBJECT_CAST:
2334  {
2335  /* We can only check permissions on the source/target types */
2336  TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
2337  TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
2338  Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
2339  Oid targettypeid = typenameTypeId(NULL, targettype);
2340 
2341  if (!pg_type_ownercheck(sourcetypeid, roleid)
2342  && !pg_type_ownercheck(targettypeid, roleid))
2343  ereport(ERROR,
2344  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2345  errmsg("must be owner of type %s or type %s",
2346  format_type_be(sourcetypeid),
2347  format_type_be(targettypeid))));
2348  }
2349  break;
2350  case OBJECT_PUBLICATION:
2351  if (!pg_publication_ownercheck(address.objectId, roleid))
2353  strVal((Value *) object));
2354  break;
2355  case OBJECT_SUBSCRIPTION:
2356  if (!pg_subscription_ownercheck(address.objectId, roleid))
2358  strVal((Value *) object));
2359  break;
2360  case OBJECT_TRANSFORM:
2361  {
2362  TypeName *typename = linitial_node(TypeName, castNode(List, object));
2363  Oid typeid = typenameTypeId(NULL, typename);
2364 
2365  if (!pg_type_ownercheck(typeid, roleid))
2367  }
2368  break;
2369  case OBJECT_TABLESPACE:
2370  if (!pg_tablespace_ownercheck(address.objectId, roleid))
2372  strVal((Value *) object));
2373  break;
2374  case OBJECT_TSDICTIONARY:
2375  if (!pg_ts_dict_ownercheck(address.objectId, roleid))
2377  NameListToString(castNode(List, object)));
2378  break;
2380  if (!pg_ts_config_ownercheck(address.objectId, roleid))
2382  NameListToString(castNode(List, object)));
2383  break;
2384  case OBJECT_ROLE:
2385 
2386  /*
2387  * We treat roles as being "owned" by those with CREATEROLE priv,
2388  * except that superusers are only owned by superusers.
2389  */
2390  if (superuser_arg(address.objectId))
2391  {
2392  if (!superuser_arg(roleid))
2393  ereport(ERROR,
2394  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2395  errmsg("must be superuser")));
2396  }
2397  else
2398  {
2399  if (!has_createrole_privilege(roleid))
2400  ereport(ERROR,
2401  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2402  errmsg("must have CREATEROLE privilege")));
2403  }
2404  break;
2405  case OBJECT_TSPARSER:
2406  case OBJECT_TSTEMPLATE:
2407  case OBJECT_ACCESS_METHOD:
2408  /* We treat these object types as being owned by superusers */
2409  if (!superuser_arg(roleid))
2410  ereport(ERROR,
2411  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2412  errmsg("must be superuser")));
2413  break;
2414  case OBJECT_STATISTIC_EXT:
2415  if (!pg_statistics_object_ownercheck(address.objectId, roleid))
2417  break;
2418  default:
2419  elog(ERROR, "unrecognized object type: %d",
2420  (int) objtype);
2421  }
2422 }
bool has_createrole_privilege(Oid roleid)
Definition: aclchk.c:5376
bool pg_collation_ownercheck(Oid coll_oid, Oid roleid)
Definition: aclchk.c:5195
bool lo_compat_privileges
Definition: inv_api.c:57
bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
Definition: aclchk.c:4884
bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid)
Definition: aclchk.c:5034
bool pg_language_ownercheck(Oid lan_oid, Oid roleid)
Definition: aclchk.c:4855
#define castNode(_type_, nodeptr)
Definition: nodes.h:585
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:5061
bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid)
Definition: aclchk.c:5115
bool pg_publication_ownercheck(Oid pub_oid, Oid roleid)
Definition: aclchk.c:5289
#define strVal(v)
Definition: value.h:54
bool pg_oper_ownercheck(Oid oper_oid, Oid roleid)
Definition: aclchk.c:4803
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:328
bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
Definition: aclchk.c:4927
unsigned int Oid
Definition: postgres_ext.h:31
bool pg_type_ownercheck(Oid type_oid, Oid roleid)
Definition: aclchk.c:4777
#define linitial_node(type, l)
Definition: pg_list.h:114
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3662
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3349
#define ERROR
Definition: elog.h:43
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:5142
bool pg_extension_ownercheck(Oid ext_oid, Oid roleid)
Definition: aclchk.c:5247
#define RelationGetRelationName(relation)
Definition: rel.h:441
bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
Definition: aclchk.c:4953
bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid)
Definition: aclchk.c:5007
#define ereport(elevel, rest)
Definition: elog.h:122
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:5169
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
char * NameListToString(List *names)
Definition: namespace.c:3082
#define lsecond_node(type, l)
Definition: pg_list.h:119
bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
Definition: aclchk.c:4980
bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid)
Definition: aclchk.c:5221
Definition: value.h:42
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4751
bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid)
Definition: aclchk.c:5088
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:407
bool pg_proc_ownercheck(Oid proc_oid, Oid roleid)
Definition: aclchk.c:4829
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
bool pg_subscription_ownercheck(Oid sub_oid, Oid roleid)
Definition: aclchk.c:5315
bool pg_statistics_object_ownercheck(Oid stat_oid, Oid roleid)
Definition: aclchk.c:5341

◆ get_catalog_object_by_oid()

HeapTuple get_catalog_object_by_oid ( Relation  catalog,
Oid  objectId 
)

Definition at line 2628 of file objectaddress.c.

References Assert, BTEqualStrategyNumber, get_object_catcache_oid(), get_object_oid_index(), heap_copytuple(), HeapTupleIsValid, ObjectIdAttributeNumber, 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().

2629 {
2630  HeapTuple tuple;
2631  Oid classId = RelationGetRelid(catalog);
2632  int oidCacheId = get_object_catcache_oid(classId);
2633 
2634  if (oidCacheId > 0)
2635  {
2636  tuple = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId));
2637  if (!HeapTupleIsValid(tuple)) /* should not happen */
2638  return NULL;
2639  }
2640  else
2641  {
2642  Oid oidIndexId = get_object_oid_index(classId);
2643  SysScanDesc scan;
2644  ScanKeyData skey;
2645 
2646  Assert(OidIsValid(oidIndexId));
2647 
2648  ScanKeyInit(&skey,
2650  BTEqualStrategyNumber, F_OIDEQ,
2651  ObjectIdGetDatum(objectId));
2652 
2653  scan = systable_beginscan(catalog, oidIndexId, true,
2654  NULL, 1, &skey);
2655  tuple = systable_getnext(scan);
2656  if (!HeapTupleIsValid(tuple))
2657  {
2658  systable_endscan(scan);
2659  return NULL;
2660  }
2661  tuple = heap_copytuple(tuple);
2662 
2663  systable_endscan(scan);
2664  }
2665 
2666  return tuple;
2667 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
Oid get_object_oid_index(Oid class_id)
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
int get_object_catcache_oid(Oid class_id)
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:699
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define RelationGetRelid(relation)
Definition: rel.h:407
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_object_address()

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

Definition at line 797 of file objectaddress.c.

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_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_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_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, 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().

799 {
800  ObjectAddress address;
801  ObjectAddress old_address = {InvalidOid, InvalidOid, 0};
802  Relation relation = NULL;
803  uint64 inval_count;
804 
805  /* Some kind of lock must be taken. */
806  Assert(lockmode != NoLock);
807 
808  for (;;)
809  {
810  /*
811  * Remember this value, so that, after looking up the object name and
812  * locking it, we can check whether any invalidation messages have
813  * been processed that might require a do-over.
814  */
815  inval_count = SharedInvalidMessageCounter;
816 
817  /* Look up object address. */
818  switch (objtype)
819  {
820  case OBJECT_INDEX:
821  case OBJECT_SEQUENCE:
822  case OBJECT_TABLE:
823  case OBJECT_VIEW:
824  case OBJECT_MATVIEW:
826  address =
827  get_relation_by_qualified_name(objtype, castNode(List, object),
828  &relation, lockmode,
829  missing_ok);
830  break;
831  case OBJECT_COLUMN:
832  address =
833  get_object_address_attribute(objtype, castNode(List, object),
834  &relation, lockmode,
835  missing_ok);
836  break;
837  case OBJECT_DEFAULT:
838  address =
839  get_object_address_attrdef(objtype, castNode(List, object),
840  &relation, lockmode,
841  missing_ok);
842  break;
843  case OBJECT_RULE:
844  case OBJECT_TRIGGER:
846  case OBJECT_POLICY:
847  address = get_object_address_relobject(objtype, castNode(List, object),
848  &relation, missing_ok);
849  break;
851  {
852  List *objlist;
853  ObjectAddress domaddr;
854  char *constrname;
855 
856  objlist = castNode(List, object);
858  linitial_node(TypeName, objlist),
859  missing_ok);
860  constrname = strVal(lsecond(objlist));
861 
862  address.classId = ConstraintRelationId;
863  address.objectId = get_domain_constraint_oid(domaddr.objectId,
864  constrname, missing_ok);
865  address.objectSubId = 0;
866 
867  }
868  break;
869  case OBJECT_DATABASE:
870  case OBJECT_EXTENSION:
871  case OBJECT_TABLESPACE:
872  case OBJECT_ROLE:
873  case OBJECT_SCHEMA:
874  case OBJECT_LANGUAGE:
875  case OBJECT_FDW:
879  case OBJECT_PUBLICATION:
880  case OBJECT_SUBSCRIPTION:
881  address = get_object_address_unqualified(objtype,
882  (Value *) object, missing_ok);
883  break;
884  case OBJECT_TYPE:
885  case OBJECT_DOMAIN:
886  address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
887  break;
888  case OBJECT_AGGREGATE:
889  case OBJECT_FUNCTION:
890  case OBJECT_PROCEDURE:
891  case OBJECT_ROUTINE:
892  address.classId = ProcedureRelationId;
893  address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
894  address.objectSubId = 0;
895  break;
896  case OBJECT_OPERATOR:
897  address.classId = OperatorRelationId;
898  address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
899  address.objectSubId = 0;
900  break;
901  case OBJECT_COLLATION:
902  address.classId = CollationRelationId;
903  address.objectId = get_collation_oid(castNode(List, object), missing_ok);
904  address.objectSubId = 0;
905  break;
906  case OBJECT_CONVERSION:
907  address.classId = ConversionRelationId;
908  address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
909  address.objectSubId = 0;
910  break;
911  case OBJECT_OPCLASS:
912  case OBJECT_OPFAMILY:
913  address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
914  break;
915  case OBJECT_AMOP:
916  case OBJECT_AMPROC:
917  address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
918  break;
919  case OBJECT_LARGEOBJECT:
920  address.classId = LargeObjectRelationId;
921  address.objectId = oidparse(object);
922  address.objectSubId = 0;
923  if (!LargeObjectExists(address.objectId))
924  {
925  if (!missing_ok)
926  ereport(ERROR,
927  (errcode(ERRCODE_UNDEFINED_OBJECT),
928  errmsg("large object %u does not exist",
929  address.objectId)));
930  }
931  break;
932  case OBJECT_CAST:
933  {
934  TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
935  TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
936  Oid sourcetypeid;
937  Oid targettypeid;
938 
939  sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
940  targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
941  address.classId = CastRelationId;
942  address.objectId =
943  get_cast_oid(sourcetypeid, targettypeid, missing_ok);
944  address.objectSubId = 0;
945  }
946  break;
947  case OBJECT_TRANSFORM:
948  {
949  TypeName *typename = linitial_node(TypeName, castNode(List, object));
950  char *langname = strVal(lsecond(castNode(List, object)));
951  Oid type_id = LookupTypeNameOid(NULL, typename, missing_ok);
952  Oid lang_id = get_language_oid(langname, missing_ok);
953 
954  address.classId = TransformRelationId;
955  address.objectId =
956  get_transform_oid(type_id, lang_id, missing_ok);
957  address.objectSubId = 0;
958  }
959  break;
960  case OBJECT_TSPARSER:
961  address.classId = TSParserRelationId;
962  address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
963  address.objectSubId = 0;
964  break;
965  case OBJECT_TSDICTIONARY:
966  address.classId = TSDictionaryRelationId;
967  address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
968  address.objectSubId = 0;
969  break;
970  case OBJECT_TSTEMPLATE:
971  address.classId = TSTemplateRelationId;
972  address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
973  address.objectSubId = 0;
974  break;
976  address.classId = TSConfigRelationId;
977  address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
978  address.objectSubId = 0;
979  break;
980  case OBJECT_USER_MAPPING:
981  address = get_object_address_usermapping(castNode(List, object),
982  missing_ok);
983  break;
986  &relation,
987  missing_ok);
988  break;
989  case OBJECT_DEFACL:
990  address = get_object_address_defacl(castNode(List, object),
991  missing_ok);
992  break;
994  address.classId = StatisticExtRelationId;
995  address.objectId = get_statistics_object_oid(castNode(List, object),
996  missing_ok);
997  address.objectSubId = 0;
998  break;
999  default:
1000  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1001  /* placate compiler, in case it thinks elog might return */
1002  address.classId = InvalidOid;
1003  address.objectId = InvalidOid;
1004  address.objectSubId = 0;
1005  }
1006 
1007  /*
1008  * If we could not find the supplied object, return without locking.
1009  */
1010  if (!OidIsValid(address.objectId))
1011  {
1012  Assert(missing_ok);
1013  return address;
1014  }
1015 
1016  /*
1017  * If we're retrying, see if we got the same answer as last time. If
1018  * so, we're done; if not, we locked the wrong thing, so give up our
1019  * lock.
1020  */
1021  if (OidIsValid(old_address.classId))
1022  {
1023  if (old_address.classId == address.classId
1024  && old_address.objectId == address.objectId
1025  && old_address.objectSubId == address.objectSubId)
1026  break;
1027  if (old_address.classId != RelationRelationId)
1028  {
1029  if (IsSharedRelation(old_address.classId))
1030  UnlockSharedObject(old_address.classId,
1031  old_address.objectId,
1032  0, lockmode);
1033  else
1034  UnlockDatabaseObject(old_address.classId,
1035  old_address.objectId,
1036  0, lockmode);
1037  }
1038  }
1039 
1040  /*
1041  * If we're dealing with a relation or attribute, then the relation is
1042  * already locked. Otherwise, we lock it now.
1043  */
1044  if (address.classId != RelationRelationId)
1045  {
1046  if (IsSharedRelation(address.classId))
1047  LockSharedObject(address.classId, address.objectId, 0,
1048  lockmode);
1049  else
1050  LockDatabaseObject(address.classId, address.objectId, 0,
1051  lockmode);
1052  }
1053 
1054  /*
1055  * At this point, we've resolved the name to an OID and locked the
1056  * corresponding database object. However, it's possible that by the
1057  * time we acquire the lock on the object, concurrent DDL has modified
1058  * the database in such a way that the name we originally looked up no
1059  * longer resolves to that OID.
1060  *
1061  * We can be certain that this isn't an issue if (a) no shared
1062  * invalidation messages have been processed or (b) we've locked a
1063  * relation somewhere along the line. All the relation name lookups
1064  * in this module ultimately use RangeVarGetRelid() to acquire a
1065  * relation lock, and that function protects against the same kinds of
1066  * races we're worried about here. Even when operating on a
1067  * constraint, rule, or trigger, we still acquire AccessShareLock on
1068  * the relation, which is enough to freeze out any concurrent DDL.
1069  *
1070  * In all other cases, however, it's possible that the name we looked
1071  * up no longer refers to the object we locked, so we retry the lookup
1072  * and see whether we get the same answer.
1073  */
1074  if (inval_count == SharedInvalidMessageCounter || relation != NULL)
1075  break;
1076  old_address = address;
1077  }
1078 
1079  /* Return the object address and the relation. */
1080  *relp = relation;
1081  return address;
1082 }
Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
Definition: parse_oper.c:140
static ObjectAddress get_object_address_usermapping(List *object, bool missing_ok)
static ObjectAddress get_object_address_publication_rel(List *object, Relation *relp, bool missing_ok)
Oid oidparse(Node *node)
Definition: oid.c:314
static ObjectAddress get_object_address_attribute(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define castNode(_type_, nodeptr)
Definition: nodes.h:585
Oid get_language_oid(const char *langname, bool missing_ok)
Definition: proclang.c:549
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2658
unsigned int Oid
Definition: postgres_ext.h:31
#define linitial_node(type, l)
Definition: pg_list.h:114
static ObjectAddress get_object_address_unqualified(ObjectType objtype, Value *strval, bool missing_ok)
#define OidIsValid(objectId)
Definition: c.h:605
#define lsecond(l)
Definition: pg_list.h:116
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 get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2405
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
#define ERROR
Definition: elog.h:43
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:918
Oid get_statistics_object_oid(List *names, bool missing_ok)
Definition: namespace.c:2157
Oid get_ts_template_oid(List *names, bool missing_ok)
Definition: namespace.c:2532
#define NoLock
Definition: lockdefs.h:34
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError)
Definition: parse_func.c:2086
static ObjectAddress get_object_address_relobject(ObjectType objtype, List *object, Relation *relp, bool missing_ok)
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:856
static ObjectAddress get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
static ObjectAddress get_object_address_defacl(List *object, bool missing_ok)
#define ereport(elevel, rest)
Definition: elog.h:122
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:877
#define lsecond_node(type, l)
Definition: pg_list.h:119
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:220
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:897
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
Oid get_ts_parser_oid(List *names, bool missing_ok)
Definition: namespace.c:2279
#define Assert(condition)
Definition: c.h:699
Definition: value.h:42
static ObjectAddress get_object_address_opf_member(ObjectType objtype, List *object, bool missing_ok)
Oid get_conversion_oid(List *name, bool missing_ok)
Definition: namespace.c:3566
bool LargeObjectExists(Oid loid)
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
#define elog
Definition: elog.h:219
Oid get_collation_oid(List *name, bool missing_ok)
Definition: namespace.c:3512
Definition: pg_list.h:45
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition: parse_type.c:215

◆ 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 1092 of file objectaddress.c.

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

Referenced by ExecAlterObjectDependsStmt().

1095 {
1096  if (rel)
1097  {
1098  object = lcons(makeString(rel->relname), object);
1099  if (rel->schemaname)
1100  object = lcons(makeString(rel->schemaname), object);
1101  if (rel->catalogname)
1102  object = lcons(makeString(rel->catalogname), object);
1103  }
1104 
1105  return get_object_address(objtype, (Node *) object,
1106  relp, lockmode, missing_ok);
1107 }
Value * makeString(char *str)
Definition: value.c:53
Definition: nodes.h:516
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
List * lcons(void *datum, List *list)
Definition: list.c:259
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
char * catalogname
Definition: primnodes.h:66

◆ get_object_attnum_acl()

AttrNumber get_object_attnum_acl ( Oid  class_id)

Definition at line 2538 of file objectaddress.c.

References ObjectPropertyType::attnum_acl, and get_object_property_data().

Referenced by AlterObjectOwner_internal().

2539 {
2540  const ObjectPropertyType *prop = get_object_property_data(class_id);
2541 
2542  return prop->attnum_acl;
2543 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)
AttrNumber attnum_acl

◆ get_object_attnum_name()

AttrNumber get_object_attnum_name ( Oid  class_id)

Definition at line 2514 of file objectaddress.c.

References ObjectPropertyType::attnum_name, and get_object_property_data().

Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), EventTriggerSQLDropAddObject(), and pg_identify_object().

2515 {
2516  const ObjectPropertyType *prop = get_object_property_data(class_id);
2517 
2518  return prop->attnum_name;
2519 }
AttrNumber attnum_name
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_attnum_namespace()

AttrNumber get_object_attnum_namespace ( Oid  class_id)

Definition at line 2522 of file objectaddress.c.

References ObjectPropertyType::attnum_namespace, and get_object_property_data().

Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), EventTriggerSQLDropAddObject(), pg_event_trigger_ddl_commands(), and pg_identify_object().

2523 {
2524  const ObjectPropertyType *prop = get_object_property_data(class_id);
2525 
2526  return prop->attnum_namespace;
2527 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)
AttrNumber attnum_namespace

◆ get_object_attnum_owner()

AttrNumber get_object_attnum_owner ( Oid  class_id)

Definition at line 2530 of file objectaddress.c.

References ObjectPropertyType::attnum_owner, and get_object_property_data().

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

2531 {
2532  const ObjectPropertyType *prop = get_object_property_data(class_id);
2533 
2534  return prop->attnum_owner;
2535 }
AttrNumber attnum_owner
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_catcache_name()

int get_object_catcache_name ( Oid  class_id)

Definition at line 2506 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::name_catcache_id.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

2507 {
2508  const ObjectPropertyType *prop = get_object_property_data(class_id);
2509 
2510  return prop->name_catcache_id;
2511 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_catcache_oid()

int get_object_catcache_oid ( Oid  class_id)

Definition at line 2498 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::oid_catcache_id.

Referenced by AlterObjectNamespace_internal(), AlterObjectRename_internal(), and get_catalog_object_by_oid().

2499 {
2500  const ObjectPropertyType *prop = get_object_property_data(class_id);
2501 
2502  return prop->oid_catcache_id;
2503 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_namensp_unique()

bool get_object_namensp_unique ( Oid  class_id)

Definition at line 2564 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::is_nsp_name_unique.

Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().

2565 {
2566  const ObjectPropertyType *prop = get_object_property_data(class_id);
2567 
2568  return prop->is_nsp_name_unique;
2569 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_namespace()

Oid get_object_namespace ( const ObjectAddress address)

Definition at line 2431 of file objectaddress.c.

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

Referenced by RemoveObjects().

2432 {
2433  int cache;
2434  HeapTuple tuple;
2435  bool isnull;
2436  Oid oid;
2437  const ObjectPropertyType *property;
2438 
2439  /* If not owned by a namespace, just return InvalidOid. */
2440  property = get_object_property_data(address->classId);
2441  if (property->attnum_namespace == InvalidAttrNumber)
2442  return InvalidOid;
2443 
2444  /* Currently, we can only handle object types with system caches. */
2445  cache = property->oid_catcache_id;
2446  Assert(cache != -1);
2447 
2448  /* Fetch tuple from syscache and extract namespace attribute. */
2449  tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
2450  if (!HeapTupleIsValid(tuple))
2451  elog(ERROR, "cache lookup failed for cache %d oid %u",
2452  cache, address->objectId);
2453  oid = DatumGetObjectId(SysCacheGetAttr(cache,
2454  tuple,
2455  property->attnum_namespace,
2456  &isnull));
2457  Assert(!isnull);
2458  ReleaseSysCache(tuple);
2459 
2460  return oid;
2461 }
#define DatumGetObjectId(X)
Definition: postgres.h:485
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
static const ObjectPropertyType * get_object_property_data(Oid class_id)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:699
AttrNumber attnum_namespace
#define InvalidAttrNumber
Definition: attnum.h:23
#define elog
Definition: elog.h:219

◆ get_object_oid_index()

Oid get_object_oid_index ( Oid  class_id)

Definition at line 2490 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::oid_index_oid.

Referenced by get_catalog_object_by_oid().

2491 {
2492  const ObjectPropertyType *prop = get_object_property_data(class_id);
2493 
2494  return prop->oid_index_oid;
2495 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_type()

ObjectType get_object_type ( Oid  class_id,
Oid  object_id 
)

Definition at line 2546 of file objectaddress.c.

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

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

2547 {
2548  const ObjectPropertyType *prop = get_object_property_data(class_id);
2549 
2550  if (prop->objtype == OBJECT_TABLE)
2551  {
2552  /*
2553  * If the property data says it's a table, dig a little deeper to get
2554  * the real relation kind, so that callers can produce more precise
2555  * error messages.
2556  */
2557  return get_relkind_objtype(get_rel_relkind(object_id));
2558  }
2559  else
2560  return prop->objtype;
2561 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
static const ObjectPropertyType * get_object_property_data(Oid class_id)
ObjectType get_relkind_objtype(char relkind)

◆ get_relkind_objtype()

ObjectType get_relkind_objtype ( char  relkind)

Definition at line 5243 of file objectaddress.c.

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

Referenced by AlterTableMoveAll(), ATExecChangeOwner(), ATPrepSetStatistics(), ATSimplePermissions(), checkFkeyPermissions(), CreateStatistics(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), DefineQueryRewrite(), EnableDisableRule(), ExecCheckRTPerms(), get_object_type(), get_rel_from_relname(), LockTableRecurse(), LockViewRecurse_walker(), MergeAttributes(), pg_prewarm(), pgrowlocks(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), renameatt_check(), transformTableLikeClause(), and truncate_check_rel().

5244 {
5245  switch (relkind)
5246  {
5247  case RELKIND_RELATION:
5248  case RELKIND_PARTITIONED_TABLE:
5249  return OBJECT_TABLE;
5250  case RELKIND_INDEX:
5251  return OBJECT_INDEX;
5252  case RELKIND_SEQUENCE:
5253  return OBJECT_SEQUENCE;
5254  case RELKIND_VIEW:
5255  return OBJECT_VIEW;
5256  case RELKIND_MATVIEW:
5257  return OBJECT_MATVIEW;
5258  case RELKIND_FOREIGN_TABLE:
5259  return OBJECT_FOREIGN_TABLE;
5260 
5261  /*
5262  * other relkinds are not supported here because they don't map to
5263  * OBJECT_* values
5264  */
5265  default:
5266  elog(ERROR, "unexpected relkind: %d", relkind);
5267  return 0;
5268  }
5269 }
char relkind
Definition: pg_class.h:51
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219

◆ getObjectDescription()

char* getObjectDescription ( const ObjectAddress object)

Definition at line 2675 of file objectaddress.c.

References _, AccessMethodOperatorOidIndexId, AccessMethodProcedureOidIndexId, AccessShareLock, AMOID, appendStringInfo(), Assert, AttrDefaultOidIndexId, BTEqualStrategyNumber, buffer, CastOidIndexId, CLAOID, ObjectAddress::classId, CollationIsVisible(), COLLOID, CONSTROID, ConversionIsVisible(), CONVOID, StringInfoData::data, DefaultAclOidIndexId, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator(), format_procedure(), format_type_be(), get_attname(), get_database_name(), get_extension_name(), get_language_name(), get_namespace_name(), get_publication_name(), get_subscription_name(), get_tablespace_name(), GetForeignDataWrapper(), GetForeignServer(), getObjectClass(), getObjectDescription(), getOpFamilyDescription(), getRelationDescription(), GETSTRUCT, GetUserNameFromId(), heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), NameStr, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectIdGetDatum, ObjectAddress::objectSubId, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, OCLASS_USER_MAPPING, OidIsValid, OpclassIsVisible(), pfree(), PolicyOidIndexId, PUBLICATIONREL, quote_qualified_identifier(), ReleaseSysCache(), RewriteOidIndexId, ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, STATEXTOID, StatisticsObjIsVisible(), systable_beginscan(), systable_endscan(), systable_getnext(), TRFOID, TriggerOidIndexId, TSConfigIsVisible(), TSCONFIGOID, TSDictionaryIsVisible(), TSDICTOID, TSParserIsVisible(), TSPARSEROID, TSTemplateIsVisible(), TSTEMPLATEOID, and USERMAPPINGOID.

Referenced by AlterExtensionNamespace(), ATExecAlterColumnType(), changeDependencyFor(), check_relation_privileges(), checkSharedDependencies(), ExecAlterExtensionContentsStmt(), findDependentObjects(), get_object_address_opf_member(), getObjectDescription(), getObjectDescriptionOids(), pg_describe_object(), recordDependencyOnCurrentExtension(), reportDependentObjects(), sepgsql_fmgr_hook(), shdepDropOwned(), shdepReassignOwned(), and storeObjectDescription().

2676 {
2678 
2679  initStringInfo(&buffer);
2680 
2681  switch (getObjectClass(object))
2682  {
2683  case OCLASS_CLASS:
2684  if (object->objectSubId == 0)
2685  getRelationDescription(&buffer, object->objectId);
2686  else
2687  {
2688  /* column, not whole relation */
2689  StringInfoData rel;
2690 
2691  initStringInfo(&rel);
2692  getRelationDescription(&rel, object->objectId);
2693  /* translator: second %s is, e.g., "table %s" */
2694  appendStringInfo(&buffer, _("column %s of %s"),
2695  get_attname(object->objectId,
2696  object->objectSubId,
2697  false),
2698  rel.data);
2699  pfree(rel.data);
2700  }
2701  break;
2702 
2703  case OCLASS_PROC:
2704  appendStringInfo(&buffer, _("function %s"),
2705  format_procedure(object->objectId));
2706  break;
2707 
2708  case OCLASS_TYPE:
2709  appendStringInfo(&buffer, _("type %s"),
2710  format_type_be(object->objectId));
2711  break;
2712 
2713  case OCLASS_CAST:
2714  {
2715  Relation castDesc;
2716  ScanKeyData skey[1];
2717  SysScanDesc rcscan;
2718  HeapTuple tup;
2719  Form_pg_cast castForm;
2720 
2721  castDesc = heap_open(CastRelationId, AccessShareLock);
2722 
2723  ScanKeyInit(&skey[0],
2725  BTEqualStrategyNumber, F_OIDEQ,
2726  ObjectIdGetDatum(object->objectId));
2727 
2728  rcscan = systable_beginscan(castDesc, CastOidIndexId, true,
2729  NULL, 1, skey);
2730 
2731  tup = systable_getnext(rcscan);
2732 
2733  if (!HeapTupleIsValid(tup))
2734  elog(ERROR, "could not find tuple for cast %u",
2735  object->objectId);
2736 
2737  castForm = (Form_pg_cast) GETSTRUCT(tup);
2738 
2739  appendStringInfo(&buffer, _("cast from %s to %s"),
2740  format_type_be(castForm->castsource),
2741  format_type_be(castForm->casttarget));
2742 
2743  systable_endscan(rcscan);
2744  heap_close(castDesc, AccessShareLock);
2745  break;
2746  }
2747 
2748  case OCLASS_COLLATION:
2749  {
2750  HeapTuple collTup;
2751  Form_pg_collation coll;
2752  char *nspname;
2753 
2754  collTup = SearchSysCache1(COLLOID,
2755  ObjectIdGetDatum(object->objectId));
2756  if (!HeapTupleIsValid(collTup))
2757  elog(ERROR, "cache lookup failed for collation %u",
2758  object->objectId);
2759  coll = (Form_pg_collation) GETSTRUCT(collTup);
2760 
2761  /* Qualify the name if not visible in search path */
2762  if (CollationIsVisible(object->objectId))
2763  nspname = NULL;
2764  else
2765  nspname = get_namespace_name(coll->collnamespace);
2766 
2767  appendStringInfo(&buffer, _("collation %s"),
2769  NameStr(coll->collname)));
2770  ReleaseSysCache(collTup);
2771  break;
2772  }
2773 
2774  case OCLASS_CONSTRAINT:
2775  {
2776  HeapTuple conTup;
2777  Form_pg_constraint con;
2778 
2779  conTup = SearchSysCache1(CONSTROID,
2780  ObjectIdGetDatum(object->objectId));
2781  if (!HeapTupleIsValid(conTup))
2782  elog(ERROR, "cache lookup failed for constraint %u",
2783  object->objectId);
2784  con = (Form_pg_constraint) GETSTRUCT(conTup);
2785 
2786  if (OidIsValid(con->conrelid))
2787  {
2788  StringInfoData rel;
2789 
2790  initStringInfo(&rel);
2791  getRelationDescription(&rel, con->conrelid);
2792  /* translator: second %s is, e.g., "table %s" */
2793  appendStringInfo(&buffer, _("constraint %s on %s"),
2794  NameStr(con->conname), rel.data);
2795  pfree(rel.data);
2796  }
2797  else
2798  {
2799  appendStringInfo(&buffer, _("constraint %s"),
2800  NameStr(con->conname));
2801  }
2802 
2803  ReleaseSysCache(conTup);
2804  break;
2805  }
2806 
2807  case OCLASS_CONVERSION:
2808  {
2809  HeapTuple conTup;
2810  Form_pg_conversion conv;
2811  char *nspname;
2812 
2813  conTup = SearchSysCache1(CONVOID,
2814  ObjectIdGetDatum(object->objectId));
2815  if (!HeapTupleIsValid(conTup))
2816  elog(ERROR, "cache lookup failed for conversion %u",
2817  object->objectId);
2818  conv = (Form_pg_conversion) GETSTRUCT(conTup);
2819 
2820  /* Qualify the name if not visible in search path */
2821  if (ConversionIsVisible(object->objectId))
2822  nspname = NULL;
2823  else
2824  nspname = get_namespace_name(conv->connamespace);
2825 
2826  appendStringInfo(&buffer, _("conversion %s"),
2828  NameStr(conv->conname)));
2829  ReleaseSysCache(conTup);
2830  break;
2831  }
2832 
2833  case OCLASS_DEFAULT:
2834  {
2835  Relation attrdefDesc;
2836  ScanKeyData skey[1];
2837  SysScanDesc adscan;
2838  HeapTuple tup;
2839  Form_pg_attrdef attrdef;
2840  ObjectAddress colobject;
2841 
2842  attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock);
2843 
2844  ScanKeyInit(&skey[0],
2846  BTEqualStrategyNumber, F_OIDEQ,
2847  ObjectIdGetDatum(object->objectId));
2848 
2849  adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId,
2850  true, NULL, 1, skey);
2851 
2852  tup = systable_getnext(adscan);
2853 
2854  if (!HeapTupleIsValid(tup))
2855  elog(ERROR, "could not find tuple for attrdef %u",
2856  object->objectId);
2857 
2858  attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
2859 
2860  colobject.classId = RelationRelationId;
2861  colobject.objectId = attrdef->adrelid;
2862  colobject.objectSubId = attrdef->adnum;
2863 
2864  /* translator: %s is typically "column %s of table %s" */
2865  appendStringInfo(&buffer, _("default value for %s"),
2866  getObjectDescription(&colobject));
2867 
2868  systable_endscan(adscan);
2869  heap_close(attrdefDesc, AccessShareLock);
2870  break;
2871  }
2872 
2873  case OCLASS_LANGUAGE:
2874  appendStringInfo(&buffer, _("language %s"),
2875  get_language_name(object->objectId, false));
2876  break;
2877 
2878  case OCLASS_LARGEOBJECT:
2879  appendStringInfo(&buffer, _("large object %u"),
2880  object->objectId);
2881  break;
2882 
2883  case OCLASS_OPERATOR:
2884  appendStringInfo(&buffer, _("operator %s"),
2885  format_operator(object->objectId));
2886  break;
2887 
2888  case OCLASS_OPCLASS:
2889  {
2890  HeapTuple opcTup;
2891  Form_pg_opclass opcForm;
2892  HeapTuple amTup;
2893  Form_pg_am amForm;
2894  char *nspname;
2895 
2896  opcTup = SearchSysCache1(CLAOID,
2897  ObjectIdGetDatum(object->objectId));
2898  if (!HeapTupleIsValid(opcTup))
2899  elog(ERROR, "cache lookup failed for opclass %u",
2900  object->objectId);
2901  opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
2902 
2903  amTup = SearchSysCache1(AMOID,
2904  ObjectIdGetDatum(opcForm->opcmethod));
2905  if (!HeapTupleIsValid(amTup))
2906  elog(ERROR, "cache lookup failed for access method %u",
2907  opcForm->opcmethod);
2908  amForm = (Form_pg_am) GETSTRUCT(amTup);
2909 
2910  /* Qualify the name if not visible in search path */
2911  if (OpclassIsVisible(object->objectId))
2912  nspname = NULL;
2913  else
2914  nspname = get_namespace_name(opcForm->opcnamespace);
2915 
2916  appendStringInfo(&buffer, _("operator class %s for access method %s"),
2918  NameStr(opcForm->opcname)),
2919  NameStr(amForm->amname));
2920 
2921  ReleaseSysCache(amTup);
2922  ReleaseSysCache(opcTup);
2923  break;
2924  }
2925 
2926  case OCLASS_OPFAMILY:
2927  getOpFamilyDescription(&buffer, object->objectId);
2928  break;
2929 
2930  case OCLASS_AM:
2931  {
2932  HeapTuple tup;
2933 
2934  tup = SearchSysCache1(AMOID,
2935  ObjectIdGetDatum(object->objectId));
2936  if (!HeapTupleIsValid(tup))
2937  elog(ERROR, "cache lookup failed for access method %u",
2938  object->objectId);
2939  appendStringInfo(&buffer, _("access method %s"),
2940  NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
2941  ReleaseSysCache(tup);
2942  break;
2943  }
2944 
2945  case OCLASS_AMOP:
2946  {
2947  Relation amopDesc;
2948  HeapTuple tup;
2949  ScanKeyData skey[1];
2950  SysScanDesc amscan;
2951  Form_pg_amop amopForm;
2952  StringInfoData opfam;
2953 
2954  amopDesc = heap_open(AccessMethodOperatorRelationId,
2955  AccessShareLock);
2956 
2957  ScanKeyInit(&skey[0],
2959  BTEqualStrategyNumber, F_OIDEQ,
2960  ObjectIdGetDatum(object->objectId));
2961 
2962  amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
2963  NULL, 1, skey);
2964 
2965  tup = systable_getnext(amscan);
2966 
2967  if (!HeapTupleIsValid(tup))
2968  elog(ERROR, "could not find tuple for amop entry %u",
2969  object->objectId);
2970 
2971  amopForm = (Form_pg_amop) GETSTRUCT(tup);
2972 
2973  initStringInfo(&opfam);
2974  getOpFamilyDescription(&opfam, amopForm->amopfamily);
2975 
2976  /*------
2977  translator: %d is the operator strategy (a number), the
2978  first two %s's are data type names, the third %s is the
2979  description of the operator family, and the last %s is the
2980  textual form of the operator with arguments. */
2981  appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"),
2982  amopForm->amopstrategy,
2983  format_type_be(amopForm->amoplefttype),
2984  format_type_be(amopForm->amoprighttype),
2985  opfam.data,
2986  format_operator(amopForm->amopopr));
2987 
2988  pfree(opfam.data);
2989 
2990  systable_endscan(amscan);
2991  heap_close(amopDesc, AccessShareLock);
2992  break;
2993  }
2994 
2995  case OCLASS_AMPROC:
2996  {
2997  Relation amprocDesc;
2998  ScanKeyData skey[1];
2999  SysScanDesc amscan;
3000  HeapTuple tup;
3001  Form_pg_amproc amprocForm;
3002  StringInfoData opfam;
3003 
3004  amprocDesc = heap_open(AccessMethodProcedureRelationId,
3005  AccessShareLock);
3006 
3007  ScanKeyInit(&skey[0],
3009  BTEqualStrategyNumber, F_OIDEQ,
3010  ObjectIdGetDatum(object->objectId));
3011 
3012  amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
3013  NULL, 1, skey);
3014 
3015  tup = systable_getnext(amscan);
3016 
3017  if (!HeapTupleIsValid(tup))
3018  elog(ERROR, "could not find tuple for amproc entry %u",
3019  object->objectId);
3020 
3021  amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
3022 
3023  initStringInfo(&opfam);
3024  getOpFamilyDescription(&opfam, amprocForm->amprocfamily);
3025 
3026  /*------
3027  translator: %d is the function number, the first two %s's
3028  are data type names, the third %s is the description of the
3029  operator family, and the last %s is the textual form of the
3030  function with arguments. */
3031  appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"),
3032  amprocForm->amprocnum,
3033  format_type_be(amprocForm->amproclefttype),
3034  format_type_be(amprocForm->amprocrighttype),
3035  opfam.data,
3036  format_procedure(amprocForm->amproc));
3037 
3038  pfree(opfam.data);
3039 
3040  systable_endscan(amscan);
3041  heap_close(amprocDesc, AccessShareLock);
3042  break;
3043  }
3044 
3045  case OCLASS_REWRITE:
3046  {
3047  Relation ruleDesc;
3048  ScanKeyData skey[1];
3049  SysScanDesc rcscan;
3050  HeapTuple tup;
3052  StringInfoData rel;
3053 
3054  ruleDesc = heap_open(RewriteRelationId, AccessShareLock);
3055 
3056  ScanKeyInit(&skey[0],
3058  BTEqualStrategyNumber, F_OIDEQ,
3059  ObjectIdGetDatum(object->objectId));
3060 
3061  rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true,
3062  NULL, 1, skey);
3063 
3064  tup = systable_getnext(rcscan);
3065 
3066  if (!HeapTupleIsValid(tup))
3067  elog(ERROR, "could not find tuple for rule %u",
3068  object->objectId);
3069  rule = (Form_pg_rewrite) GETSTRUCT(tup);
3070 
3071  initStringInfo(&rel);
3072  getRelationDescription(&rel, rule->ev_class);
3073 
3074  /* translator: second %s is, e.g., "table %s" */
3075  appendStringInfo(&buffer, _("rule %s on %s"),
3076  NameStr(rule->rulename), rel.data);
3077  pfree(rel.data);
3078  systable_endscan(rcscan);
3079  heap_close(ruleDesc, AccessShareLock);
3080  break;
3081  }
3082 
3083  case OCLASS_TRIGGER:
3084  {
3085  Relation trigDesc;
3086  ScanKeyData skey[1];
3087  SysScanDesc tgscan;
3088  HeapTuple tup;
3089  Form_pg_trigger trig;
3090  StringInfoData rel;
3091 
3092  trigDesc = heap_open(TriggerRelationId, AccessShareLock);
3093 
3094  ScanKeyInit(&skey[0],
3096  BTEqualStrategyNumber, F_OIDEQ,
3097  ObjectIdGetDatum(object->objectId));
3098 
3099  tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true,
3100  NULL, 1, skey);
3101 
3102  tup = systable_getnext(tgscan);
3103 
3104  if (!HeapTupleIsValid(tup))
3105  elog(ERROR, "could not find tuple for trigger %u",
3106  object->objectId);
3107  trig = (Form_pg_trigger) GETSTRUCT(tup);
3108 
3109  initStringInfo(&rel);
3110  getRelationDescription(&rel, trig->tgrelid);
3111 
3112  /* translator: second %s is, e.g., "table %s" */
3113  appendStringInfo(&buffer, _("trigger %s on %s"),
3114  NameStr(trig->tgname), rel.data);
3115  pfree(rel.data);
3116  systable_endscan(tgscan);
3117  heap_close(trigDesc, AccessShareLock);
3118  break;
3119  }
3120 
3121  case OCLASS_SCHEMA:
3122  {
3123  char *nspname;
3124 
3125  nspname = get_namespace_name(object->objectId);
3126  if (!nspname)
3127  elog(ERROR, "cache lookup failed for namespace %u",
3128  object->objectId);
3129  appendStringInfo(&buffer, _("schema %s"), nspname);
3130  break;
3131  }
3132 
3133  case OCLASS_STATISTIC_EXT:
3134  {
3135  HeapTuple stxTup;
3136  Form_pg_statistic_ext stxForm;
3137  char *nspname;
3138 
3139  stxTup = SearchSysCache1(STATEXTOID,
3140  ObjectIdGetDatum(object->objectId));
3141  if (!HeapTupleIsValid(stxTup))
3142  elog(ERROR, "could not find tuple for statistics object %u",
3143  object->objectId);
3144  stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup);
3145 
3146  /* Qualify the name if not visible in search path */
3147  if (StatisticsObjIsVisible(object->objectId))
3148  nspname = NULL;
3149  else
3150  nspname = get_namespace_name(stxForm->stxnamespace);
3151 
3152  appendStringInfo(&buffer, _("statistics object %s"),
3154  NameStr(stxForm->stxname)));
3155 
3156  ReleaseSysCache(stxTup);
3157  break;
3158  }
3159 
3160  case OCLASS_TSPARSER:
3161  {
3162  HeapTuple tup;
3163  Form_pg_ts_parser prsForm;
3164  char *nspname;
3165 
3167  ObjectIdGetDatum(object->objectId));
3168  if (!HeapTupleIsValid(tup))
3169  elog(ERROR, "cache lookup failed for text search parser %u",
3170  object->objectId);
3171  prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
3172 
3173  /* Qualify the name if not visible in search path */
3174  if (TSParserIsVisible(object->objectId))
3175  nspname = NULL;
3176  else
3177  nspname = get_namespace_name(prsForm->prsnamespace);
3178 
3179  appendStringInfo(&buffer, _("text search parser %s"),
3181  NameStr(prsForm->prsname)));
3182  ReleaseSysCache(tup);
3183  break;
3184  }
3185 
3186  case OCLASS_TSDICT:
3187  {
3188  HeapTuple tup;
3189  Form_pg_ts_dict dictForm;
3190  char *nspname;
3191 
3192  tup = SearchSysCache1(TSDICTOID,
3193  ObjectIdGetDatum(object->objectId));
3194  if (!HeapTupleIsValid(tup))
3195  elog(ERROR, "cache lookup failed for text search dictionary %u",
3196  object->objectId);
3197  dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
3198 
3199  /* Qualify the name if not visible in search path */
3200  if (TSDictionaryIsVisible(object->objectId))
3201  nspname = NULL;
3202  else
3203  nspname = get_namespace_name(dictForm->dictnamespace);
3204 
3205  appendStringInfo(&buffer, _("text search dictionary %s"),
3207  NameStr(dictForm->dictname)));
3208  ReleaseSysCache(tup);
3209  break;
3210  }
3211 
3212  case OCLASS_TSTEMPLATE:
3213  {
3214  HeapTuple tup;
3215  Form_pg_ts_template tmplForm;
3216  char *nspname;
3217 
3219  ObjectIdGetDatum(object->objectId));
3220  if (!HeapTupleIsValid(tup))
3221  elog(ERROR, "cache lookup failed for text search template %u",
3222  object->objectId);
3223  tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
3224 
3225  /* Qualify the name if not visible in search path */
3226  if (TSTemplateIsVisible(object->objectId))
3227  nspname = NULL;
3228  else
3229  nspname = get_namespace_name(tmplForm->tmplnamespace);
3230 
3231  appendStringInfo(&buffer, _("text search template %s"),
3233  NameStr(tmplForm->tmplname)));
3234  ReleaseSysCache(tup);
3235  break;
3236  }
3237 
3238  case OCLASS_TSCONFIG:
3239  {
3240  HeapTuple tup;
3241  Form_pg_ts_config cfgForm;
3242  char *nspname;
3243 
3245  ObjectIdGetDatum(object->objectId));
3246  if (!HeapTupleIsValid(tup))
3247  elog(ERROR, "cache lookup failed for text search configuration %u",
3248  object->objectId);
3249  cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
3250 
3251  /* Qualify the name if not visible in search path */
3252  if (TSConfigIsVisible(object->objectId))
3253  nspname = NULL;
3254  else
3255  nspname = get_namespace_name(cfgForm->cfgnamespace);
3256 
3257  appendStringInfo(&buffer, _("text search configuration %s"),
3259  NameStr(cfgForm->cfgname)));
3260  ReleaseSysCache(tup);
3261  break;
3262  }
3263 
3264  case OCLASS_ROLE:
3265  {
3266  appendStringInfo(&buffer, _("role %s"),
3267  GetUserNameFromId(object->objectId, false));
3268  break;
3269  }
3270 
3271  case OCLASS_DATABASE:
3272  {
3273  char *datname;
3274 
3275  datname = get_database_name(object->objectId);
3276  if (!datname)
3277  elog(ERROR, "cache lookup failed for database %u",
3278  object->objectId);
3279  appendStringInfo(&buffer, _("database %s"), datname);
3280  break;
3281  }
3282 
3283  case OCLASS_TBLSPACE:
3284  {
3285  char *tblspace;
3286 
3287  tblspace = get_tablespace_name(object->objectId);
3288  if (!tblspace)
3289  elog(ERROR, "cache lookup failed for tablespace %u",
3290  object->objectId);
3291  appendStringInfo(&buffer, _("tablespace %s"), tblspace);
3292  break;
3293  }
3294 
3295  case OCLASS_FDW:
3296  {
3297  ForeignDataWrapper *fdw;
3298 
3299  fdw = GetForeignDataWrapper(object->objectId);
3300  appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
3301  break;
3302  }
3303 
3304  case OCLASS_FOREIGN_SERVER:
3305  {
3306  ForeignServer *srv;
3307 
3308  srv = GetForeignServer(object->objectId);
3309  appendStringInfo(&buffer, _("server %s"), srv->servername);
3310  break;
3311  }
3312 
3313  case OCLASS_USER_MAPPING:
3314  {
3315  HeapTuple tup;
3316  Oid useid;
3317  char *usename;
3318  Form_pg_user_mapping umform;
3319  ForeignServer *srv;
3320 
3322  ObjectIdGetDatum(object->objectId));
3323  if (!HeapTupleIsValid(tup))
3324  elog(ERROR, "cache lookup failed for user mapping %u",
3325  object->objectId);
3326  umform = (Form_pg_user_mapping) GETSTRUCT(tup);
3327  useid = umform->umuser;
3328  srv = GetForeignServer(umform->umserver);
3329 
3330  ReleaseSysCache(tup);
3331 
3332  if (OidIsValid(useid))
3333  usename = GetUserNameFromId(useid, false);
3334  else
3335  usename = "public";
3336 
3337  appendStringInfo(&buffer, _("user mapping for %s on server %s"), usename,
3338  srv->servername);
3339  break;
3340  }
3341 
3342  case OCLASS_DEFACL:
3343  {
3344  Relation defaclrel;
3345  ScanKeyData skey[1];
3346  SysScanDesc rcscan;
3347  HeapTuple tup;
3348  Form_pg_default_acl defacl;
3349  char *rolename;
3350  char *nspname;
3351 
3352  defaclrel = heap_open(DefaultAclRelationId, AccessShareLock);
3353 
3354  ScanKeyInit(&skey[0],
3356  BTEqualStrategyNumber, F_OIDEQ,
3357  ObjectIdGetDatum(object->objectId));
3358 
3359  rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
3360  true, NULL, 1, skey);
3361 
3362  tup = systable_getnext(rcscan);
3363 
3364  if (!HeapTupleIsValid(tup))
3365  elog(ERROR, "could not find tuple for default ACL %u",
3366  object->objectId);
3367 
3368  defacl = (Form_pg_default_acl) GETSTRUCT(tup);
3369 
3370  rolename = GetUserNameFromId(defacl->defaclrole, false);
3371 
3372  if (OidIsValid(defacl->defaclnamespace))
3373  nspname = get_namespace_name(defacl->defaclnamespace);
3374  else
3375  nspname = NULL;
3376 
3377  switch (defacl->defaclobjtype)
3378  {
3379  case DEFACLOBJ_RELATION:
3380  if (nspname)
3381  appendStringInfo(&buffer,
3382  _("default privileges on new relations belonging to role %s in schema %s"),
3383  rolename, nspname);
3384  else
3385  appendStringInfo(&buffer,
3386  _("default privileges on new relations belonging to role %s"),
3387  rolename);
3388  break;
3389  case DEFACLOBJ_SEQUENCE:
3390  if (nspname)
3391  appendStringInfo(&buffer,
3392  _("default privileges on new sequences belonging to role %s in schema %s"),
3393  rolename, nspname);
3394  else
3395  appendStringInfo(&buffer,
3396  _("default privileges on new sequences belonging to role %s"),
3397  rolename);
3398  break;
3399  case DEFACLOBJ_FUNCTION:
3400  if (nspname)
3401  appendStringInfo(&buffer,
3402  _("default privileges on new functions belonging to role %s in schema %s"),
3403  rolename, nspname);
3404  else
3405  appendStringInfo(&buffer,
3406  _("default privileges on new functions belonging to role %s"),
3407  rolename);
3408  break;
3409  case DEFACLOBJ_TYPE:
3410  if (nspname)
3411  appendStringInfo(&buffer,
3412  _("default privileges on new types belonging to role %s in schema %s"),
3413  rolename, nspname);
3414  else
3415  appendStringInfo(&buffer,
3416  _("default privileges on new types belonging to role %s"),
3417  rolename);
3418  break;
3419  case DEFACLOBJ_NAMESPACE:
3420  Assert(!nspname);
3421  appendStringInfo(&buffer,
3422  _("default privileges on new schemas belonging to role %s"),
3423  rolename);
3424  break;
3425  default:
3426  /* shouldn't get here */
3427  if (nspname)
3428  appendStringInfo(&buffer,
3429  _("default privileges belonging to role %s in schema %s"),
3430  rolename, nspname);
3431  else
3432  appendStringInfo(&buffer,
3433  _("default privileges belonging to role %s"),
3434  rolename);
3435  break;
3436  }
3437 
3438  systable_endscan(rcscan);
3439  heap_close(defaclrel, AccessShareLock);
3440  break;
3441  }
3442 
3443  case OCLASS_EXTENSION:
3444  {
3445  char *extname;
3446 
3447  extname = get_extension_name(object->objectId);
3448  if (!extname)
3449  elog(ERROR, "cache lookup failed for extension %u",
3450  object->objectId);
3451  appendStringInfo(&buffer, _("extension %s"), extname);
3452  break;
3453  }
3454 
3455  case OCLASS_EVENT_TRIGGER:
3456  {
3457  HeapTuple tup;
3458 
3460  ObjectIdGetDatum(object->objectId));
3461  if (!HeapTupleIsValid(tup))
3462  elog(ERROR, "cache lookup failed for event trigger %u",
3463  object->objectId);
3464  appendStringInfo(&buffer, _("event trigger %s"),
3465  NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname));
3466  ReleaseSysCache(tup);
3467  break;
3468  }
3469 
3470  case OCLASS_POLICY:
3471  {
3472  Relation policy_rel;
3473  ScanKeyData skey[1];
3474  SysScanDesc sscan;
3475  HeapTuple tuple;
3476  Form_pg_policy form_policy;
3477  StringInfoData rel;
3478 
3479  policy_rel = heap_open(PolicyRelationId, AccessShareLock);
3480 
3481  ScanKeyInit(&skey[0],
3483  BTEqualStrategyNumber, F_OIDEQ,
3484  ObjectIdGetDatum(object->objectId));
3485 
3486  sscan = systable_beginscan(policy_rel, PolicyOidIndexId,
3487  true, NULL, 1, skey);
3488 
3489  tuple = systable_getnext(sscan);
3490 
3491  if (!HeapTupleIsValid(tuple))
3492  elog(ERROR, "could not find tuple for policy %u",
3493  object->objectId);
3494  form_policy = (Form_pg_policy) GETSTRUCT(tuple);
3495 
3496  initStringInfo(&rel);
3497  getRelationDescription(&rel, form_policy->polrelid);
3498 
3499  /* translator: second %s is, e.g., "table %s" */
3500  appendStringInfo(&buffer, _("policy %s on %s"),
3501  NameStr(form_policy->polname), rel.data);
3502  pfree(rel.data);
3503  systable_endscan(sscan);
3504  heap_close(policy_rel, AccessShareLock);
3505  break;
3506  }
3507 
3508  case OCLASS_PUBLICATION:
3509  {
3510  appendStringInfo(&buffer, _("publication %s"),
3511  get_publication_name(object->objectId));
3512  break;
3513  }
3514 
3516  {
3517  HeapTuple tup;
3518  char *pubname;
3519  Form_pg_publication_rel prform;
3520  StringInfoData rel;
3521 
3523  ObjectIdGetDatum(object->objectId));
3524  if (!HeapTupleIsValid(tup))
3525  elog(ERROR, "cache lookup failed for publication table %u",
3526  object->objectId);
3527 
3528  prform = (Form_pg_publication_rel) GETSTRUCT(tup);
3529  pubname = get_publication_name(prform->prpubid);
3530 
3531  initStringInfo(&rel);
3532  getRelationDescription(&rel, prform->prrelid);
3533 
3534  /* translator: first %s is, e.g., "table %s" */
3535  appendStringInfo(&buffer, _("publication of %s in publication %s"),
3536  rel.data, pubname);
3537  pfree(rel.data);
3538  ReleaseSysCache(tup);
3539  break;
3540  }
3541 
3542  case OCLASS_SUBSCRIPTION:
3543  {
3544  appendStringInfo(&buffer, _("subscription %s"),
3545  get_subscription_name(object->objectId));
3546  break;
3547  }
3548 
3549  case OCLASS_TRANSFORM:
3550  {
3551  HeapTuple trfTup;
3552  Form_pg_transform trfForm;
3553 
3554  trfTup = SearchSysCache1(TRFOID,
3555  ObjectIdGetDatum(object->objectId));
3556  if (!HeapTupleIsValid(trfTup))
3557  elog(ERROR, "could not find tuple for transform %u",
3558  object->objectId);
3559 
3560  trfForm = (Form_pg_transform) GETSTRUCT(trfTup);
3561 
3562  appendStringInfo(&buffer, _("transform for %s language %s"),
3563  format_type_be(trfForm->trftype),
3564  get_language_name(trfForm->trflang, false));
3565 
3566  ReleaseSysCache(trfTup);
3567  break;
3568  }
3569 
3570  /*
3571  * There's intentionally no default: case here; we want the
3572  * compiler to warn if a new OCLASS hasn't been handled above.
3573  */
3574  }
3575 
3576  return buffer.data;
3577 }
#define RewriteOidIndexId
Definition: indexing.h:222
#define TriggerOidIndexId
Definition: indexing.h:252
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Definition: syscache.h:36
char * get_language_name(Oid langoid, bool missing_ok)
Definition: lsyscache.c:1003
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:38
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
char * fdwname
Definition: foreign.h:39
#define PolicyOidIndexId
Definition: indexing.h:328
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:66
char * get_extension_name(Oid ext_oid)
Definition: extension.c:180
#define DefaultAclOidIndexId
Definition: indexing.h:308
#define AccessShareLock
Definition: lockdefs.h:36
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2214
static void getOpFamilyDescription(StringInfo buffer, Oid opfid)
#define AttrDefaultOidIndexId
Definition: indexing.h:88
#define AccessMethodOperatorOidIndexId
Definition: indexing.h:78
char * format_type_be(Oid type_oid)
Definition: format_type.c:328
char * format_operator(Oid operator_oid)
Definition: regproc.c:820
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2416
#define OidIsValid(objectId)
Definition: c.h:605
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
Definition: localtime.c:77
#define AccessMethodProcedureOidIndexId
Definition: indexing.h:83
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
FormData_pg_transform * Form_pg_transform
Definition: pg_transform.h:42
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2716
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
FormData_pg_user_mapping * Form_pg_user_mapping
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:41
FormData_pg_default_acl * Form_pg_default_acl
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051
#define CastOidIndexId
Definition: indexing.h:106
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2027
FormData_pg_cast * Form_pg_cast
Definition: pg_cast.h:54
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:45
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2463
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:10574
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
ForeignServer * GetForeignServer(Oid serverid)
Definition: foreign.c:93
char * get_publication_name(Oid pubid)
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:53
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:56
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1812
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:48
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:323
static void getRelationDescription(StringInfo buffer, Oid relid)
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2110
FormData_pg_constraint * Form_pg_constraint
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:787
#define Assert(condition)
Definition: c.h:699
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
FormData_pg_trigger * Form_pg_trigger
Definition: pg_trigger.h:70
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:49
FormData_pg_rewrite * Form_pg_rewrite
Definition: pg_rewrite.h:51
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2590
FormData_pg_am * Form_pg_am
Definition: pg_am.h:46
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2337
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:86
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1428
char * servername
Definition: foreign.h:50
FormData_pg_ts_template * Form_pg_ts_template
FormData_pg_publication_rel * Form_pg_publication_rel
#define NameStr(name)
Definition: c.h:576
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:775
#define elog
Definition: elog.h:219
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:81
#define _(x)
Definition: elog.c:84
#define BTEqualStrategyNumber
Definition: stratnum.h:31
FormData_pg_statistic_ext * Form_pg_statistic_ext
char * get_subscription_name(Oid subid)

◆ getObjectDescriptionOids()

char* getObjectDescriptionOids ( Oid  classid,
Oid  objid 
)

Definition at line 3583 of file objectaddress.c.

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

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

3584 {
3585  ObjectAddress address;
3586 
3587  address.classId = classid;
3588  address.objectId = objid;
3589  address.objectSubId = 0;
3590 
3591  return getObjectDescription(&address);
3592 }
char * getObjectDescription(const ObjectAddress *object)

◆ getObjectIdentity()

◆ getObjectIdentityParts()

char* getObjectIdentityParts ( const ObjectAddress address,
List **  objname,
List **  objargs 
)

Definition at line 4210 of file objectaddress.c.

References AccessMethodOperatorOidIndexId, AccessMethodProcedureOidIndexId, AccessShareLock, AMOID, appendStringInfo(), appendStringInfoString(), Assert, AttrDefaultOidIndexId, BTEqualStrategyNumber, buffer, CLAOID, ObjectAddress::classId, COLLOID, CONSTROID, CONVOID, StringInfoData::data, DefaultAclOidIndexId, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator_parts(), format_operator_qualified(), format_procedure_parts(), format_procedure_qualified(), format_type_be_qualified(), 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(), GetForeignDataWrapper(), GetForeignServer(), getObjectClass(), getObjectIdentityParts(), getOpFamilyIdentity(), getRelationIdentity(), GETSTRUCT, GetUserNameFromId(), heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), LANGOID, lappend(), list_make1, list_make2, list_make3, NameStr, NIL, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectIdGetDatum, ObjectAddress::objectSubId, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, OCLASS_USER_MAPPING, OidIsValid, pfree(), PointerIsValid, psprintf(), pstrdup(), PUBLICATIONREL, quote_identifier(), quote_qualified_identifier(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, STATEXTOID, subname, systable_beginscan(), systable_endscan(), systable_getnext(), TSCONFIGOID, TSDICTOID, TSPARSEROID, TSTEMPLATEOID, USERMAPPINGOID, and username.

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

4212 {
4214 
4215  initStringInfo(&buffer);
4216 
4217  /*
4218  * Make sure that both objname and objargs were passed, or none was; and
4219  * initialize them to empty lists. For objname this is useless because it
4220  * will be initialized in all cases inside the switch; but we do it anyway
4221  * so that we can test below that no branch leaves it unset.
4222  */
4223  Assert(PointerIsValid(objname) == PointerIsValid(objargs));
4224  if (objname)
4225  {
4226  *objname = NIL;
4227  *objargs = NIL;
4228  }
4229 
4230  switch (getObjectClass(object))
4231  {
4232  case OCLASS_CLASS:
4233  getRelationIdentity(&buffer, object->objectId, objname);
4234  if (object->objectSubId != 0)
4235  {
4236  char *attr;
4237 
4238  attr = get_attname(object->objectId, object->objectSubId,
4239  false);
4240  appendStringInfo(&buffer, ".%s", quote_identifier(attr));
4241  if (objname)
4242  *objname = lappend(*objname, attr);
4243  }
4244  break;
4245 
4246  case OCLASS_PROC:
4247  appendStringInfoString(&buffer,
4248  format_procedure_qualified(object->objectId));
4249  if (objname)
4250  format_procedure_parts(object->objectId, objname, objargs);
4251  break;
4252 
4253  case OCLASS_TYPE:
4254  {
4255  char *typeout;
4256 
4257  typeout = format_type_be_qualified(object->objectId);
4258  appendStringInfoString(&buffer, typeout);
4259  if (objname)
4260  *objname = list_make1(typeout);
4261  }
4262  break;
4263 
4264  case OCLASS_CAST:
4265  {
4266  Relation castRel;
4267  HeapTuple tup;
4268  Form_pg_cast castForm;
4269 
4270  castRel = heap_open(CastRelationId, AccessShareLock);
4271 
4272  tup = get_catalog_object_by_oid(castRel, object->objectId);
4273 
4274  if (!HeapTupleIsValid(tup))
4275  elog(ERROR, "could not find tuple for cast %u",
4276  object->objectId);
4277 
4278  castForm = (Form_pg_cast) GETSTRUCT(tup);
4279 
4280  appendStringInfo(&buffer, "(%s AS %s)",
4281  format_type_be_qualified(castForm->castsource),
4282  format_type_be_qualified(castForm->casttarget));
4283 
4284  if (objname)
4285  {
4286  *objname = list_make1(format_type_be_qualified(castForm->castsource));
4287  *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
4288  }
4289 
4290  heap_close(castRel, AccessShareLock);
4291  break;
4292  }
4293 
4294  case OCLASS_COLLATION:
4295  {
4296  HeapTuple collTup;
4297  Form_pg_collation coll;
4298  char *schema;
4299 
4300  collTup = SearchSysCache1(COLLOID,
4301  ObjectIdGetDatum(object->objectId));
4302  if (!HeapTupleIsValid(collTup))
4303  elog(ERROR, "cache lookup failed for collation %u",
4304  object->objectId);
4305  coll = (Form_pg_collation) GETSTRUCT(collTup);
4306  schema = get_namespace_name_or_temp(coll->collnamespace);
4307  appendStringInfoString(&buffer,
4309  NameStr(coll->collname)));
4310  if (objname)
4311  *objname = list_make2(schema,
4312  pstrdup(NameStr(coll->collname)));
4313  ReleaseSysCache(collTup);
4314  break;
4315  }
4316 
4317  case OCLASS_CONSTRAINT:
4318  {
4319  HeapTuple conTup;
4320  Form_pg_constraint con;
4321 
4322  conTup = SearchSysCache1(CONSTROID,
4323  ObjectIdGetDatum(object->objectId));
4324  if (!HeapTupleIsValid(conTup))
4325  elog(ERROR, "cache lookup failed for constraint %u",
4326  object->objectId);
4327  con = (Form_pg_constraint) GETSTRUCT(conTup);
4328 
4329  if (OidIsValid(con->conrelid))
4330  {
4331  appendStringInfo(&buffer, "%s on ",
4332  quote_identifier(NameStr(con->conname)));
4333  getRelationIdentity(&buffer, con->conrelid, objname);
4334  if (objname)
4335  *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
4336  }
4337  else
4338  {
4339  ObjectAddress domain;
4340 
4341  Assert(OidIsValid(con->contypid));
4342  domain.classId = TypeRelationId;
4343  domain.objectId = con->contypid;
4344  domain.objectSubId = 0;
4345 
4346  appendStringInfo(&buffer, "%s on %s",
4347  quote_identifier(NameStr(con->conname)),
4348  getObjectIdentityParts(&domain, objname, objargs));
4349 
4350  if (objname)
4351  *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
4352  }
4353 
4354  ReleaseSysCache(conTup);
4355  break;
4356  }
4357 
4358  case OCLASS_CONVERSION:
4359  {
4360  HeapTuple conTup;
4361  Form_pg_conversion conForm;
4362  char *schema;
4363 
4364  conTup = SearchSysCache1(CONVOID,
4365  ObjectIdGetDatum(object->objectId));
4366  if (!HeapTupleIsValid(conTup))
4367  elog(ERROR, "cache lookup failed for conversion %u",
4368  object->objectId);
4369  conForm = (Form_pg_conversion) GETSTRUCT(conTup);
4370  schema = get_namespace_name_or_temp(conForm->connamespace);
4371  appendStringInfoString(&buffer,
4373  NameStr(conForm->conname)));
4374  if (objname)
4375  *objname = list_make2(schema,
4376  pstrdup(NameStr(conForm->conname)));
4377  ReleaseSysCache(conTup);
4378  break;
4379  }
4380 
4381  case OCLASS_DEFAULT:
4382  {
4383  Relation attrdefDesc;
4384  ScanKeyData skey[1];
4385  SysScanDesc adscan;
4386 
4387  HeapTuple tup;
4388  Form_pg_attrdef attrdef;
4389  ObjectAddress colobject;
4390 
4391  attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock);
4392 
4393  ScanKeyInit(&skey[0],
4395  BTEqualStrategyNumber, F_OIDEQ,
4396  ObjectIdGetDatum(object->objectId));
4397 
4398  adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId,
4399  true, NULL, 1, skey);
4400 
4401  tup = systable_getnext(adscan);
4402 
4403  if (!HeapTupleIsValid(tup))
4404  elog(ERROR, "could not find tuple for attrdef %u",
4405  object->objectId);
4406 
4407  attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
4408 
4409  colobject.classId = RelationRelationId;
4410  colobject.objectId = attrdef->adrelid;
4411  colobject.objectSubId = attrdef->adnum;
4412 
4413  appendStringInfo(&buffer, "for %s",
4414  getObjectIdentityParts(&colobject,
4415  objname, objargs));
4416 
4417  systable_endscan(adscan);
4418  heap_close(attrdefDesc, AccessShareLock);
4419  break;
4420  }
4421 
4422  case OCLASS_LANGUAGE:
4423  {
4424  HeapTuple langTup;
4425  Form_pg_language langForm;
4426 
4427  langTup = SearchSysCache1(LANGOID,
4428  ObjectIdGetDatum(object->objectId));
4429  if (!HeapTupleIsValid(langTup))
4430  elog(ERROR, "cache lookup failed for language %u",
4431  object->objectId);
4432  langForm = (Form_pg_language) GETSTRUCT(langTup);
4433  appendStringInfoString(&buffer,
4434  quote_identifier(NameStr(langForm->lanname)));
4435  if (objname)
4436  *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
4437  ReleaseSysCache(langTup);
4438  break;
4439  }
4440  case OCLASS_LARGEOBJECT:
4441  appendStringInfo(&buffer, "%u",
4442  object->objectId);
4443  if (objname)
4444  *objname = list_make1(psprintf("%u", object->objectId));
4445  break;
4446 
4447  case OCLASS_OPERATOR:
4448  appendStringInfoString(&buffer,
4449  format_operator_qualified(object->objectId));
4450  if (objname)
4451  format_operator_parts(object->objectId, objname, objargs);
4452  break;
4453 
4454  case OCLASS_OPCLASS:
4455  {
4456  HeapTuple opcTup;
4457  Form_pg_opclass opcForm;
4458  HeapTuple amTup;
4459  Form_pg_am amForm;
4460  char *schema;
4461 
4462  opcTup = SearchSysCache1(CLAOID,
4463  ObjectIdGetDatum(object->objectId));
4464  if (!HeapTupleIsValid(opcTup))
4465  elog(ERROR, "cache lookup failed for opclass %u",
4466  object->objectId);
4467  opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
4468  schema = get_namespace_name_or_temp(opcForm->opcnamespace);
4469 
4470  amTup = SearchSysCache1(AMOID,
4471  ObjectIdGetDatum(opcForm->opcmethod));
4472  if (!HeapTupleIsValid(amTup))
4473  elog(ERROR, "cache lookup failed for access method %u",
4474  opcForm->opcmethod);
4475  amForm = (Form_pg_am) GETSTRUCT(amTup);
4476 
4477  appendStringInfo(&buffer, "%s USING %s",
4479  NameStr(opcForm->opcname)),
4480  quote_identifier(NameStr(amForm->amname)));
4481  if (objname)
4482  *objname = list_make3(pstrdup(NameStr(amForm->amname)),
4483  schema,
4484  pstrdup(NameStr(opcForm->opcname)));
4485 
4486  ReleaseSysCache(amTup);
4487  ReleaseSysCache(opcTup);
4488  break;
4489  }
4490 
4491  case OCLASS_OPFAMILY:
4492  getOpFamilyIdentity(&buffer, object->objectId, objname);
4493  break;
4494 
4495  case OCLASS_AM:
4496  {
4497  char *amname;
4498 
4499  amname = get_am_name(object->objectId);
4500  if (!amname)
4501  elog(ERROR, "cache lookup failed for access method %u",
4502  object->objectId);
4503  appendStringInfoString(&buffer, quote_identifier(amname));
4504  if (objname)
4505  *objname = list_make1(amname);
4506  }
4507  break;
4508 
4509  case OCLASS_AMOP:
4510  {
4511  Relation amopDesc;
4512  HeapTuple tup;
4513  ScanKeyData skey[1];
4514  SysScanDesc amscan;
4515  Form_pg_amop amopForm;
4516  StringInfoData opfam;
4517  char *ltype;
4518  char *rtype;
4519 
4520  amopDesc = heap_open(AccessMethodOperatorRelationId,
4521  AccessShareLock);
4522 
4523  ScanKeyInit(&skey[0],
4525  BTEqualStrategyNumber, F_OIDEQ,
4526  ObjectIdGetDatum(object->objectId));
4527 
4528  amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
4529  NULL, 1, skey);
4530 
4531  tup = systable_getnext(amscan);
4532 
4533  if (!HeapTupleIsValid(tup))
4534  elog(ERROR, "could not find tuple for amop entry %u",
4535  object->objectId);
4536 
4537  amopForm = (Form_pg_amop) GETSTRUCT(tup);
4538 
4539  initStringInfo(&opfam);
4540  getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname);
4541 
4542  ltype = format_type_be_qualified(amopForm->amoplefttype);
4543  rtype = format_type_be_qualified(amopForm->amoprighttype);
4544 
4545  if (objname)
4546  {
4547  *objname = lappend(*objname,
4548  psprintf("%d", amopForm->amopstrategy));
4549  *objargs = list_make2(ltype, rtype);
4550  }
4551 
4552  appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
4553  amopForm->amopstrategy,
4554  ltype, rtype, opfam.data);
4555 
4556  pfree(opfam.data);
4557 
4558  systable_endscan(amscan);
4559  heap_close(amopDesc, AccessShareLock);
4560  break;
4561  }
4562 
4563  case OCLASS_AMPROC:
4564  {
4565  Relation amprocDesc;
4566  ScanKeyData skey[1];
4567  SysScanDesc amscan;
4568  HeapTuple tup;
4569  Form_pg_amproc amprocForm;
4570  StringInfoData opfam;
4571  char *ltype;
4572  char *rtype;
4573 
4574  amprocDesc = heap_open(AccessMethodProcedureRelationId,
4575  AccessShareLock);
4576 
4577  ScanKeyInit(&skey[0],
4579  BTEqualStrategyNumber, F_OIDEQ,
4580  ObjectIdGetDatum(object->objectId));
4581 
4582  amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
4583  NULL, 1, skey);
4584 
4585  tup = systable_getnext(amscan);
4586 
4587  if (!HeapTupleIsValid(tup))
4588  elog(ERROR, "could not find tuple for amproc entry %u",
4589  object->objectId);
4590 
4591  amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
4592 
4593  initStringInfo(&opfam);
4594  getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname);
4595 
4596  ltype = format_type_be_qualified(amprocForm->amproclefttype);
4597  rtype = format_type_be_qualified(amprocForm->amprocrighttype);
4598 
4599  if (objname)
4600  {
4601  *objname = lappend(*objname,
4602  psprintf("%d", amprocForm->amprocnum));
4603  *objargs = list_make2(ltype, rtype);
4604  }
4605 
4606  appendStringInfo(&buffer, "function %d (%s, %s) of %s",
4607  amprocForm->amprocnum,
4608  ltype, rtype, opfam.data);
4609 
4610  pfree(opfam.data);
4611 
4612  systable_endscan(amscan);
4613  heap_close(amprocDesc, AccessShareLock);
4614  break;
4615  }
4616 
4617  case OCLASS_REWRITE:
4618  {
4619  Relation ruleDesc;
4620  HeapTuple tup;
4622 
4623  ruleDesc = heap_open(RewriteRelationId, AccessShareLock);
4624 
4625  tup = get_catalog_object_by_oid(ruleDesc, object->objectId);
4626 
4627  if (!HeapTupleIsValid(tup))
4628  elog(ERROR, "could not find tuple for rule %u",
4629  object->objectId);
4630 
4631  rule = (Form_pg_rewrite) GETSTRUCT(tup);
4632 
4633  appendStringInfo(&buffer, "%s on ",
4634  quote_identifier(NameStr(rule->rulename)));
4635  getRelationIdentity(&buffer, rule->ev_class, objname);
4636  if (objname)
4637  *objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
4638 
4639  heap_close(ruleDesc, AccessShareLock);
4640  break;
4641  }
4642 
4643  case OCLASS_TRIGGER:
4644  {
4645  Relation trigDesc;
4646  HeapTuple tup;
4647  Form_pg_trigger trig;
4648 
4649  trigDesc = heap_open(TriggerRelationId, AccessShareLock);
4650 
4651  tup = get_catalog_object_by_oid(trigDesc, object->objectId);
4652 
4653  if (!HeapTupleIsValid(tup))
4654  elog(ERROR, "could not find tuple for trigger %u",
4655  object->objectId);
4656 
4657  trig = (Form_pg_trigger) GETSTRUCT(tup);
4658 
4659  appendStringInfo(&buffer, "%s on ",
4660  quote_identifier(NameStr(trig->tgname)));
4661  getRelationIdentity(&buffer, trig->tgrelid, objname);
4662  if (objname)
4663  *objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
4664 
4665  heap_close(trigDesc, AccessShareLock);
4666  break;
4667  }
4668 
4669  case OCLASS_SCHEMA:
4670  {
4671  char *nspname;
4672 
4673  nspname = get_namespace_name_or_temp(object->objectId);
4674  if (!nspname)
4675  elog(ERROR, "cache lookup failed for namespace %u",
4676  object->objectId);
4677  appendStringInfoString(&buffer,
4678  quote_identifier(nspname));
4679  if (objname)
4680  *objname = list_make1(nspname);
4681  break;
4682  }
4683 
4684  case OCLASS_STATISTIC_EXT:
4685  {
4686  HeapTuple tup;
4687  Form_pg_statistic_ext formStatistic;
4688  char *schema;
4689 
4691  ObjectIdGetDatum(object->objectId));
4692  if (!HeapTupleIsValid(tup))
4693  elog(ERROR, "cache lookup failed for statistics object %u",
4694  object->objectId);
4695  formStatistic = (Form_pg_statistic_ext) GETSTRUCT(tup);
4696  schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
4697  appendStringInfoString(&buffer,
4699  NameStr(formStatistic->stxname)));
4700  if (objname)
4701  *objname = list_make2(schema,
4702  pstrdup(NameStr(formStatistic->stxname)));
4703  ReleaseSysCache(tup);
4704  }
4705  break;
4706 
4707  case OCLASS_TSPARSER:
4708  {
4709  HeapTuple tup;
4710  Form_pg_ts_parser formParser;
4711  char *schema;
4712 
4714  ObjectIdGetDatum(object->objectId));
4715  if (!HeapTupleIsValid(tup))
4716  elog(ERROR, "cache lookup failed for text search parser %u",
4717  object->objectId);
4718  formParser = (Form_pg_ts_parser) GETSTRUCT(tup);
4719  schema = get_namespace_name_or_temp(formParser->prsnamespace);
4720  appendStringInfoString(&buffer,
4722  NameStr(formParser->prsname)));
4723  if (objname)
4724  *objname = list_make2(schema,
4725  pstrdup(NameStr(formParser->prsname)));
4726  ReleaseSysCache(tup);
4727  break;
4728  }
4729 
4730  case OCLASS_TSDICT:
4731  {
4732  HeapTuple tup;
4733  Form_pg_ts_dict formDict;
4734  char *schema;
4735 
4736  tup = SearchSysCache1(TSDICTOID,
4737  ObjectIdGetDatum(object->objectId));
4738  if (!HeapTupleIsValid(tup))
4739  elog(ERROR, "cache lookup failed for text search dictionary %u",
4740  object->objectId);
4741  formDict = (Form_pg_ts_dict) GETSTRUCT(tup);
4742  schema = get_namespace_name_or_temp(formDict->dictnamespace);
4743  appendStringInfoString(&buffer,
4745  NameStr(formDict->dictname)));
4746  if (objname)
4747  *objname = list_make2(schema,
4748  pstrdup(NameStr(formDict->dictname)));
4749  ReleaseSysCache(tup);
4750  break;
4751  }
4752 
4753  case OCLASS_TSTEMPLATE:
4754  {
4755  HeapTuple tup;
4756  Form_pg_ts_template formTmpl;
4757  char *schema;
4758 
4760  ObjectIdGetDatum(object->objectId));
4761  if (!HeapTupleIsValid(tup))
4762  elog(ERROR, "cache lookup failed for text search template %u",
4763  object->objectId);
4764  formTmpl = (Form_pg_ts_template) GETSTRUCT(tup);
4765  schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
4766  appendStringInfoString(&buffer,
4768  NameStr(formTmpl->tmplname)));
4769  if (objname)
4770  *objname = list_make2(schema,
4771  pstrdup(NameStr(formTmpl->tmplname)));
4772  ReleaseSysCache(tup);
4773  break;
4774  }
4775 
4776  case OCLASS_TSCONFIG:
4777  {
4778  HeapTuple tup;
4779  Form_pg_ts_config formCfg;
4780  char *schema;
4781 
4783  ObjectIdGetDatum(object->objectId));
4784  if (!HeapTupleIsValid(tup))
4785  elog(ERROR, "cache lookup failed for text search configuration %u",
4786  object->objectId);
4787  formCfg = (Form_pg_ts_config) GETSTRUCT(tup);
4788  schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
4789  appendStringInfoString(&buffer,
4791  NameStr(formCfg->cfgname)));
4792  if (objname)
4793  *objname = list_make2(schema,
4794  pstrdup(NameStr(formCfg->cfgname)));
4795  ReleaseSysCache(tup);
4796  break;
4797  }
4798 
4799  case OCLASS_ROLE:
4800  {
4801  char *username;
4802 
4803  username = GetUserNameFromId(object->objectId, false);
4804  if (objname)
4805  *objname = list_make1(username);
4806  appendStringInfoString(&buffer,
4807  quote_identifier(username));
4808  break;
4809  }
4810 
4811  case OCLASS_DATABASE:
4812  {
4813  char *datname;
4814 
4815  datname = get_database_name(object->objectId);
4816  if (!datname)
4817  elog(ERROR, "cache lookup failed for database %u",
4818  object->objectId);
4819  if (objname)
4820  *objname = list_make1(datname);
4821  appendStringInfoString(&buffer,
4822  quote_identifier(datname));
4823  break;
4824  }
4825 
4826  case OCLASS_TBLSPACE:
4827  {
4828  char *tblspace;
4829 
4830  tblspace = get_tablespace_name(object->objectId);
4831  if (!tblspace)
4832  elog(ERROR, "cache lookup failed for tablespace %u",
4833  object->objectId);
4834  if (objname)
4835  *objname = list_make1(tblspace);
4836  appendStringInfoString(&buffer,
4837  quote_identifier(tblspace));
4838  break;
4839  }
4840 
4841  case OCLASS_FDW:
4842  {
4843  ForeignDataWrapper *fdw;
4844 
4845  fdw = GetForeignDataWrapper(object->objectId);
4847  if (objname)
4848  *objname = list_make1(pstrdup(fdw->fdwname));
4849  break;
4850  }
4851 
4852  case OCLASS_FOREIGN_SERVER:
4853  {
4854  ForeignServer *srv;
4855 
4856  srv = GetForeignServer(object->objectId);
4857  appendStringInfoString(&buffer,
4859  if (objname)
4860  *objname = list_make1(pstrdup(srv->servername));
4861  break;
4862  }
4863 
4864  case OCLASS_USER_MAPPING:
4865  {
4866  HeapTuple tup;
4867  Oid useid;
4868  Form_pg_user_mapping umform;
4869  ForeignServer *srv;
4870  const char *usename;
4871 
4873  ObjectIdGetDatum(object->objectId));
4874  if (!HeapTupleIsValid(tup))
4875  elog(ERROR, "cache lookup failed for user mapping %u",
4876  object->objectId);
4877  umform = (Form_pg_user_mapping) GETSTRUCT(tup);
4878  useid = umform->umuser;
4879  srv = GetForeignServer(umform->umserver);
4880 
4881  ReleaseSysCache(tup);
4882 
4883  if (OidIsValid(useid))
4884  usename = GetUserNameFromId(useid, false);
4885  else
4886  usename = "public";
4887 
4888  if (objname)
4889  {
4890  *objname = list_make1(pstrdup(usename));
4891  *objargs = list_make1(pstrdup(srv->servername));
4892  }
4893 
4894  appendStringInfo(&buffer, "%s on server %s",
4895  quote_identifier(usename),
4896  srv->servername);
4897  break;
4898  }
4899 
4900  case OCLASS_DEFACL:
4901  {
4902  Relation defaclrel;
4903  ScanKeyData skey[1];
4904  SysScanDesc rcscan;
4905  HeapTuple tup;
4906  Form_pg_default_acl defacl;
4907  char *schema;
4908  char *username;
4909 
4910  defaclrel = heap_open(DefaultAclRelationId, AccessShareLock);
4911 
4912  ScanKeyInit(&skey[0],
4914  BTEqualStrategyNumber, F_OIDEQ,
4915  ObjectIdGetDatum(object->objectId));
4916 
4917  rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
4918  true, NULL, 1, skey);
4919 
4920  tup = systable_getnext(rcscan);
4921 
4922  if (!HeapTupleIsValid(tup))
4923  elog(ERROR, "could not find tuple for default ACL %u",
4924  object->objectId);
4925 
4926  defacl = (Form_pg_default_acl) GETSTRUCT(tup);
4927 
4928  username = GetUserNameFromId(defacl->defaclrole, false);
4929  appendStringInfo(&buffer,
4930  "for role %s",
4931  quote_identifier(username));
4932 
4933  if (OidIsValid(defacl->defaclnamespace))
4934  {
4935  schema = get_namespace_name_or_temp(defacl->defaclnamespace);
4936  appendStringInfo(&buffer,
4937  " in schema %s",
4938  quote_identifier(schema));
4939  }
4940  else
4941  schema = NULL;
4942 
4943  switch (defacl->defaclobjtype)
4944  {
4945  case DEFACLOBJ_RELATION:
4946  appendStringInfoString(&buffer,
4947  " on tables");
4948  break;
4949  case DEFACLOBJ_SEQUENCE:
4950  appendStringInfoString(&buffer,
4951  " on sequences");
4952  break;
4953  case DEFACLOBJ_FUNCTION:
4954  appendStringInfoString(&buffer,
4955  " on functions");
4956  break;
4957  case DEFACLOBJ_TYPE:
4958  appendStringInfoString(&buffer,
4959  " on types");
4960  break;
4961  case DEFACLOBJ_NAMESPACE:
4962  appendStringInfoString(&buffer,
4963  " on schemas");
4964  break;
4965  }
4966 
4967  if (objname)
4968  {
4969  *objname = list_make1(username);
4970  if (schema)
4971  *objname = lappend(*objname, schema);
4972  *objargs = list_make1(psprintf("%c", defacl->defaclobjtype));
4973  }
4974 
4975  systable_endscan(rcscan);
4976  heap_close(defaclrel, AccessShareLock);
4977  break;
4978  }
4979 
4980  case OCLASS_EXTENSION:
4981  {
4982  char *extname;
4983 
4984  extname = get_extension_name(object->objectId);
4985  if (!extname)
4986  elog(ERROR, "cache lookup failed for extension %u",
4987  object->objectId);
4988  appendStringInfoString(&buffer, quote_identifier(extname));
4989  if (objname)
4990  *objname = list_make1(extname);
4991  break;
4992  }
4993 
4994  case OCLASS_EVENT_TRIGGER:
4995  {
4996  HeapTuple tup;
4997  Form_pg_event_trigger trigForm;
4998 
4999  /* no objname support here */
5000  if (objname)
5001  *objname = NIL;
5002 
5004  ObjectIdGetDatum(object->objectId));
5005  if (!HeapTupleIsValid(tup))
5006  elog(ERROR, "cache lookup failed for event trigger %u",
5007  object->objectId);
5008  trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
5009  appendStringInfoString(&buffer,
5010  quote_identifier(NameStr(trigForm->evtname)));
5011  ReleaseSysCache(tup);
5012  break;
5013  }
5014 
5015  case OCLASS_POLICY:
5016  {
5017  Relation polDesc;
5018  HeapTuple tup;
5019  Form_pg_policy policy;
5020 
5021  polDesc = heap_open(PolicyRelationId, AccessShareLock);
5022 
5023  tup = get_catalog_object_by_oid(polDesc, object->objectId);
5024 
5025  if (!HeapTupleIsValid(tup))
5026  elog(ERROR, "could not find tuple for policy %u",
5027  object->objectId);
5028 
5029  policy = (Form_pg_policy) GETSTRUCT(tup);
5030 
5031  appendStringInfo(&buffer, "%s on ",
5032  quote_identifier(NameStr(policy->polname)));
5033  getRelationIdentity(&buffer, policy->polrelid, objname);
5034  if (objname)
5035  *objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
5036 
5037  heap_close(polDesc, AccessShareLock);
5038  break;
5039  }
5040 
5041  case OCLASS_PUBLICATION:
5042  {
5043  char *pubname;
5044 
5045  pubname = get_publication_name(object->objectId);
5046  appendStringInfoString(&buffer,
5047  quote_identifier(pubname));
5048  if (objname)
5049  *objname = list_make1(pubname);
5050  break;
5051  }
5052 
5054  {
5055  HeapTuple tup;
5056  char *pubname;
5057  Form_pg_publication_rel prform;
5058 
5060  ObjectIdGetDatum(object->objectId));
5061  if (!HeapTupleIsValid(tup))
5062  elog(ERROR, "cache lookup failed for publication table %u",
5063  object->objectId);
5064 
5065  prform = (Form_pg_publication_rel) GETSTRUCT(tup);
5066  pubname = get_publication_name(prform->prpubid);
5067 
5068  getRelationIdentity(&buffer, prform->prrelid, objname);
5069  appendStringInfo(&buffer, " in publication %s", pubname);
5070 
5071  if (objargs)
5072  *objargs = list_make1(pubname);
5073 
5074  ReleaseSysCache(tup);
5075  break;
5076  }
5077 
5078  case OCLASS_SUBSCRIPTION:
5079  {
5080  char *subname;
5081 
5082  subname = get_subscription_name(object->objectId);
5083  appendStringInfoString(&buffer,
5084  quote_identifier(subname));
5085  if (objname)
5086  *objname = list_make1(subname);
5087  break;
5088  }
5089 
5090  case OCLASS_TRANSFORM:
5091  {
5092  Relation transformDesc;
5093  HeapTuple tup;
5094  Form_pg_transform transform;
5095  char *transformLang;
5096  char *transformType;
5097 
5098  transformDesc = heap_open(TransformRelationId, AccessShareLock);
5099 
5100  tup = get_catalog_object_by_oid(transformDesc, object->objectId);
5101 
5102  if (!HeapTupleIsValid(tup))
5103  elog(ERROR, "could not find tuple for transform %u",
5104  object->objectId);
5105 
5106  transform = (Form_pg_transform) GETSTRUCT(tup);
5107 
5108  transformType = format_type_be_qualified(transform->trftype);
5109  transformLang = get_language_name(transform->trflang, false);
5110 
5111  appendStringInfo(&buffer, "for %s on language %s",
5112  transformType,
5113  transformLang);
5114  if (objname)
5115  {
5116  *objname = list_make1(transformType);
5117  *objargs = list_make1(pstrdup(transformLang));
5118  }
5119 
5120  heap_close(transformDesc, AccessShareLock);
5121  }
5122  break;
5123 
5124  /*
5125  * There's intentionally no default: case here; we want the
5126  * compiler to warn if a new OCLASS hasn't been handled above.
5127  */
5128  }
5129 
5130  /*
5131  * If a get_object_address representation was requested, make sure we are
5132  * providing one. We don't check objargs, because many of the cases above
5133  * leave it as NIL.
5134  */
5135  if (objname && *objname == NIL)
5136  elog(ERROR, "requested object address for unsupported object class %d: text result \"%s\"",
5137  (int) getObjectClass(object), buffer.data);
5138 
5139  return buffer.data;
5140 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
#define list_make3(x1, x2, x3)
Definition: pg_list.h:141
#define NIL
Definition: pg_list.h:69
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Definition: syscache.h:36
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10488
char * get_language_name(Oid langoid, bool missing_ok)
Definition: lsyscache.c:1003
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:38
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
char * fdwname
Definition: foreign.h:39
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:66
char * pstrdup(const char *in)
Definition: mcxt.c:1161
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * get_extension_name(Oid ext_oid)
Definition: extension.c:180
static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object)
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs)
#define DefaultAclOidIndexId
Definition: indexing.h:308
#define AccessShareLock
Definition: lockdefs.h:36
#define AttrDefaultOidIndexId
Definition: indexing.h:88
#define AccessMethodOperatorOidIndexId
Definition: indexing.h:78
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
NameData subname
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2416
#define OidIsValid(objectId)
Definition: c.h:605
static void getRelationIdentity(StringInfo buffer, Oid relid, List **object)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
Definition: localtime.c:77
#define AccessMethodProcedureOidIndexId
Definition: indexing.h:83
#define list_make1(x1)
Definition: pg_list.h:139
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
void pfree(void *pointer)
Definition: mcxt.c:1031
void format_operator_parts(Oid operator_oid, List **objnames, List **objargs)
Definition: regproc.c:832
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
FormData_pg_transform * Form_pg_transform
Definition: pg_transform.h:42
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
char * format_operator_qualified(Oid operator_oid)
Definition: regproc.c:826
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
FormData_pg_user_mapping * Form_pg_user_mapping
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:41
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
FormData_pg_default_acl * Form_pg_default_acl
char * get_am_name(Oid amOid)
Definition: amcmds.c:202
void format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs)
Definition: regproc.c:408
FormData_pg_cast * Form_pg_cast
Definition: pg_cast.h:54
char * format_procedure_qualified(Oid procedure_oid)
Definition: regproc.c:329
List * lappend(List *list, void *datum)
Definition: list.c:128
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:45
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:10574
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
ForeignServer * GetForeignServer(Oid serverid)
Definition: foreign.c:93
char * get_publication_name(Oid pubid)
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:53
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:56
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
static char * username
Definition: initdb.c:132
FormData_pg_policy * Form_pg_policy
Definition: pg_policy.h:48
FormData_pg_constraint * Form_pg_constraint
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:787
#define Assert(condition)
Definition: c.h:699
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
char * format_type_be_qualified(Oid type_oid)
Definition: format_type.c:338
FormData_pg_trigger * Form_pg_trigger
Definition: pg_trigger.h:70
HeapTuple get_catalog_object_by_oid(Relation catalog, Oid objectId)
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:49
FormData_pg_rewrite * Form_pg_rewrite
Definition: pg_rewrite.h:51
FormData_pg_am * Form_pg_am
Definition: pg_am.h:46
FormData_pg_language * Form_pg_language
Definition: pg_language.h:63
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3075
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:86
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1428
char * servername
Definition: foreign.h:50
FormData_pg_ts_template * Form_pg_ts_template
FormData_pg_publication_rel * Form_pg_publication_rel
#define NameStr(name)
Definition: c.h:576
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:775
#define elog
Definition: elog.h:219
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:81
#define PointerIsValid(pointer)
Definition: c.h:593
#define BTEqualStrategyNumber
Definition: stratnum.h:31
FormData_pg_statistic_ext * Form_pg_statistic_ext
char * get_subscription_name(Oid subid)

◆ getObjectTypeDescription()

char* getObjectTypeDescription ( const ObjectAddress object)

Definition at line 3912 of file objectaddress.c.

References appendStringInfoString(), buffer, StringInfoData::data, getConstraintTypeDescription(), getObjectClass(), getProcedureTypeDescription(), getRelationTypeDescription(), initStringInfo(), ObjectAddress::objectId, ObjectAddress::objectSubId, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, and OCLASS_USER_MAPPING.

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

3913 {
3915 
3916  initStringInfo(&buffer);
3917 
3918  switch (getObjectClass(object))
3919  {
3920  case OCLASS_CLASS:
3921  getRelationTypeDescription(&buffer, object->objectId,
3922  object->objectSubId);
3923  break;
3924 
3925  case OCLASS_PROC:
3926  getProcedureTypeDescription(&buffer, object->objectId);
3927  break;
3928 
3929  case OCLASS_TYPE:
3930  appendStringInfoString(&buffer, "type");
3931  break;
3932 
3933  case OCLASS_CAST:
3934  appendStringInfoString(&buffer, "cast");
3935  break;
3936 
3937  case OCLASS_COLLATION:
3938  appendStringInfoString(&buffer, "collation");
3939  break;
3940 
3941  case OCLASS_CONSTRAINT:
3942  getConstraintTypeDescription(&buffer, object->objectId);
3943  break;
3944 
3945  case OCLASS_CONVERSION:
3946  appendStringInfoString(&buffer, "conversion");
3947  break;
3948 
3949  case OCLASS_DEFAULT:
3950  appendStringInfoString(&buffer, "default value");
3951  break;
3952 
3953  case OCLASS_LANGUAGE:
3954  appendStringInfoString(&buffer, "language");
3955  break;
3956 
3957  case OCLASS_LARGEOBJECT:
3958  appendStringInfoString(&buffer, "large object");
3959  break;
3960 
3961  case OCLASS_OPERATOR:
3962  appendStringInfoString(&buffer, "operator");
3963  break;
3964 
3965  case OCLASS_OPCLASS:
3966  appendStringInfoString(&buffer, "operator class");
3967  break;
3968 
3969  case OCLASS_OPFAMILY:
3970  appendStringInfoString(&buffer, "operator family");
3971  break;
3972 
3973  case OCLASS_AM:
3974  appendStringInfoString(&buffer, "access method");
3975  break;
3976 
3977  case OCLASS_AMOP:
3978  appendStringInfoString(&buffer, "operator of access method");
3979  break;
3980 
3981  case OCLASS_AMPROC:
3982  appendStringInfoString(&buffer, "function of access method");
3983  break;
3984 
3985  case OCLASS_REWRITE:
3986  appendStringInfoString(&buffer, "rule");
3987  break;
3988 
3989  case OCLASS_TRIGGER:
3990  appendStringInfoString(&buffer, "trigger");
3991  break;
3992 
3993  case OCLASS_SCHEMA:
3994  appendStringInfoString(&buffer, "schema");
3995  break;
3996 
3997  case OCLASS_STATISTIC_EXT:
3998  appendStringInfoString(&buffer, "statistics object");
3999  break;
4000 
4001  case OCLASS_TSPARSER:
4002  appendStringInfoString(&buffer, "text search parser");
4003  break;
4004 
4005  case OCLASS_TSDICT:
4006  appendStringInfoString(&buffer, "text search dictionary");
4007  break;
4008 
4009  case OCLASS_TSTEMPLATE:
4010  appendStringInfoString(&buffer, "text search template");
4011  break;
4012 
4013  case OCLASS_TSCONFIG:
4014  appendStringInfoString(&buffer, "text search configuration");
4015  break;
4016 
4017  case OCLASS_ROLE:
4018  appendStringInfoString(&buffer, "role");
4019  break;
4020 
4021  case OCLASS_DATABASE:
4022  appendStringInfoString(&buffer, "database");
4023  break;
4024 
4025  case OCLASS_TBLSPACE:
4026  appendStringInfoString(&buffer, "tablespace");
4027  break;
4028 
4029  case OCLASS_FDW:
4030  appendStringInfoString(&buffer, "foreign-data wrapper");
4031  break;
4032 
4033  case OCLASS_FOREIGN_SERVER:
4034  appendStringInfoString(&buffer, "server");
4035  break;
4036 
4037  case OCLASS_USER_MAPPING:
4038  appendStringInfoString(&buffer, "user mapping");
4039  break;
4040 
4041  case OCLASS_DEFACL:
4042  appendStringInfoString(&buffer, "default acl");
4043  break;
4044 
4045  case OCLASS_EXTENSION:
4046  appendStringInfoString(&buffer, "extension");
4047  break;
4048 
4049  case OCLASS_EVENT_TRIGGER:
4050  appendStringInfoString(&buffer, "event trigger");
4051  break;
4052 
4053  case OCLASS_POLICY:
4054  appendStringInfoString(&buffer, "policy");
4055  break;
4056 
4057  case OCLASS_PUBLICATION:
4058  appendStringInfoString(&buffer, "publication");
4059  break;
4060 
4062  appendStringInfoString(&buffer, "publication relation");
4063  break;
4064 
4065  case OCLASS_SUBSCRIPTION:
4066  appendStringInfoString(&buffer, "subscription");
4067  break;
4068 
4069  case OCLASS_TRANSFORM:
4070  appendStringInfoString(&buffer, "transform");
4071  break;
4072 
4073  /*
4074  * There's intentionally no default: case here; we want the
4075  * compiler to warn if a new OCLASS hasn't been handled above.
4076  */
4077  }
4078 
4079  return buffer.data;
4080 }
static void getConstraintTypeDescription(StringInfo buffer, Oid constroid)
static void getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2416
static void getProcedureTypeDescription(StringInfo buffer, Oid procid)
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215

◆ is_objectclass_supported()

bool is_objectclass_supported ( Oid  class_id)

Definition at line 2576 of file objectaddress.c.

References lengthof.

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

2577 {
2578  int index;
2579 
2580  for (index = 0; index < lengthof(ObjectProperty); index++)
2581  {
2582  if (ObjectProperty[index].class_oid == class_id)
2583  return true;
2584  }
2585 
2586  return false;
2587 }
#define lengthof(array)
Definition: c.h:629
Definition: type.h:89
static const ObjectPropertyType ObjectProperty[]

◆ read_objtype_from_string()

int read_objtype_from_string ( const char *  objtype)

Definition at line 2470 of file objectaddress.c.

References ereport, errcode(), errmsg(), ERROR, i, lengthof, ObjectTypeMap, object_type_map::tm_name, and object_type_map::tm_type.

Referenced by pg_get_object_address().

2471 {
2472  int i;
2473 
2474  for (i = 0; i < lengthof(ObjectTypeMap); i++)
2475  {
2476  if (strcmp(ObjectTypeMap[i].tm_name, objtype) == 0)
2477  return ObjectTypeMap[i].tm_type;
2478  }
2479  ereport(ERROR,
2480  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2481  errmsg("unrecognized object type \"%s\"", objtype)));
2482 
2483  return -1; /* keep compiler quiet */
2484 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lengthof(array)
Definition: c.h:629
#define ERROR
Definition: elog.h:43
static const struct object_type_map ObjectTypeMap[]
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i

◆ strlist_to_textarray()

ArrayType* strlist_to_textarray ( List list)

Definition at line 5208 of file objectaddress.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, construct_array(), CStringGetTextDatum, CurrentMemoryContext, lfirst, list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), name, and palloc().

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

5209 {
5210  ArrayType *arr;
5211  Datum *datums;
5212  int j = 0;
5213  ListCell *cell;
5214  MemoryContext memcxt;
5215  MemoryContext oldcxt;
5216 
5217  /* Work in a temp context; easier than individually pfree'ing the Datums */
5219  "strlist to array",
5221  oldcxt = MemoryContextSwitchTo(memcxt);
5222 
5223  datums = (Datum *) palloc(sizeof(Datum) * list_length(list));
5224 
5225  foreach(cell, list)
5226  {
5227  char *name = lfirst(cell);
5228 
5229  datums[j++] = CStringGetTextDatum(name);
5230  }
5231 
5232  MemoryContextSwitchTo(oldcxt);
5233 
5234  arr = construct_array(datums, list_length(list),
5235  TEXTOID, -1, false, 'i');
5236 
5237  MemoryContextDelete(memcxt);
5238 
5239  return arr;
5240 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3279
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170
uintptr_t Datum
Definition: postgres.h:367
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
const char * name
Definition: encode.c:521
void * palloc(Size size)
Definition: mcxt.c:924
#define CStringGetTextDatum(s)
Definition: builtins.h:95

Variable Documentation

◆ InvalidObjectAddress