PostgreSQL Source Code  git master
objectaddress.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_default_acl.h"
#include "catalog/pg_enum.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_language.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_policy.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_publication.h"
#include "catalog/pg_publication_rel.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_transform.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "catalog/pg_user_mapping.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/policy.h"
#include "commands/proclang.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "foreign/foreign.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_type.h"
#include "rewrite/rewriteSupport.h"
#include "storage/large_object.h"
#include "storage/lmgr.h"
#include "storage/sinval.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/regproc.h"
#include "utils/syscache.h"
Include dependency graph for objectaddress.c:

Go to the source code of this file.

Data Structures

struct  ObjectPropertyType
 
struct  object_type_map
 

Functions

static ObjectAddress get_object_address_unqualified (ObjectType objtype, String *strval, bool missing_ok)
 
static ObjectAddress get_relation_by_qualified_name (ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
 
static ObjectAddress get_object_address_relobject (ObjectType objtype, List *object, Relation *relp, bool missing_ok)
 
static ObjectAddress get_object_address_attribute (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)
 
static ObjectAddress get_object_address_type (ObjectType objtype, TypeName *typename, bool missing_ok)
 
static ObjectAddress get_object_address_opcf (ObjectType objtype, List *object, bool missing_ok)
 
static ObjectAddress get_object_address_opf_member (ObjectType objtype, List *object, bool missing_ok)
 
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)
 
static ObjectAddress get_object_address_defacl (List *object, bool missing_ok)
 
static const ObjectPropertyTypeget_object_property_data (Oid class_id)
 
static void getRelationDescription (StringInfo buffer, Oid relid, bool missing_ok)
 
static void getOpFamilyDescription (StringInfo buffer, Oid opfid, bool missing_ok)
 
static void getRelationTypeDescription (StringInfo buffer, Oid relid, int32 objectSubId, bool missing_ok)
 
static void getProcedureTypeDescription (StringInfo buffer, Oid procid, bool missing_ok)
 
static void getConstraintTypeDescription (StringInfo buffer, Oid constroid, bool missing_ok)
 
static void getOpFamilyIdentity (StringInfo buffer, Oid opfid, List **object, bool missing_ok)
 
static void getRelationIdentity (StringInfo buffer, Oid relid, List **object, bool missing_ok)
 
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)
 
static Listtextarray_to_strvaluelist (ArrayType *arr)
 
Datum pg_get_object_address (PG_FUNCTION_ARGS)
 
void check_object_ownership (Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
 
Oid get_object_namespace (const ObjectAddress *address)
 
int read_objtype_from_string (const char *objtype)
 
const char * get_object_class_descr (Oid class_id)
 
Oid get_object_oid_index (Oid class_id)
 
int get_object_catcache_oid (Oid class_id)
 
int get_object_catcache_name (Oid class_id)
 
AttrNumber get_object_attnum_oid (Oid class_id)
 
AttrNumber get_object_attnum_name (Oid class_id)
 
AttrNumber get_object_attnum_namespace (Oid class_id)
 
AttrNumber get_object_attnum_owner (Oid class_id)
 
AttrNumber get_object_attnum_acl (Oid class_id)
 
ObjectType get_object_type (Oid class_id, Oid object_id)
 
bool get_object_namensp_unique (Oid class_id)
 
bool is_objectclass_supported (Oid class_id)
 
HeapTuple get_catalog_object_by_oid (Relation catalog, AttrNumber oidcol, Oid objectId)
 
char * getObjectDescription (const ObjectAddress *object, bool missing_ok)
 
char * getObjectDescriptionOids (Oid classid, Oid objid)
 
Datum pg_describe_object (PG_FUNCTION_ARGS)
 
Datum pg_identify_object (PG_FUNCTION_ARGS)
 
Datum pg_identify_object_as_address (PG_FUNCTION_ARGS)
 
char * getObjectTypeDescription (const ObjectAddress *object, bool missing_ok)
 
char * getObjectIdentity (const ObjectAddress *object, bool missing_ok)
 
char * getObjectIdentityParts (const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
 
ArrayTypestrlist_to_textarray (List *list)
 
ObjectType get_relkind_objtype (char relkind)
 

Variables

static const ObjectPropertyType ObjectProperty []
 
static const struct object_type_map ObjectTypeMap []
 
const ObjectAddress InvalidObjectAddress
 

Function Documentation

◆ check_object_ownership()

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

Definition at line 2366 of file objectaddress.c.

References aclcheck_error(), aclcheck_error_type(), ACLCHECK_NOT_OWNER, castNode, CONSTROID, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), GETSTRUCT, has_createrole_privilege(), HeapTupleIsValid, 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, ObjectIdGetDatum, 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, ReleaseSysCache(), SearchSysCache1(), strVal, superuser_arg(), and typenameTypeId().

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

2368 {
2369  switch (objtype)
2370  {
2371  case OBJECT_INDEX:
2372  case OBJECT_SEQUENCE:
2373  case OBJECT_TABLE:
2374  case OBJECT_VIEW:
2375  case OBJECT_MATVIEW:
2376  case OBJECT_FOREIGN_TABLE:
2377  case OBJECT_COLUMN:
2378  case OBJECT_RULE:
2379  case OBJECT_TRIGGER:
2380  case OBJECT_POLICY:
2381  case OBJECT_TABCONSTRAINT:
2382  if (!pg_class_ownercheck(RelationGetRelid(relation), roleid))
2384  RelationGetRelationName(relation));
2385  break;
2386  case OBJECT_DATABASE:
2387  if (!pg_database_ownercheck(address.objectId, roleid))
2389  strVal(object));
2390  break;
2391  case OBJECT_TYPE:
2392  case OBJECT_DOMAIN:
2393  case OBJECT_ATTRIBUTE:
2394  if (!pg_type_ownercheck(address.objectId, roleid))
2396  break;
2397  case OBJECT_DOMCONSTRAINT:
2398  {
2399  HeapTuple tuple;
2400  Oid contypid;
2401 
2402  tuple = SearchSysCache1(CONSTROID,
2403  ObjectIdGetDatum(address.objectId));
2404  if (!HeapTupleIsValid(tuple))
2405  elog(ERROR, "constraint with OID %u does not exist",
2406  address.objectId);
2407 
2408  contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid;
2409 
2410  ReleaseSysCache(tuple);
2411 
2412  /*
2413  * Fallback to type ownership check in this case as this is
2414  * what domain constraints rely on.
2415  */
2416  if (!pg_type_ownercheck(contypid, roleid))
2418  }
2419  break;
2420  case OBJECT_AGGREGATE:
2421  case OBJECT_FUNCTION:
2422  case OBJECT_PROCEDURE:
2423  case OBJECT_ROUTINE:
2424  if (!pg_proc_ownercheck(address.objectId, roleid))
2426  NameListToString((castNode(ObjectWithArgs, object))->objname));
2427  break;
2428  case OBJECT_OPERATOR:
2429  if (!pg_oper_ownercheck(address.objectId, roleid))
2431  NameListToString((castNode(ObjectWithArgs, object))->objname));
2432  break;
2433  case OBJECT_SCHEMA:
2434  if (!pg_namespace_ownercheck(address.objectId, roleid))
2436  strVal(object));
2437  break;
2438  case OBJECT_COLLATION:
2439  if (!pg_collation_ownercheck(address.objectId, roleid))
2441  NameListToString(castNode(List, object)));
2442  break;
2443  case OBJECT_CONVERSION:
2444  if (!pg_conversion_ownercheck(address.objectId, roleid))
2446  NameListToString(castNode(List, object)));
2447  break;
2448  case OBJECT_EXTENSION:
2449  if (!pg_extension_ownercheck(address.objectId, roleid))
2451  strVal(object));
2452  break;
2453  case OBJECT_FDW:
2454  if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid))
2456  strVal(object));
2457  break;
2458  case OBJECT_FOREIGN_SERVER:
2459  if (!pg_foreign_server_ownercheck(address.objectId, roleid))
2461  strVal(object));
2462  break;
2463  case OBJECT_EVENT_TRIGGER:
2464  if (!pg_event_trigger_ownercheck(address.objectId, roleid))
2466  strVal(object));
2467  break;
2468  case OBJECT_LANGUAGE:
2469  if (!pg_language_ownercheck(address.objectId, roleid))
2471  strVal(object));
2472  break;
2473  case OBJECT_OPCLASS:
2474  if (!pg_opclass_ownercheck(address.objectId, roleid))
2476  NameListToString(castNode(List, object)));
2477  break;
2478  case OBJECT_OPFAMILY:
2479  if (!pg_opfamily_ownercheck(address.objectId, roleid))
2481  NameListToString(castNode(List, object)));
2482  break;
2483  case OBJECT_LARGEOBJECT:
2484  if (!lo_compat_privileges &&
2485  !pg_largeobject_ownercheck(address.objectId, roleid))
2486  ereport(ERROR,
2487  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2488  errmsg("must be owner of large object %u",
2489  address.objectId)));
2490  break;
2491  case OBJECT_CAST:
2492  {
2493  /* We can only check permissions on the source/target types */
2494  TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
2495  TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
2496  Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
2497  Oid targettypeid = typenameTypeId(NULL, targettype);
2498 
2499  if (!pg_type_ownercheck(sourcetypeid, roleid)
2500  && !pg_type_ownercheck(targettypeid, roleid))
2501  ereport(ERROR,
2502  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2503  errmsg("must be owner of type %s or type %s",
2504  format_type_be(sourcetypeid),
2505  format_type_be(targettypeid))));
2506  }
2507  break;
2508  case OBJECT_PUBLICATION:
2509  if (!pg_publication_ownercheck(address.objectId, roleid))
2511  strVal(object));
2512  break;
2513  case OBJECT_SUBSCRIPTION:
2514  if (!pg_subscription_ownercheck(address.objectId, roleid))
2516  strVal(object));
2517  break;
2518  case OBJECT_TRANSFORM:
2519  {
2520  TypeName *typename = linitial_node(TypeName, castNode(List, object));
2521  Oid typeid = typenameTypeId(NULL, typename);
2522 
2523  if (!pg_type_ownercheck(typeid, roleid))
2525  }
2526  break;
2527  case OBJECT_TABLESPACE:
2528  if (!pg_tablespace_ownercheck(address.objectId, roleid))
2530  strVal(object));
2531  break;
2532  case OBJECT_TSDICTIONARY:
2533  if (!pg_ts_dict_ownercheck(address.objectId, roleid))
2535  NameListToString(castNode(List, object)));
2536  break;
2538  if (!pg_ts_config_ownercheck(address.objectId, roleid))
2540  NameListToString(castNode(List, object)));
2541  break;
2542  case OBJECT_ROLE:
2543 
2544  /*
2545  * We treat roles as being "owned" by those with CREATEROLE priv,
2546  * except that superusers are only owned by superusers.
2547  */
2548  if (superuser_arg(address.objectId))
2549  {
2550  if (!superuser_arg(roleid))
2551  ereport(ERROR,
2552  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2553  errmsg("must be superuser")));
2554  }
2555  else
2556  {
2557  if (!has_createrole_privilege(roleid))
2558  ereport(ERROR,
2559  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2560  errmsg("must have CREATEROLE privilege")));
2561  }
2562  break;
2563  case OBJECT_TSPARSER:
2564  case OBJECT_TSTEMPLATE:
2565  case OBJECT_ACCESS_METHOD:
2566  /* We treat these object types as being owned by superusers */
2567  if (!superuser_arg(roleid))
2568  ereport(ERROR,
2569  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2570  errmsg("must be superuser")));
2571  break;
2572  case OBJECT_STATISTIC_EXT:
2573  if (!pg_statistics_object_ownercheck(address.objectId, roleid))
2575  NameListToString(castNode(List, object)));
2576  break;
2577  default:
2578  elog(ERROR, "unrecognized object type: %d",
2579  (int) objtype);
2580  }
2581 }
bool has_createrole_privilege(Oid roleid)
Definition: aclchk.c:5443
bool pg_collation_ownercheck(Oid coll_oid, Oid roleid)
Definition: aclchk.c:5262
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
bool lo_compat_privileges
Definition: inv_api.c:58
bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
Definition: aclchk.c:4951
bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid)
Definition: aclchk.c:5101
bool pg_language_ownercheck(Oid lan_oid, Oid roleid)
Definition: aclchk.c:4922
#define castNode(_type_, nodeptr)
Definition: nodes.h:606
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:5128
bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid)
Definition: aclchk.c:5182
bool pg_publication_ownercheck(Oid pub_oid, Oid roleid)
Definition: aclchk.c:5356
#define strVal(v)
Definition: value.h:65
bool pg_oper_ownercheck(Oid oper_oid, Oid roleid)
Definition: aclchk.c:4870
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
Definition: aclchk.c:4994
unsigned int Oid
Definition: postgres_ext.h:31
bool pg_type_ownercheck(Oid type_oid, Oid roleid)
Definition: aclchk.c:4844
#define linitial_node(type, l)
Definition: pg_list.h:177
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3621
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid)
Definition: aclchk.c:5209
bool pg_extension_ownercheck(Oid ext_oid, Oid roleid)
Definition: aclchk.c:5314
#define RelationGetRelationName(relation)
Definition: rel.h:511
bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
Definition: aclchk.c:5020
bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid)
Definition: aclchk.c:5074
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:5236
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
char * NameListToString(List *names)
Definition: namespace.c:3147
#define lsecond_node(type, l)
Definition: pg_list.h:182
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
Definition: aclchk.c:5047
bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid)
Definition: aclchk.c:5288
#define ereport(elevel,...)
Definition: elog.h:157
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4818
bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid)
Definition: aclchk.c:5155
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:477
bool pg_proc_ownercheck(Oid proc_oid, Oid roleid)
Definition: aclchk.c:4896
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:291
bool pg_subscription_ownercheck(Oid sub_oid, Oid roleid)
Definition: aclchk.c:5382
bool pg_statistics_object_ownercheck(Oid stat_oid, Oid roleid)
Definition: aclchk.c:5408

◆ get_catalog_object_by_oid()

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

Definition at line 2810 of file objectaddress.c.

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

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

2811 {
2812  HeapTuple tuple;
2813  Oid classId = RelationGetRelid(catalog);
2814  int oidCacheId = get_object_catcache_oid(classId);
2815 
2816  if (oidCacheId > 0)
2817  {
2818  tuple = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId));
2819  if (!HeapTupleIsValid(tuple)) /* should not happen */
2820  return NULL;
2821  }
2822  else
2823  {
2824  Oid oidIndexId = get_object_oid_index(classId);
2825  SysScanDesc scan;
2826  ScanKeyData skey;
2827 
2828  Assert(OidIsValid(oidIndexId));
2829 
2830  ScanKeyInit(&skey,
2831  oidcol,
2832  BTEqualStrategyNumber, F_OIDEQ,
2833  ObjectIdGetDatum(objectId));
2834 
2835  scan = systable_beginscan(catalog, oidIndexId, true,
2836  NULL, 1, &skey);
2837  tuple = systable_getnext(scan);
2838  if (!HeapTupleIsValid(tuple))
2839  {
2840  systable_endscan(scan);
2841  return NULL;
2842  }
2843  tuple = heap_copytuple(tuple);
2844 
2845  systable_endscan(scan);
2846  }
2847 
2848  return tuple;
2849 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
Oid get_object_oid_index(Oid class_id)
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
int get_object_catcache_oid(Oid class_id)
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:804
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:175
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define RelationGetRelid(relation)
Definition: rel.h:477
#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 929 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().

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

◆ get_object_address_attrdef()

static ObjectAddress get_object_address_attrdef ( ObjectType  objtype,
List object,
Relation relp,
LOCKMODE  lockmode,
bool  missing_ok 
)
static

Definition at line 1544 of file objectaddress.c.

References AccessShareLock, attname, attnum, BTEqualStrategyNumber, ObjectAddress::classId, TupleDescData::constr, ereport, errcode(), errmsg(), ERROR, get_attnum(), GETSTRUCT, HeapTupleIsValid, Int16GetDatum, InvalidAttrNumber, InvalidOid, list_copy(), list_length(), list_truncate(), llast, makeRangeVarFromNameList(), NameListToString(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, relation_close(), relation_open(), relation_openrv(), RelationGetDescr, RelationGetRelid, relname, ScanKeyInit(), strVal, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address().

1547 {
1548  ObjectAddress address;
1549  List *relname;
1550  Oid reloid;
1551  Relation relation;
1552  const char *attname;
1554  TupleDesc tupdesc;
1555  Oid defoid;
1556 
1557  /* Extract relation name and open relation. */
1558  if (list_length(object) < 2)
1559  ereport(ERROR,
1560  (errcode(ERRCODE_SYNTAX_ERROR),
1561  errmsg("column name must be qualified")));
1562  attname = strVal(llast(object));
1563  relname = list_truncate(list_copy(object), list_length(object) - 1);
1564  /* XXX no missing_ok support here */
1565  relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
1566  reloid = RelationGetRelid(relation);
1567 
1568  tupdesc = RelationGetDescr(relation);
1569 
1570  /* Look up attribute number and scan pg_attrdef to find its tuple */
1571  attnum = get_attnum(reloid, attname);
1572  defoid = InvalidOid;
1573  if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
1574  {
1575  Relation attrdef;
1576  ScanKeyData keys[2];
1577  SysScanDesc scan;
1578  HeapTuple tup;
1579 
1580  attrdef = relation_open(AttrDefaultRelationId, AccessShareLock);
1581  ScanKeyInit(&keys[0],
1582  Anum_pg_attrdef_adrelid,
1584  F_OIDEQ,
1585  ObjectIdGetDatum(reloid));
1586  ScanKeyInit(&keys[1],
1587  Anum_pg_attrdef_adnum,
1589  F_INT2EQ,
1590  Int16GetDatum(attnum));
1591  scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
1592  NULL, 2, keys);
1593  if (HeapTupleIsValid(tup = systable_getnext(scan)))
1594  {
1595  Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
1596 
1597  defoid = atdform->oid;
1598  }
1599 
1600  systable_endscan(scan);
1601  relation_close(attrdef, AccessShareLock);
1602  }
1603  if (!OidIsValid(defoid))
1604  {
1605  if (!missing_ok)
1606  ereport(ERROR,
1607  (errcode(ERRCODE_UNDEFINED_COLUMN),
1608  errmsg("default value for column \"%s\" of relation \"%s\" does not exist",
1609  attname, NameListToString(relname))));
1610 
1611  address.classId = AttrDefaultRelationId;
1612  address.objectId = InvalidOid;
1613  address.objectSubId = InvalidAttrNumber;
1614  relation_close(relation, lockmode);
1615  return address;
1616  }
1617 
1618  address.classId = AttrDefaultRelationId;
1619  address.objectId = defoid;
1620  address.objectSubId = 0;
1621 
1622  *relp = relation;
1623  return address;
1624 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define RelationGetDescr(relation)
Definition: rel.h:503
#define llast(l)
Definition: pg_list.h:194
#define Int16GetDatum(X)
Definition: postgres.h:495
List * list_truncate(List *list, int new_size)
Definition: list.c:600
#define AccessShareLock
Definition: lockdefs.h:36
List * list_copy(const List *oldlist)
Definition: list.c:1418
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
NameData attname
Definition: pg_attribute.h:41
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:856
TupleConstr * constr
Definition: tupdesc.h:85
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:48
char * NameListToString(List *names)
Definition: namespace.c:3147
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:138
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:83
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
static int list_length(const List *l)
Definition: pg_list.h:149
#define InvalidAttrNumber
Definition: attnum.h:23
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Definition: pg_list.h:50
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:477
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_object_address_attribute()

static ObjectAddress get_object_address_attribute ( ObjectType  objtype,
List object,
Relation relp,
LOCKMODE  lockmode,
bool  missing_ok 
)
static

Definition at line 1493 of file objectaddress.c.

References attname, attnum, ObjectAddress::classId, ereport, errcode(), errmsg(), ERROR, get_attnum(), InvalidAttrNumber, InvalidOid, list_copy(), list_length(), list_truncate(), llast, makeRangeVarFromNameList(), NameListToString(), ObjectAddress::objectId, ObjectAddress::objectSubId, relation_close(), relation_openrv(), RelationGetRelid, relname, and strVal.

Referenced by get_object_address().

1496 {
1497  ObjectAddress address;
1498  List *relname;
1499  Oid reloid;
1500  Relation relation;
1501  const char *attname;
1503 
1504  /* Extract relation name and open relation. */
1505  if (list_length(object) < 2)
1506  ereport(ERROR,
1507  (errcode(ERRCODE_SYNTAX_ERROR),
1508  errmsg("column name must be qualified")));
1509  attname = strVal(llast(object));
1510  relname = list_truncate(list_copy(object), list_length(object) - 1);
1511  /* XXX no missing_ok support here */
1512  relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
1513  reloid = RelationGetRelid(relation);
1514 
1515  /* Look up attribute and construct return value. */
1516  attnum = get_attnum(reloid, attname);
1517  if (attnum == InvalidAttrNumber)
1518  {
1519  if (!missing_ok)
1520  ereport(ERROR,
1521  (errcode(ERRCODE_UNDEFINED_COLUMN),
1522  errmsg("column \"%s\" of relation \"%s\" does not exist",
1523  attname, NameListToString(relname))));
1524 
1525  address.classId = RelationRelationId;
1526  address.objectId = InvalidOid;
1527  address.objectSubId = InvalidAttrNumber;
1528  relation_close(relation, lockmode);
1529  return address;
1530  }
1531 
1532  address.classId = RelationRelationId;
1533  address.objectId = reloid;
1534  address.objectSubId = attnum;
1535 
1536  *relp = relation;
1537  return address;
1538 }
#define llast(l)
Definition: pg_list.h:194
List * list_truncate(List *list, int new_size)
Definition: list.c:600
List * list_copy(const List *oldlist)
Definition: list.c:1418
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
NameData attname
Definition: pg_attribute.h:41
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:856
char * NameListToString(List *names)
Definition: namespace.c:3147
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:138
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:83
#define ereport(elevel,...)
Definition: elog.h:157
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
static int list_length(const List *l)
Definition: pg_list.h:149
#define InvalidAttrNumber
Definition: attnum.h:23
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: pg_list.h:50
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:477

◆ get_object_address_defacl()

static ObjectAddress get_object_address_defacl ( List object,
bool  missing_ok 
)
static

Definition at line 1942 of file objectaddress.c.

References AUTHNAME, CharGetDatum, CStringGetDatum, DEFACLROLENSPOBJ, ereport, errcode(), errhint(), errmsg(), ERROR, get_namespace_oid(), GETSTRUCT, HeapTupleIsValid, InvalidOid, linitial, list_length(), lsecond, lthird, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), SearchSysCache3(), strVal, and username.

Referenced by get_object_address().

1943 {
1944  HeapTuple tp;
1945  Oid userid;
1946  Oid schemaid;
1947  char *username;
1948  char *schema;
1949  char objtype;
1950  char *objtype_str;
1951  ObjectAddress address;
1952 
1953  ObjectAddressSet(address, DefaultAclRelationId, InvalidOid);
1954 
1955  /*
1956  * First figure out the textual attributes so that they can be used for
1957  * error reporting.
1958  */
1959  username = strVal(lsecond(object));
1960  if (list_length(object) >= 3)
1961  schema = (char *) strVal(lthird(object));
1962  else
1963  schema = NULL;
1964 
1965  /*
1966  * Decode defaclobjtype. Only first char is considered; the rest of the
1967  * string, if any, is blissfully ignored.
1968  */
1969  objtype = ((char *) strVal(linitial(object)))[0];
1970  switch (objtype)
1971  {
1972  case DEFACLOBJ_RELATION:
1973  objtype_str = "tables";
1974  break;
1975  case DEFACLOBJ_SEQUENCE:
1976  objtype_str = "sequences";
1977  break;
1978  case DEFACLOBJ_FUNCTION:
1979  objtype_str = "functions";
1980  break;
1981  case DEFACLOBJ_TYPE:
1982  objtype_str = "types";
1983  break;
1984  case DEFACLOBJ_NAMESPACE:
1985  objtype_str = "schemas";
1986  break;
1987  default:
1988  ereport(ERROR,
1989  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1990  errmsg("unrecognized default ACL object type \"%c\"", objtype),
1991  errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
1992  DEFACLOBJ_RELATION,
1993  DEFACLOBJ_SEQUENCE,
1994  DEFACLOBJ_FUNCTION,
1995  DEFACLOBJ_TYPE,
1996  DEFACLOBJ_NAMESPACE)));
1997  }
1998 
1999  /*
2000  * Look up user ID. Behave as "default ACL not found" if the user doesn't
2001  * exist.
2002  */
2004  CStringGetDatum(username));
2005  if (!HeapTupleIsValid(tp))
2006  goto not_found;
2007  userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
2008  ReleaseSysCache(tp);
2009 
2010  /*
2011  * If a schema name was given, look up its OID. If it doesn't exist,
2012  * behave as "default ACL not found".
2013  */
2014  if (schema)
2015  {
2016  schemaid = get_namespace_oid(schema, true);
2017  if (schemaid == InvalidOid)
2018  goto not_found;
2019  }
2020  else
2021  schemaid = InvalidOid;
2022 
2023  /* Finally, look up the pg_default_acl object */
2025  ObjectIdGetDatum(userid),
2026  ObjectIdGetDatum(schemaid),
2027  CharGetDatum(objtype));
2028  if (!HeapTupleIsValid(tp))
2029  goto not_found;
2030 
2031  address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid;
2032  ReleaseSysCache(tp);
2033 
2034  return address;
2035 
2036 not_found:
2037  if (!missing_ok)
2038  {
2039  if (schema)
2040  ereport(ERROR,
2041  (errcode(ERRCODE_UNDEFINED_OBJECT),
2042  errmsg("default ACL for user \"%s\" in schema \"%s\" on %s does not exist",
2043  username, schema, objtype_str)));
2044  else
2045  ereport(ERROR,
2046  (errcode(ERRCODE_UNDEFINED_OBJECT),
2047  errmsg("default ACL for user \"%s\" on %s does not exist",
2048  username, objtype_str)));
2049  }
2050  return address;
2051 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
int errhint(const char *fmt,...)
Definition: elog.c:1156
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:179
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1149
FormData_pg_default_acl * Form_pg_default_acl
#define CStringGetDatum(X)
Definition: postgres.h:622
const char * username
Definition: pgbench.c:282
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static int list_length(const List *l)
Definition: pg_list.h:149
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define CharGetDatum(X)
Definition: postgres.h:460
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lthird(l)
Definition: pg_list.h:184

◆ get_object_address_opcf()

static ObjectAddress get_object_address_opcf ( ObjectType  objtype,
List object,
bool  missing_ok 
)
static

Definition at line 1669 of file objectaddress.c.

References ObjectAddress::classId, elog, ERROR, get_index_am_oid(), get_opclass_oid(), get_opfamily_oid(), InvalidOid, linitial, list_copy_tail(), OBJECT_OPCLASS, OBJECT_OPFAMILY, ObjectAddress::objectId, ObjectAddress::objectSubId, and strVal.

Referenced by get_object_address(), and get_object_address_opf_member().

1670 {
1671  Oid amoid;
1672  ObjectAddress address;
1673 
1674  /* XXX no missing_ok support here */
1675  amoid = get_index_am_oid(strVal(linitial(object)), false);
1676  object = list_copy_tail(object, 1);
1677 
1678  switch (objtype)
1679  {
1680  case OBJECT_OPCLASS:
1681  address.classId = OperatorClassRelationId;
1682  address.objectId = get_opclass_oid(amoid, object, missing_ok);
1683  address.objectSubId = 0;
1684  break;
1685  case OBJECT_OPFAMILY:
1686  address.classId = OperatorFamilyRelationId;
1687  address.objectId = get_opfamily_oid(amoid, object, missing_ok);
1688  address.objectSubId = 0;
1689  break;
1690  default:
1691  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1692  /* placate compiler, which doesn't know elog won't return */
1693  address.classId = InvalidOid;
1694  address.objectId = InvalidOid;
1695  address.objectSubId = 0;
1696  }
1697 
1698  return address;
1699 }
#define strVal(v)
Definition: value.h:65
Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
Definition: opclasscmds.c:220
List * list_copy_tail(const List *oldlist, int nskip)
Definition: list.c:1437
unsigned int Oid
Definition: postgres_ext.h:31
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
Oid get_index_am_oid(const char *amname, bool missing_ok)
Definition: amcmds.c:163
#define InvalidOid
Definition: postgres_ext.h:36
Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
Definition: opclasscmds.c:139
#define elog(elevel,...)
Definition: elog.h:232

◆ get_object_address_opf_member()

static ObjectAddress get_object_address_opf_member ( ObjectType  objtype,
List object,
bool  missing_ok 
)
static

Definition at line 1707 of file objectaddress.c.

References AMOPSTRATEGY, AMPROCNUM, elog, ereport, errcode(), errmsg(), ERROR, get_object_address_opcf(), get_object_address_type(), getObjectDescription(), GETSTRUCT, HeapTupleIsValid, i, Int16GetDatum, InvalidOid, lfirst_node, linitial, list_copy(), list_length(), list_truncate(), llast, lsecond, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_OPFAMILY, OBJECT_TYPE, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache4(), strVal, and TypeNameToString().

Referenced by get_object_address().

1709 {
1710  ObjectAddress famaddr;
1711  ObjectAddress address;
1712  ListCell *cell;
1713  List *copy;
1714  TypeName *typenames[2];
1715  Oid typeoids[2];
1716  int membernum;
1717  int i;
1718 
1719  /*
1720  * The last element of the object list contains the strategy or procedure
1721  * number. We need to strip that out before getting the opclass/family
1722  * address. The rest can be used directly by get_object_address_opcf().
1723  */
1724  membernum = atoi(strVal(llast(linitial(object))));
1725  copy = list_truncate(list_copy(linitial(object)), list_length(linitial(object)) - 1);
1726 
1727  /* no missing_ok support here */
1728  famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false);
1729 
1730  /* find out left/right type names and OIDs */
1731  typenames[0] = typenames[1] = NULL;
1732  typeoids[0] = typeoids[1] = InvalidOid;
1733  i = 0;
1734  foreach(cell, lsecond(object))
1735  {
1736  ObjectAddress typaddr;
1737 
1738  typenames[i] = lfirst_node(TypeName, cell);
1739  typaddr = get_object_address_type(OBJECT_TYPE, typenames[i], missing_ok);
1740  typeoids[i] = typaddr.objectId;
1741  if (++i >= 2)
1742  break;
1743  }
1744 
1745  switch (objtype)
1746  {
1747  case OBJECT_AMOP:
1748  {
1749  HeapTuple tp;
1750 
1751  ObjectAddressSet(address, AccessMethodOperatorRelationId,
1752  InvalidOid);
1753 
1755  ObjectIdGetDatum(famaddr.objectId),
1756  ObjectIdGetDatum(typeoids[0]),
1757  ObjectIdGetDatum(typeoids[1]),
1758  Int16GetDatum(membernum));
1759  if (!HeapTupleIsValid(tp))
1760  {
1761  if (!missing_ok)
1762  ereport(ERROR,
1763  (errcode(ERRCODE_UNDEFINED_OBJECT),
1764  errmsg("operator %d (%s, %s) of %s does not exist",
1765  membernum,
1766  TypeNameToString(typenames[0]),
1767  TypeNameToString(typenames[1]),
1768  getObjectDescription(&famaddr, false))));
1769  }
1770  else
1771  {
1772  address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
1773  ReleaseSysCache(tp);
1774  }
1775  }
1776  break;
1777 
1778  case OBJECT_AMPROC:
1779  {
1780  HeapTuple tp;
1781 
1782  ObjectAddressSet(address, AccessMethodProcedureRelationId,
1783  InvalidOid);
1784 
1786  ObjectIdGetDatum(famaddr.objectId),
1787  ObjectIdGetDatum(typeoids[0]),
1788  ObjectIdGetDatum(typeoids[1]),
1789  Int16GetDatum(membernum));
1790  if (!HeapTupleIsValid(tp))
1791  {
1792  if (!missing_ok)
1793  ereport(ERROR,
1794  (errcode(ERRCODE_UNDEFINED_OBJECT),
1795  errmsg("function %d (%s, %s) of %s does not exist",
1796  membernum,
1797  TypeNameToString(typenames[0]),
1798  TypeNameToString(typenames[1]),
1799  getObjectDescription(&famaddr, false))));
1800  }
1801  else
1802  {
1803  address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
1804  ReleaseSysCache(tp);
1805  }
1806  }
1807  break;
1808  default:
1809  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1810  }
1811 
1812  return address;
1813 }
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:480
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
#define llast(l)
Definition: pg_list.h:194
#define Int16GetDatum(X)
Definition: postgres.h:495
List * list_truncate(List *list, int new_size)
Definition: list.c:600
List * list_copy(const List *oldlist)
Definition: list.c:1418
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
#define lfirst_node(type, lc)
Definition: pg_list.h:172
static ObjectAddress get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1160
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static int list_length(const List *l)
Definition: pg_list.h:149
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:909
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
#define elog(elevel,...)
Definition: elog.h:232
int i
Definition: pg_list.h:50

◆ get_object_address_publication_rel()

static ObjectAddress get_object_address_publication_rel ( List object,
Relation relp,
bool  missing_ok 
)
static

Definition at line 1890 of file objectaddress.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, GetPublicationByName(), GetSysCacheOid2, InvalidOid, linitial, lsecond, makeRangeVarFromNameList(), ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, Publication::oid, OidIsValid, PUBLICATIONRELMAP, relation_close(), relation_openrv_extended(), RelationGetRelationName, RelationGetRelid, relname, and strVal.

Referenced by get_object_address().

1892 {
1893  ObjectAddress address;
1894  Relation relation;
1895  List *relname;
1896  char *pubname;
1897  Publication *pub;
1898 
1899  ObjectAddressSet(address, PublicationRelRelationId, InvalidOid);
1900 
1901  relname = linitial(object);
1903  AccessShareLock, missing_ok);
1904  if (!relation)
1905  return address;
1906 
1907  /* fetch publication name from input list */
1908  pubname = strVal(lsecond(object));
1909 
1910  /* Now look up the pg_publication tuple */
1911  pub = GetPublicationByName(pubname, missing_ok);
1912  if (!pub)
1913  {
1914  relation_close(relation, AccessShareLock);
1915  return address;
1916  }
1917 
1918  /* Find the publication relation mapping in syscache. */
1919  address.objectId =
1920  GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid,
1922  ObjectIdGetDatum(pub->oid));
1923  if (!OidIsValid(address.objectId))
1924  {
1925  if (!missing_ok)
1926  ereport(ERROR,
1927  (errcode(ERRCODE_UNDEFINED_OBJECT),
1928  errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
1929  RelationGetRelationName(relation), pubname)));
1930  relation_close(relation, AccessShareLock);
1931  return address;
1932  }
1933 
1934  *relp = relation;
1935  return address;
1936 }
#define AccessShareLock
Definition: lockdefs.h:36
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
#define OidIsValid(objectId)
Definition: c.h:710
Publication * GetPublicationByName(const char *pubname, bool missing_ok)
#define lsecond(l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:477
Relation relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition: relation.c:173

◆ get_object_address_relobject()

static ObjectAddress get_object_address_relobject ( ObjectType  objtype,
List object,
Relation relp,
bool  missing_ok 
)
static

Definition at line 1414 of file objectaddress.c.

References AccessShareLock, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, get_relation_constraint_oid(), get_relation_policy_oid(), get_rewrite_oid(), get_trigger_oid(), InvalidOid, list_copy(), list_length(), list_truncate(), llast, makeRangeVarFromNameList(), OBJECT_POLICY, OBJECT_RULE, OBJECT_TABCONSTRAINT, OBJECT_TRIGGER, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, RelationGetRelid, relname, strVal, table_close(), and table_openrv_extended().

Referenced by get_object_address().

1416 {
1417  ObjectAddress address;
1418  Relation relation = NULL;
1419  int nnames;
1420  const char *depname;
1421  List *relname;
1422  Oid reloid;
1423 
1424  /* Extract name of dependent object. */
1425  depname = strVal(llast(object));
1426 
1427  /* Separate relation name from dependent object name. */
1428  nnames = list_length(object);
1429  if (nnames < 2)
1430  ereport(ERROR,
1431  (errcode(ERRCODE_SYNTAX_ERROR),
1432  errmsg("must specify relation and object name")));
1433 
1434  /* Extract relation name and open relation. */
1435  relname = list_truncate(list_copy(object), nnames - 1);
1436  relation = table_openrv_extended(makeRangeVarFromNameList(relname),
1438  missing_ok);
1439 
1440  reloid = relation ? RelationGetRelid(relation) : InvalidOid;
1441 
1442  switch (objtype)
1443  {
1444  case OBJECT_RULE:
1445  address.classId = RewriteRelationId;
1446  address.objectId = relation ?
1447  get_rewrite_oid(reloid, depname, missing_ok) : InvalidOid;
1448  address.objectSubId = 0;
1449  break;
1450  case OBJECT_TRIGGER:
1451  address.classId = TriggerRelationId;
1452  address.objectId = relation ?
1453  get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
1454  address.objectSubId = 0;
1455  break;
1456  case OBJECT_TABCONSTRAINT:
1457  address.classId = ConstraintRelationId;
1458  address.objectId = relation ?
1459  get_relation_constraint_oid(reloid, depname, missing_ok) :
1460  InvalidOid;
1461  address.objectSubId = 0;
1462  break;
1463  case OBJECT_POLICY:
1464  address.classId = PolicyRelationId;
1465  address.objectId = relation ?
1466  get_relation_policy_oid(reloid, depname, missing_ok) :
1467  InvalidOid;
1468  address.objectSubId = 0;
1469  break;
1470  default:
1471  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1472  }
1473 
1474  /* Avoid relcache leak when object not found. */
1475  if (!OidIsValid(address.objectId))
1476  {
1477  if (relation != NULL)
1478  table_close(relation, AccessShareLock);
1479 
1480  relation = NULL; /* department of accident prevention */
1481  return address;
1482  }
1483 
1484  /* Done. */
1485  *relp = relation;
1486  return address;
1487 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Relation table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition: table.c:132
Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)
#define llast(l)
Definition: pg_list.h:194
List * list_truncate(List *list, int new_size)
Definition: list.c:600
#define AccessShareLock
Definition: lockdefs.h:36
List * list_copy(const List *oldlist)
Definition: list.c:1418
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
Oid get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
Definition: policy.c:1210
static int list_length(const List *l)
Definition: pg_list.h:149
Oid get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
Definition: trigger.c:1330
Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
Definition: pg_list.h:50
#define RelationGetRelid(relation)
Definition: rel.h:477

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

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

Referenced by ExecAlterObjectDependsStmt().

1227 {
1228  if (rel)
1229  {
1230  object = lcons(makeString(rel->relname), object);
1231  if (rel->schemaname)
1232  object = lcons(makeString(rel->schemaname), object);
1233  if (rel->catalogname)
1234  object = lcons(makeString(rel->catalogname), object);
1235  }
1236 
1237  return get_object_address(objtype, (Node *) object,
1238  relp, lockmode, missing_ok);
1239 }
Definition: nodes.h:537
String * makeString(char *str)
Definition: value.c:51
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
List * lcons(void *datum, List *list)
Definition: list.c:468
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
char * catalogname
Definition: primnodes.h:66

◆ get_object_address_type()

static ObjectAddress get_object_address_type ( ObjectType  objtype,
TypeName typename,
bool  missing_ok 
)
static

Definition at line 1630 of file objectaddress.c.

References ObjectAddress::classId, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, InvalidOid, LookupTypeName(), OBJECT_DOMAIN, ObjectAddress::objectId, ObjectAddress::objectSubId, ReleaseSysCache(), TypeNameToString(), and typeTypeId().

Referenced by get_object_address(), and get_object_address_opf_member().

1631 {
1632  ObjectAddress address;
1633  Type tup;
1634 
1635  address.classId = TypeRelationId;
1636  address.objectId = InvalidOid;
1637  address.objectSubId = 0;
1638 
1639  tup = LookupTypeName(NULL, typename, NULL, missing_ok);
1640  if (!HeapTupleIsValid(tup))
1641  {
1642  if (!missing_ok)
1643  ereport(ERROR,
1644  (errcode(ERRCODE_UNDEFINED_OBJECT),
1645  errmsg("type \"%s\" does not exist",
1646  TypeNameToString(typename))));
1647  return address;
1648  }
1649  address.objectId = typeTypeId(tup);
1650 
1651  if (objtype == OBJECT_DOMAIN)
1652  {
1653  if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN)
1654  ereport(ERROR,
1655  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1656  errmsg("\"%s\" is not a domain",
1657  TypeNameToString(typename))));
1658  }
1659 
1660  ReleaseSysCache(tup);
1661 
1662  return address;
1663 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:38
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:480
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
int errmsg(const char *fmt,...)
Definition: elog.c:909
Oid typeTypeId(Type tp)
Definition: parse_type.c:592

◆ get_object_address_unqualified()

static ObjectAddress get_object_address_unqualified ( ObjectType  objtype,
String strval,
bool  missing_ok 
)
static

Definition at line 1246 of file objectaddress.c.

References ObjectAddress::classId, elog, ERROR, get_am_oid(), get_database_oid(), get_event_trigger_oid(), get_extension_oid(), get_foreign_data_wrapper_oid(), get_foreign_server_oid(), get_language_oid(), get_namespace_oid(), get_publication_oid(), get_role_oid(), get_subscription_oid(), get_tablespace_oid(), InvalidOid, name, OBJECT_ACCESS_METHOD, OBJECT_DATABASE, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_LANGUAGE, OBJECT_PUBLICATION, OBJECT_ROLE, OBJECT_SCHEMA, OBJECT_SUBSCRIPTION, OBJECT_TABLESPACE, ObjectAddress::objectId, ObjectAddress::objectSubId, and strVal.

Referenced by get_object_address().

1248 {
1249  const char *name;
1250  ObjectAddress address;
1251 
1252  name = strVal(strval);
1253 
1254  /* Translate name to OID. */
1255  switch (objtype)
1256  {
1257  case OBJECT_ACCESS_METHOD:
1258  address.classId = AccessMethodRelationId;
1259  address.objectId = get_am_oid(name, missing_ok);
1260  address.objectSubId = 0;
1261  break;
1262  case OBJECT_DATABASE:
1263  address.classId = DatabaseRelationId;
1264  address.objectId = get_database_oid(name, missing_ok);
1265  address.objectSubId = 0;
1266  break;
1267  case OBJECT_EXTENSION:
1268  address.classId = ExtensionRelationId;
1269  address.objectId = get_extension_oid(name, missing_ok);
1270  address.objectSubId = 0;
1271  break;
1272  case OBJECT_TABLESPACE:
1273  address.classId = TableSpaceRelationId;
1274  address.objectId = get_tablespace_oid(name, missing_ok);
1275  address.objectSubId = 0;
1276  break;
1277  case OBJECT_ROLE:
1278  address.classId = AuthIdRelationId;
1279  address.objectId = get_role_oid(name, missing_ok);
1280  address.objectSubId = 0;
1281  break;
1282  case OBJECT_SCHEMA:
1283  address.classId = NamespaceRelationId;
1284  address.objectId = get_namespace_oid(name, missing_ok);
1285  address.objectSubId = 0;
1286  break;
1287  case OBJECT_LANGUAGE:
1288  address.classId = LanguageRelationId;
1289  address.objectId = get_language_oid(name, missing_ok);
1290  address.objectSubId = 0;
1291  break;
1292  case OBJECT_FDW:
1293  address.classId = ForeignDataWrapperRelationId;
1294  address.objectId = get_foreign_data_wrapper_oid(name, missing_ok);
1295  address.objectSubId = 0;
1296  break;
1297  case OBJECT_FOREIGN_SERVER:
1298  address.classId = ForeignServerRelationId;
1299  address.objectId = get_foreign_server_oid(name, missing_ok);
1300  address.objectSubId = 0;
1301  break;
1302  case OBJECT_EVENT_TRIGGER:
1303  address.classId = EventTriggerRelationId;
1304  address.objectId = get_event_trigger_oid(name, missing_ok);
1305  address.objectSubId = 0;
1306  break;
1307  case OBJECT_PUBLICATION:
1308  address.classId = PublicationRelationId;
1309  address.objectId = get_publication_oid(name, missing_ok);
1310  address.objectSubId = 0;
1311  break;
1312  case OBJECT_SUBSCRIPTION:
1313  address.classId = SubscriptionRelationId;
1314  address.objectId = get_subscription_oid(name, missing_ok);
1315  address.objectSubId = 0;
1316  break;
1317  default:
1318  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1319  /* placate compiler, which doesn't know elog won't return */
1320  address.classId = InvalidOid;
1321  address.objectId = InvalidOid;
1322  address.objectSubId = 0;
1323  }
1324 
1325  return address;
1326 }
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
Definition: tablespace.c:1427
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
Oid get_am_oid(const char *amname, bool missing_ok)
Definition: amcmds.c:183
Oid get_language_oid(const char *langname, bool missing_ok)
Definition: proclang.c:228
#define strVal(v)
Definition: value.h:65
Oid get_event_trigger_oid(const char *trigname, bool missing_ok)
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5094
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Definition: foreign.c:691
#define ERROR
Definition: elog.h:46
#define InvalidOid
Definition: postgres_ext.h:36
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2066
Oid get_subscription_oid(const char *subname, bool missing_ok)
const char * name
Definition: encode.c:561
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:140
#define elog(elevel,...)
Definition: elog.h:232
Oid get_publication_oid(const char *pubname, bool missing_ok)
Oid get_foreign_server_oid(const char *servername, bool missing_ok)
Definition: foreign.c:714

◆ get_object_address_usermapping()

static ObjectAddress get_object_address_usermapping ( List object,
bool  missing_ok 
)
static

Definition at line 1819 of file objectaddress.c.

References AUTHNAME, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetForeignServerByName(), GETSTRUCT, HeapTupleIsValid, InvalidOid, linitial, lsecond, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), SearchSysCache2(), ForeignServer::serverid, strVal, and username.

Referenced by get_object_address().

1820 {
1821  ObjectAddress address;
1822  Oid userid;
1823  char *username;
1824  char *servername;
1825  ForeignServer *server;
1826  HeapTuple tp;
1827 
1828  ObjectAddressSet(address, UserMappingRelationId, InvalidOid);
1829 
1830  /* fetch string names from input lists, for error messages */
1831  username = strVal(linitial(object));
1832  servername = strVal(lsecond(object));
1833 
1834  /* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
1835  if (strcmp(username, "public") == 0)
1836  userid = InvalidOid;
1837  else
1838  {
1840  CStringGetDatum(username));
1841  if (!HeapTupleIsValid(tp))
1842  {
1843  if (!missing_ok)
1844  ereport(ERROR,
1845  (errcode(ERRCODE_UNDEFINED_OBJECT),
1846  errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1847  username, servername)));
1848  return address;
1849  }
1850  userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
1851  ReleaseSysCache(tp);
1852  }
1853 
1854  /* Now look up the pg_user_mapping tuple */
1855  server = GetForeignServerByName(servername, true);
1856  if (!server)
1857  {
1858  if (!missing_ok)
1859  ereport(ERROR,
1860  (errcode(ERRCODE_UNDEFINED_OBJECT),
1861  errmsg("server \"%s\" does not exist", servername)));
1862  return address;
1863  }
1864  tp = SearchSysCache2(USERMAPPINGUSERSERVER,
1865  ObjectIdGetDatum(userid),
1866  ObjectIdGetDatum(server->serverid));
1867  if (!HeapTupleIsValid(tp))
1868  {
1869  if (!missing_ok)
1870  ereport(ERROR,
1871  (errcode(ERRCODE_UNDEFINED_OBJECT),
1872  errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1873  username, servername)));
1874  return address;
1875  }
1876 
1877  address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
1878 
1879  ReleaseSysCache(tp);
1880 
1881  return address;
1882 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:179
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
FormData_pg_user_mapping * Form_pg_user_mapping
#define CStringGetDatum(X)
Definition: postgres.h:622
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition: foreign.c:180
const char * username
Definition: pgbench.c:282
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1138
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:909
Oid serverid
Definition: foreign.h:36

◆ get_object_attnum_acl()

AttrNumber get_object_attnum_acl ( Oid  class_id)

Definition at line 2713 of file objectaddress.c.

References ObjectPropertyType::attnum_acl, and get_object_property_data().

Referenced by AlterObjectOwner_internal().

2714 {
2715  const ObjectPropertyType *prop = get_object_property_data(class_id);
2716 
2717  return prop->attnum_acl;
2718 }
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 2689 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().

2690 {
2691  const ObjectPropertyType *prop = get_object_property_data(class_id);
2692 
2693  return prop->attnum_name;
2694 }
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 2697 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().

2698 {
2699  const ObjectPropertyType *prop = get_object_property_data(class_id);
2700 
2701  return prop->attnum_namespace;
2702 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)
AttrNumber attnum_namespace

◆ get_object_attnum_oid()

AttrNumber get_object_attnum_oid ( Oid  class_id)

Definition at line 2681 of file objectaddress.c.

References ObjectPropertyType::attnum_oid, and get_object_property_data().

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

2682 {
2683  const ObjectPropertyType *prop = get_object_property_data(class_id);
2684 
2685  return prop->attnum_oid;
2686 }
AttrNumber attnum_oid
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_attnum_owner()

AttrNumber get_object_attnum_owner ( Oid  class_id)

Definition at line 2705 of file objectaddress.c.

References ObjectPropertyType::attnum_owner, and get_object_property_data().

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

2706 {
2707  const ObjectPropertyType *prop = get_object_property_data(class_id);
2708 
2709  return prop->attnum_owner;
2710 }
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 2673 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::name_catcache_id.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

2674 {
2675  const ObjectPropertyType *prop = get_object_property_data(class_id);
2676 
2677  return prop->name_catcache_id;
2678 }
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 2665 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::oid_catcache_id.

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

2666 {
2667  const ObjectPropertyType *prop = get_object_property_data(class_id);
2668 
2669  return prop->oid_catcache_id;
2670 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_class_descr()

const char* get_object_class_descr ( Oid  class_id)

Definition at line 2649 of file objectaddress.c.

References ObjectPropertyType::class_descr, and get_object_property_data().

Referenced by DropObjectById().

2650 {
2651  const ObjectPropertyType *prop = get_object_property_data(class_id);
2652 
2653  return prop->class_descr;
2654 }
const char * class_descr
Definition: objectaddress.c:99
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 2746 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::is_nsp_name_unique.

Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().

2747 {
2748  const ObjectPropertyType *prop = get_object_property_data(class_id);
2749 
2750  return prop->is_nsp_name_unique;
2751 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_namespace()

Oid get_object_namespace ( const ObjectAddress address)

Definition at line 2590 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().

2591 {
2592  int cache;
2593  HeapTuple tuple;
2594  bool isnull;
2595  Oid oid;
2596  const ObjectPropertyType *property;
2597 
2598  /* If not owned by a namespace, just return InvalidOid. */
2599  property = get_object_property_data(address->classId);
2600  if (property->attnum_namespace == InvalidAttrNumber)
2601  return InvalidOid;
2602 
2603  /* Currently, we can only handle object types with system caches. */
2604  cache = property->oid_catcache_id;
2605  Assert(cache != -1);
2606 
2607  /* Fetch tuple from syscache and extract namespace attribute. */
2608  tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
2609  if (!HeapTupleIsValid(tuple))
2610  elog(ERROR, "cache lookup failed for cache %d oid %u",
2611  cache, address->objectId);
2612  oid = DatumGetObjectId(SysCacheGetAttr(cache,
2613  tuple,
2614  property->attnum_namespace,
2615  &isnull));
2616  Assert(!isnull);
2617  ReleaseSysCache(tuple);
2618 
2619  return oid;
2620 }
#define DatumGetObjectId(X)
Definition: postgres.h:544
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
static const ObjectPropertyType * get_object_property_data(Oid class_id)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1388
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:804
AttrNumber attnum_namespace
#define InvalidAttrNumber
Definition: attnum.h:23
#define elog(elevel,...)
Definition: elog.h:232

◆ get_object_oid_index()

Oid get_object_oid_index ( Oid  class_id)

Definition at line 2657 of file objectaddress.c.

References get_object_property_data(), and ObjectPropertyType::oid_index_oid.

Referenced by DropObjectById(), and get_catalog_object_by_oid().

2658 {
2659  const ObjectPropertyType *prop = get_object_property_data(class_id);
2660 
2661  return prop->oid_index_oid;
2662 }
static const ObjectPropertyType * get_object_property_data(Oid class_id)

◆ get_object_property_data()

static const ObjectPropertyType * get_object_property_data ( Oid  class_id)
static

Definition at line 2775 of file objectaddress.c.

References ObjectPropertyType::class_oid, ereport, errmsg_internal(), ERROR, and lengthof.

Referenced by get_object_attnum_acl(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_oid(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), get_object_class_descr(), get_object_namensp_unique(), get_object_namespace(), get_object_oid_index(), and get_object_type().

2776 {
2777  static const ObjectPropertyType *prop_last = NULL;
2778  int index;
2779 
2780  /*
2781  * A shortcut to speed up multiple consecutive lookups of a particular
2782  * object class.
2783  */
2784  if (prop_last && prop_last->class_oid == class_id)
2785  return prop_last;
2786 
2787  for (index = 0; index < lengthof(ObjectProperty); index++)
2788  {
2789  if (ObjectProperty[index].class_oid == class_id)
2790  {
2791  prop_last = &ObjectProperty[index];
2792  return &ObjectProperty[index];
2793  }
2794  }
2795 
2796  ereport(ERROR,
2797  (errmsg_internal("unrecognized class ID: %u", class_id)));
2798 
2799  return NULL; /* keep MSC compiler happy */
2800 }
#define lengthof(array)
Definition: c.h:734
Definition: type.h:89
#define ERROR
Definition: elog.h:46
static const ObjectPropertyType ObjectProperty[]
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996

◆ get_object_type()

ObjectType get_object_type ( Oid  class_id,
Oid  object_id 
)

Definition at line 2728 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().

2729 {
2730  const ObjectPropertyType *prop = get_object_property_data(class_id);
2731 
2732  if (prop->objtype == OBJECT_TABLE)
2733  {
2734  /*
2735  * If the property data says it's a table, dig a little deeper to get
2736  * the real relation kind, so that callers can produce more precise
2737  * error messages.
2738  */
2739  return get_relkind_objtype(get_rel_relkind(object_id));
2740  }
2741  else
2742  return prop->objtype;
2743 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1974
static const ObjectPropertyType * get_object_property_data(Oid class_id)
ObjectType get_relkind_objtype(char relkind)

◆ get_relation_by_qualified_name()

static ObjectAddress get_relation_by_qualified_name ( ObjectType  objtype,
List object,
Relation relp,
LOCKMODE  lockmode,
bool  missing_ok 
)
static

Definition at line 1332 of file objectaddress.c.

References ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, InvalidOid, makeRangeVarFromNameList(), OBJECT_FOREIGN_TABLE, OBJECT_INDEX, OBJECT_MATVIEW, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_VIEW, ObjectAddress::objectId, ObjectAddress::objectSubId, RelationData::rd_rel, relation_openrv_extended(), RelationGetRelationName, and RelationGetRelid.

Referenced by get_object_address().

1335 {
1336  Relation relation;
1337  ObjectAddress address;
1338 
1339  address.classId = RelationRelationId;
1340  address.objectId = InvalidOid;
1341  address.objectSubId = 0;
1342 
1344  lockmode, missing_ok);
1345  if (!relation)
1346  return address;
1347 
1348  switch (objtype)
1349  {
1350  case OBJECT_INDEX:
1351  if (relation->rd_rel->relkind != RELKIND_INDEX &&
1352  relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
1353  ereport(ERROR,
1354  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1355  errmsg("\"%s\" is not an index",
1356  RelationGetRelationName(relation))));
1357  break;
1358  case OBJECT_SEQUENCE:
1359  if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
1360  ereport(ERROR,
1361  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1362  errmsg("\"%s\" is not a sequence",
1363  RelationGetRelationName(relation))));
1364  break;
1365  case OBJECT_TABLE:
1366  if (relation->rd_rel->relkind != RELKIND_RELATION &&
1367  relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1368  ereport(ERROR,
1369  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1370  errmsg("\"%s\" is not a table",
1371  RelationGetRelationName(relation))));
1372  break;
1373  case OBJECT_VIEW:
1374  if (relation->rd_rel->relkind != RELKIND_VIEW)
1375  ereport(ERROR,
1376  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1377  errmsg("\"%s\" is not a view",
1378  RelationGetRelationName(relation))));
1379  break;
1380  case OBJECT_MATVIEW:
1381  if (relation->rd_rel->relkind != RELKIND_MATVIEW)
1382  ereport(ERROR,
1383  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1384  errmsg("\"%s\" is not a materialized view",
1385  RelationGetRelationName(relation))));
1386  break;
1387  case OBJECT_FOREIGN_TABLE:
1388  if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
1389  ereport(ERROR,
1390  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1391  errmsg("\"%s\" is not a foreign table",
1392  RelationGetRelationName(relation))));
1393  break;
1394  default:
1395  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
1396  break;
1397  }
1398 
1399  /* Done. */
1400  address.objectId = RelationGetRelid(relation);
1401  *relp = relation;
1402 
1403  return address;
1404 }
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
Form_pg_class rd_rel
Definition: rel.h:109
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define RelationGetRelid(relation)
Definition: rel.h:477
Relation relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition: relation.c:173

◆ get_relkind_objtype()

ObjectType get_relkind_objtype ( char  relkind)

Definition at line 5937 of file objectaddress.c.

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

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

5938 {
5939  switch (relkind)
5940  {
5941  case RELKIND_RELATION:
5942  case RELKIND_PARTITIONED_TABLE:
5943  return OBJECT_TABLE;
5944  case RELKIND_INDEX:
5945  case RELKIND_PARTITIONED_INDEX:
5946  return OBJECT_INDEX;
5947  case RELKIND_SEQUENCE:
5948  return OBJECT_SEQUENCE;
5949  case RELKIND_VIEW:
5950  return OBJECT_VIEW;
5951  case RELKIND_MATVIEW:
5952  return OBJECT_MATVIEW;
5953  case RELKIND_FOREIGN_TABLE:
5954  return OBJECT_FOREIGN_TABLE;
5955  case RELKIND_TOASTVALUE:
5956  return OBJECT_TABLE;
5957  default:
5958  /* Per above, don't raise an error */
5959  return OBJECT_TABLE;
5960  }
5961 }

◆ getConstraintTypeDescription()

static void getConstraintTypeDescription ( StringInfo  buffer,
Oid  constroid,
bool  missing_ok 
)
static

Definition at line 4567 of file objectaddress.c.

References AccessShareLock, appendStringInfoString(), elog, ERROR, get_catalog_object_by_oid(), GETSTRUCT, HeapTupleIsValid, OidIsValid, table_close(), and table_open().

Referenced by getObjectTypeDescription().

4568 {
4569  Relation constrRel;
4570  HeapTuple constrTup;
4571  Form_pg_constraint constrForm;
4572 
4573  constrRel = table_open(ConstraintRelationId, AccessShareLock);
4574  constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid,
4575  constroid);
4576  if (!HeapTupleIsValid(constrTup))
4577  {
4578  if (!missing_ok)
4579  elog(ERROR, "cache lookup failed for constraint %u", constroid);
4580 
4581  table_close(constrRel, AccessShareLock);
4582 
4583  /* fallback to "constraint" for an undefined object */
4584  appendStringInfoString(buffer, "constraint");
4585  return;
4586  }
4587 
4588  constrForm = (Form_pg_constraint) GETSTRUCT(constrTup);
4589 
4590  if (OidIsValid(constrForm->conrelid))
4591  appendStringInfoString(buffer, "table constraint");
4592  else if (OidIsValid(constrForm->contypid))
4593  appendStringInfoString(buffer, "domain constraint");
4594  else
4595  elog(ERROR, "invalid constraint %u", constrForm->oid);
4596 
4597  table_close(constrRel, AccessShareLock);
4598 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define AccessShareLock
Definition: lockdefs.h:36
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:232
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ getObjectDescription()

char* getObjectDescription ( const ObjectAddress object,
bool  missing_ok 
)

Definition at line 2858 of file objectaddress.c.

References _, AccessShareLock, AMOID, appendStringInfo(), Assert, attname, BTEqualStrategyNumber, CLAOID, ObjectAddress::classId, CollationIsVisible(), COLLOID, CONSTROID, ConversionIsVisible(), CONVOID, StringInfoData::data, datname, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator(), format_operator_extended(), FORMAT_OPERATOR_INVALID_AS_NULL, FORMAT_PROC_INVALID_AS_NULL, format_procedure(), format_procedure_extended(), format_type_be(), format_type_extended(), FORMAT_TYPE_INVALID_AS_NULL, get_attname(), get_database_name(), get_extension_name(), get_language_name(), get_namespace_name(), get_publication_name(), get_subscription_name(), get_tablespace_name(), GetForeignDataWrapperExtended(), GetForeignServer(), GetForeignServerExtended(), getObjectClass(), getObjectDescription(), getOpFamilyDescription(), getRelationDescription(), GETSTRUCT, GetUserNameFromId(), HeapTupleIsValid, initStringInfo(), LargeObjectExists(), StringInfoData::len, NameStr, ObjectAddress::objectId, 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(), proname, PUBLICATIONREL, quote_qualified_identifier(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, STATEXTOID, StatisticsObjIsVisible(), subname, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TRFOID, TSConfigIsVisible(), TSCONFIGOID, TSDictionaryIsVisible(), TSDICTOID, TSParserIsVisible(), TSPARSEROID, TSTemplateIsVisible(), TSTEMPLATEOID, typname, USERMAPPINGOID, and username.

Referenced by AlterExtensionNamespace(), ATExecAlterColumnType(), changeDependenciesOn(), 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().

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

◆ getObjectDescriptionOids()

char* getObjectDescriptionOids ( Oid  classid,
Oid  objid 
)

Definition at line 3958 of file objectaddress.c.

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

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

3959 {
3960  ObjectAddress address;
3961 
3962  address.classId = classid;
3963  address.objectId = objid;
3964  address.objectSubId = 0;
3965 
3966  return getObjectDescription(&address, false);
3967 }
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)

◆ getObjectIdentity()

◆ getObjectIdentityParts()

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

Definition at line 4656 of file objectaddress.c.

References AccessShareLock, AMOID, appendStringInfo(), appendStringInfoString(), Assert, BTEqualStrategyNumber, CLAOID, ObjectAddress::classId, COLLOID, CONSTROID, CONVOID, StringInfoData::data, datname, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator_extended(), FORMAT_OPERATOR_FORCE_QUALIFY, FORMAT_OPERATOR_INVALID_AS_NULL, format_operator_parts(), FORMAT_PROC_FORCE_QUALIFY, FORMAT_PROC_INVALID_AS_NULL, format_procedure_extended(), format_procedure_parts(), format_type_be_qualified(), format_type_extended(), FORMAT_TYPE_FORCE_QUALIFY, FORMAT_TYPE_INVALID_AS_NULL, get_am_name(), get_attname(), get_catalog_object_by_oid(), get_database_name(), get_extension_name(), get_language_name(), get_namespace_name_or_temp(), get_publication_name(), get_subscription_name(), get_tablespace_name(), GetForeignDataWrapperExtended(), GetForeignServer(), GetForeignServerExtended(), getObjectClass(), getObjectIdentityParts(), getOpFamilyIdentity(), getRelationIdentity(), GETSTRUCT, GetUserNameFromId(), HeapTupleIsValid, initStringInfo(), LANGOID, lappend(), LargeObjectExists(), StringInfoData::len, list_make1, list_make2, list_make3, NameStr, NIL, ObjectAddress::objectId, 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, proname, psprintf(), pstrdup(), PUBLICATIONREL, quote_identifier(), quote_qualified_identifier(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), ForeignServer::servername, STATEXTOID, subname, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TSCONFIGOID, TSDICTOID, TSPARSEROID, TSTEMPLATEOID, USERMAPPINGOID, and username.

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

4659 {
4660  StringInfoData buffer;
4661 
4662  initStringInfo(&buffer);
4663 
4664  /*
4665  * Make sure that both objname and objargs were passed, or none was; and
4666  * initialize them to empty lists. For objname this is useless because it
4667  * will be initialized in all cases inside the switch; but we do it anyway
4668  * so that we can test below that no branch leaves it unset.
4669  */
4670  Assert(PointerIsValid(objname) == PointerIsValid(objargs));
4671  if (objname)
4672  {
4673  *objname = NIL;
4674  *objargs = NIL;
4675  }
4676 
4677  switch (getObjectClass(object))
4678  {
4679  case OCLASS_CLASS:
4680  {
4681  char *attr = NULL;
4682 
4683  /*
4684  * Check for the attribute first, so as if it is missing we
4685  * can skip the entire relation description.
4686  */
4687  if (object->objectSubId != 0)
4688  {
4689  attr = get_attname(object->objectId,
4690  object->objectSubId,
4691  missing_ok);
4692 
4693  if (missing_ok && attr == NULL)
4694  break;
4695  }
4696 
4697  getRelationIdentity(&buffer, object->objectId, objname,
4698  missing_ok);
4699  if (objname && *objname == NIL)
4700  break;
4701 
4702  if (attr)
4703  {
4704  appendStringInfo(&buffer, ".%s",
4705  quote_identifier(attr));
4706  if (objname)
4707  *objname = lappend(*objname, attr);
4708  }
4709  }
4710  break;
4711 
4712  case OCLASS_PROC:
4713  {
4715  char *proname = format_procedure_extended(object->objectId,
4716  flags);
4717 
4718  if (proname == NULL)
4719  break;
4720 
4721  appendStringInfoString(&buffer, proname);
4722  if (objname)
4723  format_procedure_parts(object->objectId, objname, objargs,
4724  missing_ok);
4725  break;
4726  }
4727 
4728  case OCLASS_TYPE:
4729  {
4731  char *typeout;
4732 
4733  typeout = format_type_extended(object->objectId, -1, flags);
4734 
4735  if (typeout == NULL)
4736  break;
4737 
4738  appendStringInfoString(&buffer, typeout);
4739  if (objname)
4740  *objname = list_make1(typeout);
4741  }
4742  break;
4743 
4744  case OCLASS_CAST:
4745  {
4746  Relation castRel;
4747  HeapTuple tup;
4748  Form_pg_cast castForm;
4749 
4750  castRel = table_open(CastRelationId, AccessShareLock);
4751 
4752  tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid,
4753  object->objectId);
4754 
4755  if (!HeapTupleIsValid(tup))
4756  {
4757  if (!missing_ok)
4758  elog(ERROR, "could not find tuple for cast %u",
4759  object->objectId);
4760 
4761  table_close(castRel, AccessShareLock);
4762  break;
4763  }
4764 
4765  castForm = (Form_pg_cast) GETSTRUCT(tup);
4766 
4767  appendStringInfo(&buffer, "(%s AS %s)",
4768  format_type_be_qualified(castForm->castsource),
4769  format_type_be_qualified(castForm->casttarget));
4770 
4771  if (objname)
4772  {
4773  *objname = list_make1(format_type_be_qualified(castForm->castsource));
4774  *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
4775  }
4776 
4777  table_close(castRel, AccessShareLock);
4778  break;
4779  }
4780 
4781  case OCLASS_COLLATION:
4782  {
4783  HeapTuple collTup;
4784  Form_pg_collation coll;
4785  char *schema;
4786 
4787  collTup = SearchSysCache1(COLLOID,
4788  ObjectIdGetDatum(object->objectId));
4789  if (!HeapTupleIsValid(collTup))
4790  {
4791  if (!missing_ok)
4792  elog(ERROR, "cache lookup failed for collation %u",
4793  object->objectId);
4794  break;
4795  }
4796  coll = (Form_pg_collation) GETSTRUCT(collTup);
4797  schema = get_namespace_name_or_temp(coll->collnamespace);
4798  appendStringInfoString(&buffer,
4800  NameStr(coll->collname)));
4801  if (objname)
4802  *objname = list_make2(schema,
4803  pstrdup(NameStr(coll->collname)));
4804  ReleaseSysCache(collTup);
4805  break;
4806  }
4807 
4808  case OCLASS_CONSTRAINT:
4809  {
4810  HeapTuple conTup;
4811  Form_pg_constraint con;
4812 
4813  conTup = SearchSysCache1(CONSTROID,
4814  ObjectIdGetDatum(object->objectId));
4815  if (!HeapTupleIsValid(conTup))
4816  {
4817  if (!missing_ok)
4818  elog(ERROR, "cache lookup failed for constraint %u",
4819  object->objectId);
4820  break;
4821  }
4822  con = (Form_pg_constraint) GETSTRUCT(conTup);
4823 
4824  if (OidIsValid(con->conrelid))
4825  {
4826  appendStringInfo(&buffer, "%s on ",
4827  quote_identifier(NameStr(con->conname)));
4828  getRelationIdentity(&buffer, con->conrelid, objname,
4829  false);
4830  if (objname)
4831  *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
4832  }
4833  else
4834  {
4835  ObjectAddress domain;
4836 
4837  Assert(OidIsValid(con->contypid));
4838  domain.classId = TypeRelationId;
4839  domain.objectId = con->contypid;
4840  domain.objectSubId = 0;
4841 
4842  appendStringInfo(&buffer, "%s on %s",
4843  quote_identifier(NameStr(con->conname)),
4844  getObjectIdentityParts(&domain, objname,
4845  objargs, false));
4846 
4847  if (objname)
4848  *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
4849  }
4850 
4851  ReleaseSysCache(conTup);
4852  break;
4853  }
4854 
4855  case OCLASS_CONVERSION:
4856  {
4857  HeapTuple conTup;
4858  Form_pg_conversion conForm;
4859  char *schema;
4860 
4861  conTup = SearchSysCache1(CONVOID,
4862  ObjectIdGetDatum(object->objectId));
4863  if (!HeapTupleIsValid(conTup))
4864  {
4865  if (!missing_ok)
4866  elog(ERROR, "cache lookup failed for conversion %u",
4867  object->objectId);
4868  break;
4869  }
4870  conForm = (Form_pg_conversion) GETSTRUCT(conTup);
4871  schema = get_namespace_name_or_temp(conForm->connamespace);
4872  appendStringInfoString(&buffer,
4874  NameStr(conForm->conname)));
4875  if (objname)
4876  *objname = list_make2(schema,
4877  pstrdup(NameStr(conForm->conname)));
4878  ReleaseSysCache(conTup);
4879  break;
4880  }
4881 
4882  case OCLASS_DEFAULT:
4883  {
4884  Relation attrdefDesc;
4885  ScanKeyData skey[1];
4886  SysScanDesc adscan;
4887 
4888  HeapTuple tup;
4889  Form_pg_attrdef attrdef;
4890  ObjectAddress colobject;
4891 
4892  attrdefDesc = table_open(AttrDefaultRelationId, AccessShareLock);
4893 
4894  ScanKeyInit(&skey[0],
4895  Anum_pg_attrdef_oid,
4896  BTEqualStrategyNumber, F_OIDEQ,
4897  ObjectIdGetDatum(object->objectId));
4898 
4899  adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId,
4900  true, NULL, 1, skey);
4901 
4902  tup = systable_getnext(adscan);
4903 
4904  if (!HeapTupleIsValid(tup))
4905  {
4906  if (!missing_ok)
4907  elog(ERROR, "could not find tuple for attrdef %u",
4908  object->objectId);
4909 
4910  systable_endscan(adscan);
4911  table_close(attrdefDesc, AccessShareLock);
4912  break;
4913  }
4914 
4915  attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
4916 
4917  colobject.classId = RelationRelationId;
4918  colobject.objectId = attrdef->adrelid;
4919  colobject.objectSubId = attrdef->adnum;
4920 
4921  appendStringInfo(&buffer, "for %s",
4922  getObjectIdentityParts(&colobject,
4923  objname, objargs,
4924  false));
4925 
4926  systable_endscan(adscan);
4927  table_close(attrdefDesc, AccessShareLock);
4928  break;
4929  }
4930 
4931  case OCLASS_LANGUAGE:
4932  {
4933  HeapTuple langTup;
4934  Form_pg_language langForm;
4935 
4936  langTup = SearchSysCache1(LANGOID,
4937  ObjectIdGetDatum(object->objectId));
4938  if (!HeapTupleIsValid(langTup))
4939  {
4940  if (!missing_ok)
4941  elog(ERROR, "cache lookup failed for language %u",
4942  object->objectId);
4943  break;
4944  }
4945  langForm = (Form_pg_language) GETSTRUCT(langTup);
4946  appendStringInfoString(&buffer,
4947  quote_identifier(NameStr(langForm->lanname)));
4948  if (objname)
4949  *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
4950  ReleaseSysCache(langTup);
4951  break;
4952  }
4953  case OCLASS_LARGEOBJECT:
4954  if (!LargeObjectExists(object->objectId))
4955  break;
4956  appendStringInfo(&buffer, "%u",
4957  object->objectId);
4958  if (objname)
4959  *objname = list_make1(psprintf("%u", object->objectId));
4960  break;
4961 
4962  case OCLASS_OPERATOR:
4963  {
4965  char *oprname = format_operator_extended(object->objectId,
4966  flags);
4967 
4968  if (oprname == NULL)
4969  break;
4970 
4971  appendStringInfoString(&buffer, oprname);
4972  if (objname)
4973  format_operator_parts(object->objectId, objname, objargs, missing_ok);
4974  break;
4975  }
4976 
4977  case OCLASS_OPCLASS:
4978  {
4979  HeapTuple opcTup;
4980  Form_pg_opclass opcForm;
4981  HeapTuple amTup;
4982  Form_pg_am amForm;
4983  char *schema;
4984 
4985  opcTup = SearchSysCache1(CLAOID,
4986  ObjectIdGetDatum(object->objectId));
4987  if (!HeapTupleIsValid(opcTup))
4988  {
4989  if (!missing_ok)
4990  elog(ERROR, "cache lookup failed for opclass %u",
4991  object->objectId);
4992  break;
4993  }
4994  opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
4995  schema = get_namespace_name_or_temp(opcForm->opcnamespace);
4996 
4997  amTup = SearchSysCache1(AMOID,
4998  ObjectIdGetDatum(opcForm->opcmethod));
4999  if (!HeapTupleIsValid(amTup))
5000  elog(ERROR, "cache lookup failed for access method %u",
5001  opcForm->opcmethod);
5002  amForm = (Form_pg_am) GETSTRUCT(amTup);
5003 
5004  appendStringInfo(&buffer, "%s USING %s",
5006  NameStr(opcForm->opcname)),
5007  quote_identifier(NameStr(amForm->amname)));
5008  if (objname)
5009  *objname = list_make3(pstrdup(NameStr(amForm->amname)),
5010  schema,
5011  pstrdup(NameStr(opcForm->opcname)));
5012 
5013  ReleaseSysCache(amTup);
5014  ReleaseSysCache(opcTup);
5015  break;
5016  }
5017 
5018  case OCLASS_OPFAMILY:
5019  getOpFamilyIdentity(&buffer, object->objectId, objname,
5020  missing_ok);
5021  break;
5022 
5023  case OCLASS_AM:
5024  {
5025  char *amname;
5026 
5027  amname = get_am_name(object->objectId);
5028  if (!amname)
5029  {
5030  if (!missing_ok)
5031  elog(ERROR, "cache lookup failed for access method %u",
5032  object->objectId);
5033  break;
5034  }
5035  appendStringInfoString(&buffer, quote_identifier(amname));
5036  if (objname)
5037  *objname = list_make1(amname);
5038  }
5039  break;
5040 
5041  case OCLASS_AMOP:
5042  {
5043  Relation amopDesc;
5044  HeapTuple tup;
5045  ScanKeyData skey[1];
5046  SysScanDesc amscan;
5047  Form_pg_amop amopForm;
5048  StringInfoData opfam;
5049  char *ltype;
5050  char *rtype;
5051 
5052  amopDesc = table_open(AccessMethodOperatorRelationId,
5053  AccessShareLock);
5054 
5055  ScanKeyInit(&skey[0],
5056  Anum_pg_amop_oid,
5057  BTEqualStrategyNumber, F_OIDEQ,
5058  ObjectIdGetDatum(object->objectId));
5059 
5060  amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
5061  NULL, 1, skey);
5062 
5063  tup = systable_getnext(amscan);
5064 
5065  if (!HeapTupleIsValid(tup))
5066  {
5067  if (!missing_ok)
5068  elog(ERROR, "could not find tuple for amop entry %u",
5069  object->objectId);
5070 
5071  systable_endscan(amscan);
5072  table_close(amopDesc, AccessShareLock);
5073  break;
5074  }
5075 
5076  amopForm = (Form_pg_amop) GETSTRUCT(tup);
5077 
5078  initStringInfo(&opfam);
5079  getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
5080  false);
5081 
5082  ltype = format_type_be_qualified(amopForm->amoplefttype);
5083  rtype = format_type_be_qualified(amopForm->amoprighttype);
5084 
5085  if (objname)
5086  {
5087  *objname = lappend(*objname,
5088  psprintf("%d", amopForm->amopstrategy));
5089  *objargs = list_make2(ltype, rtype);
5090  }
5091 
5092  appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
5093  amopForm->amopstrategy,
5094  ltype, rtype, opfam.data);
5095 
5096  pfree(opfam.data);
5097 
5098  systable_endscan(amscan);
5099  table_close(amopDesc, AccessShareLock);
5100  break;
5101  }
5102 
5103  case OCLASS_AMPROC:
5104  {
5105  Relation amprocDesc;
5106  ScanKeyData skey[1];
5107  SysScanDesc amscan;
5108  HeapTuple tup;
5109  Form_pg_amproc amprocForm;
5110  StringInfoData opfam;
5111  char *ltype;
5112  char *rtype;
5113 
5114  amprocDesc = table_open(AccessMethodProcedureRelationId,
5115  AccessShareLock);
5116 
5117  ScanKeyInit(&skey[0],
5118  Anum_pg_amproc_oid,
5119  BTEqualStrategyNumber, F_OIDEQ,
5120  ObjectIdGetDatum(object->objectId));
5121 
5122  amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
5123  NULL, 1, skey);
5124 
5125  tup = systable_getnext(amscan);
5126 
5127  if (!HeapTupleIsValid(tup))
5128  {
5129  if (!missing_ok)
5130  elog(ERROR, "could not find tuple for amproc entry %u",
5131  object->objectId);
5132 
5133  systable_endscan(amscan);
5134  table_close(amprocDesc, AccessShareLock);
5135  break;
5136  }
5137 
5138  amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
5139 
5140  initStringInfo(&opfam);
5141  getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
5142  false);
5143