#include "postgres.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/objectaddress.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_default_acl.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.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_opfamily.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_tablespace.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/proclang.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "foreign/foreign.h"
#include "funcapi.h"
#include "libpq/be-fsstubs.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/lmgr.h"
#include "storage/sinval.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
Go to the source code of this file.
void check_object_ownership | ( | Oid | roleid, | |
ObjectType | objtype, | |||
ObjectAddress | address, | |||
List * | objname, | |||
List * | objargs, | |||
Relation | relation | |||
) |
Definition at line 1120 of file objectaddress.c.
References ACL_KIND_CLASS, ACL_KIND_COLLATION, ACL_KIND_CONVERSION, ACL_KIND_DATABASE, ACL_KIND_EVENT_TRIGGER, ACL_KIND_EXTENSION, ACL_KIND_FDW, ACL_KIND_FOREIGN_SERVER, ACL_KIND_LANGUAGE, ACL_KIND_NAMESPACE, ACL_KIND_OPCLASS, ACL_KIND_OPER, ACL_KIND_OPFAMILY, ACL_KIND_PROC, ACL_KIND_TABLESPACE, ACL_KIND_TSCONFIGURATION, ACL_KIND_TSDICTIONARY, aclcheck_error(), aclcheck_error_type(), ACLCHECK_NOT_OWNER, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), has_createrole_privilege(), linitial, lo_compat_privileges, NameListToString(), NULL, OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONSTRAINT, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, 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_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddress::objectId, pg_class_ownercheck(), pg_collation_ownercheck(), pg_conversion_ownercheck(), pg_database_ownercheck(), pg_event_trigger_ownercheck(), pg_extension_ownercheck(), pg_foreign_data_wrapper_ownercheck(), pg_foreign_server_ownercheck(), pg_language_ownercheck(), pg_largeobject_ownercheck(), pg_namespace_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), RelationGetRelationName, RelationGetRelid, superuser_arg(), and typenameTypeId().
Referenced by CommentObject(), ExecAlterExtensionContentsStmt(), ExecSecLabelStmt(), and RemoveObjects().
{ switch (objtype) { case OBJECT_INDEX: case OBJECT_SEQUENCE: case OBJECT_TABLE: case OBJECT_VIEW: case OBJECT_MATVIEW: case OBJECT_FOREIGN_TABLE: case OBJECT_COLUMN: case OBJECT_RULE: case OBJECT_TRIGGER: case OBJECT_CONSTRAINT: if (!pg_class_ownercheck(RelationGetRelid(relation), roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(relation)); break; case OBJECT_DATABASE: if (!pg_database_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, NameListToString(objname)); break; case OBJECT_TYPE: case OBJECT_DOMAIN: case OBJECT_ATTRIBUTE: if (!pg_type_ownercheck(address.objectId, roleid)) aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId); break; case OBJECT_AGGREGATE: case OBJECT_FUNCTION: if (!pg_proc_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(objname)); break; case OBJECT_OPERATOR: if (!pg_oper_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER, NameListToString(objname)); break; case OBJECT_SCHEMA: if (!pg_namespace_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, NameListToString(objname)); break; case OBJECT_COLLATION: if (!pg_collation_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_COLLATION, NameListToString(objname)); break; case OBJECT_CONVERSION: if (!pg_conversion_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, NameListToString(objname)); break; case OBJECT_EXTENSION: if (!pg_extension_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION, NameListToString(objname)); break; case OBJECT_FDW: if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FDW, NameListToString(objname)); break; case OBJECT_FOREIGN_SERVER: if (!pg_foreign_server_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER, NameListToString(objname)); break; case OBJECT_EVENT_TRIGGER: if (!pg_event_trigger_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EVENT_TRIGGER, NameListToString(objname)); break; case OBJECT_LANGUAGE: if (!pg_language_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE, NameListToString(objname)); break; case OBJECT_OPCLASS: if (!pg_opclass_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, NameListToString(objname)); break; case OBJECT_OPFAMILY: if (!pg_opfamily_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY, NameListToString(objname)); break; case OBJECT_LARGEOBJECT: if (!lo_compat_privileges && !pg_largeobject_ownercheck(address.objectId, roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of large object %u", address.objectId))); break; case OBJECT_CAST: { /* We can only check permissions on the source/target types */ TypeName *sourcetype = (TypeName *) linitial(objname); TypeName *targettype = (TypeName *) linitial(objargs); Oid sourcetypeid = typenameTypeId(NULL, sourcetype); Oid targettypeid = typenameTypeId(NULL, targettype); if (!pg_type_ownercheck(sourcetypeid, roleid) && !pg_type_ownercheck(targettypeid, roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of type %s or type %s", format_type_be(sourcetypeid), format_type_be(targettypeid)))); } break; case OBJECT_TABLESPACE: if (!pg_tablespace_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, NameListToString(objname)); break; case OBJECT_TSDICTIONARY: if (!pg_ts_dict_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY, NameListToString(objname)); break; case OBJECT_TSCONFIGURATION: if (!pg_ts_config_ownercheck(address.objectId, roleid)) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION, NameListToString(objname)); break; case OBJECT_ROLE: /* * We treat roles as being "owned" by those with CREATEROLE priv, * except that superusers are only owned by superusers. */ if (superuser_arg(address.objectId)) { if (!superuser_arg(roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser"))); } else { if (!has_createrole_privilege(roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must have CREATEROLE privilege"))); } break; case OBJECT_TSPARSER: case OBJECT_TSTEMPLATE: /* We treat these object types as being owned by superusers */ if (!superuser_arg(roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser"))); break; default: elog(ERROR, "unrecognized object type: %d", (int) objtype); } }
Definition at line 1457 of file objectaddress.c.
References Assert, BTEqualStrategyNumber, get_object_catcache_oid(), get_object_oid_index(), heap_copytuple(), HeapTupleIsValid, ObjectIdAttributeNumber, ObjectIdGetDatum, OidIsValid, RelationGetRelid, ScanKeyInit(), SearchSysCacheCopy1, SnapshotNow, systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by AlterObjectOwner_internal(), EventTriggerSQLDropAddObject(), getConstraintTypeDescription(), getObjectIdentity(), and pg_identify_object().
{ HeapTuple tuple; Oid classId = RelationGetRelid(catalog); int oidCacheId = get_object_catcache_oid(classId); if (oidCacheId > 0) { tuple = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId)); if (!HeapTupleIsValid(tuple)) /* should not happen */ return NULL; } else { Oid oidIndexId = get_object_oid_index(classId); SysScanDesc scan; ScanKeyData skey; Assert(OidIsValid(oidIndexId)); ScanKeyInit(&skey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); scan = systable_beginscan(catalog, oidIndexId, true, SnapshotNow, 1, &skey); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) { systable_endscan(scan); return NULL; } tuple = heap_copytuple(tuple); systable_endscan(scan); } return tuple; }
AclObjectKind get_object_aclkind | ( | Oid | class_id | ) |
Definition at line 1385 of file objectaddress.c.
References ObjectPropertyType::acl_kind, and get_object_property_data().
Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), and AlterObjectRename_internal().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->acl_kind; }
ObjectAddress get_object_address | ( | ObjectType | objtype, | |
List * | objname, | |||
List * | objargs, | |||
Relation * | relp, | |||
LOCKMODE | lockmode, | |||
bool | missing_ok | |||
) |
Definition at line 465 of file objectaddress.c.
References Assert, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, get_cast_oid(), get_collation_oid(), get_conversion_oid(), get_object_address_attribute(), get_object_address_opcf(), get_object_address_relobject(), get_object_address_type(), get_object_address_unqualified(), get_relation_by_qualified_name(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), IsSharedRelation(), LargeObjectExists(), linitial, list_length(), LockDatabaseObject(), LockSharedObject(), LookupAggNameTypeNames(), LookupFuncNameTypeNames(), LookupOperNameTypeNames(), lsecond, NoLock, NULL, OBJECT_AGGREGATE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONSTRAINT, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, 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_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, oidparse(), RelationRelationId, SharedInvalidMessageCounter, typenameTypeId(), UnlockDatabaseObject(), and UnlockSharedObject().
Referenced by CommentObject(), ExecAlterExtensionContentsStmt(), ExecAlterObjectSchemaStmt(), ExecAlterOwnerStmt(), ExecRenameStmt(), ExecSecLabelStmt(), and RemoveObjects().
{ ObjectAddress address; ObjectAddress old_address = {InvalidOid, InvalidOid, 0}; Relation relation = NULL; uint64 inval_count; /* Some kind of lock must be taken. */ Assert(lockmode != NoLock); for (;;) { /* * Remember this value, so that, after looking up the object name and * locking it, we can check whether any invalidation messages have * been processed that might require a do-over. */ inval_count = SharedInvalidMessageCounter; /* Look up object address. */ switch (objtype) { case OBJECT_INDEX: case OBJECT_SEQUENCE: case OBJECT_TABLE: case OBJECT_VIEW: case OBJECT_MATVIEW: case OBJECT_FOREIGN_TABLE: address = get_relation_by_qualified_name(objtype, objname, &relation, lockmode, missing_ok); break; case OBJECT_COLUMN: address = get_object_address_attribute(objtype, objname, &relation, lockmode, missing_ok); break; case OBJECT_RULE: case OBJECT_TRIGGER: case OBJECT_CONSTRAINT: address = get_object_address_relobject(objtype, objname, &relation, missing_ok); break; case OBJECT_DATABASE: case OBJECT_EXTENSION: case OBJECT_TABLESPACE: case OBJECT_ROLE: case OBJECT_SCHEMA: case OBJECT_LANGUAGE: case OBJECT_FDW: case OBJECT_FOREIGN_SERVER: case OBJECT_EVENT_TRIGGER: address = get_object_address_unqualified(objtype, objname, missing_ok); break; case OBJECT_TYPE: case OBJECT_DOMAIN: address = get_object_address_type(objtype, objname, missing_ok); break; case OBJECT_AGGREGATE: address.classId = ProcedureRelationId; address.objectId = LookupAggNameTypeNames(objname, objargs, missing_ok); address.objectSubId = 0; break; case OBJECT_FUNCTION: address.classId = ProcedureRelationId; address.objectId = LookupFuncNameTypeNames(objname, objargs, missing_ok); address.objectSubId = 0; break; case OBJECT_OPERATOR: Assert(list_length(objargs) == 2); address.classId = OperatorRelationId; address.objectId = LookupOperNameTypeNames(NULL, objname, (TypeName *) linitial(objargs), (TypeName *) lsecond(objargs), missing_ok, -1); address.objectSubId = 0; break; case OBJECT_COLLATION: address.classId = CollationRelationId; address.objectId = get_collation_oid(objname, missing_ok); address.objectSubId = 0; break; case OBJECT_CONVERSION: address.classId = ConversionRelationId; address.objectId = get_conversion_oid(objname, missing_ok); address.objectSubId = 0; break; case OBJECT_OPCLASS: case OBJECT_OPFAMILY: address = get_object_address_opcf(objtype, objname, objargs, missing_ok); break; case OBJECT_LARGEOBJECT: Assert(list_length(objname) == 1); address.classId = LargeObjectRelationId; address.objectId = oidparse(linitial(objname)); address.objectSubId = 0; if (!LargeObjectExists(address.objectId)) { if (!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", address.objectId))); } break; case OBJECT_CAST: { TypeName *sourcetype = (TypeName *) linitial(objname); TypeName *targettype = (TypeName *) linitial(objargs); Oid sourcetypeid = typenameTypeId(NULL, sourcetype); Oid targettypeid = typenameTypeId(NULL, targettype); address.classId = CastRelationId; address.objectId = get_cast_oid(sourcetypeid, targettypeid, missing_ok); address.objectSubId = 0; } break; case OBJECT_TSPARSER: address.classId = TSParserRelationId; address.objectId = get_ts_parser_oid(objname, missing_ok); address.objectSubId = 0; break; case OBJECT_TSDICTIONARY: address.classId = TSDictionaryRelationId; address.objectId = get_ts_dict_oid(objname, missing_ok); address.objectSubId = 0; break; case OBJECT_TSTEMPLATE: address.classId = TSTemplateRelationId; address.objectId = get_ts_template_oid(objname, missing_ok); address.objectSubId = 0; break; case OBJECT_TSCONFIGURATION: address.classId = TSConfigRelationId; address.objectId = get_ts_config_oid(objname, missing_ok); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, in case it thinks elog might return */ address.classId = InvalidOid; address.objectId = InvalidOid; address.objectSubId = 0; } /* * If we could not find the supplied object, return without locking. */ if (!OidIsValid(address.objectId)) { Assert(missing_ok); return address; } /* * If we're retrying, see if we got the same answer as last time. If * so, we're done; if not, we locked the wrong thing, so give up our * lock. */ if (OidIsValid(old_address.classId)) { if (old_address.classId == address.classId && old_address.objectId == address.objectId && old_address.objectSubId == address.objectSubId) break; if (old_address.classId != RelationRelationId) { if (IsSharedRelation(old_address.classId)) UnlockSharedObject(old_address.classId, old_address.objectId, 0, lockmode); else UnlockDatabaseObject(old_address.classId, old_address.objectId, 0, lockmode); } } /* * If we're dealing with a relation or attribute, then the relation is * already locked. Otherwise, we lock it now. */ if (address.classId != RelationRelationId) { if (IsSharedRelation(address.classId)) LockSharedObject(address.classId, address.objectId, 0, lockmode); else LockDatabaseObject(address.classId, address.objectId, 0, lockmode); } /* * At this point, we've resolved the name to an OID and locked the * corresponding database object. However, it's possible that by the * time we acquire the lock on the object, concurrent DDL has modified * the database in such a way that the name we originally looked up no * longer resolves to that OID. * * We can be certain that this isn't an issue if (a) no shared * invalidation messages have been processed or (b) we've locked a * relation somewhere along the line. All the relation name lookups * in this module ultimately use RangeVarGetRelid() to acquire a * relation lock, and that function protects against the same kinds of * races we're worried about here. Even when operating on a * constraint, rule, or trigger, we still acquire AccessShareLock on * the relation, which is enough to freeze out any concurrent DDL. * * In all other cases, however, it's possible that the name we looked * up no longer refers to the object we locked, so we retry the lookup * and see whether we get the same answer. */ if (inval_count == SharedInvalidMessageCounter || relation != NULL) break; old_address = address; } /* Return the object address and the relation. */ *relp = relation; return address; }
static ObjectAddress get_object_address_attribute | ( | ObjectType | objtype, | |
List * | objname, | |||
Relation * | relp, | |||
LOCKMODE | lockmode, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 992 of file objectaddress.c.
References ObjectAddress::classId, ereport, errcode(), errmsg(), ERROR, get_attnum(), InvalidAttrNumber, lfirst, list_copy(), list_length(), list_tail(), list_truncate(), makeRangeVarFromNameList(), NameListToString(), ObjectAddress::objectId, ObjectAddress::objectSubId, relation_openrv(), RelationGetRelid, and strVal.
Referenced by get_object_address().
{ ObjectAddress address; List *relname; Oid reloid; Relation relation; const char *attname; AttrNumber attnum; /* Extract relation name and open relation. */ if (list_length(objname) < 2) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column name must be qualified"))); attname = strVal(lfirst(list_tail(objname))); relname = list_truncate(list_copy(objname), list_length(objname) - 1); relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode); reloid = RelationGetRelid(relation); /* Look up attribute and construct return value. */ attnum = get_attnum(reloid, attname); if (attnum == InvalidAttrNumber) { if (!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" of relation \"%s\" does not exist", attname, NameListToString(relname)))); address.classId = RelationRelationId; address.objectId = InvalidOid; address.objectSubId = InvalidAttrNumber; return address; } address.classId = RelationRelationId; address.objectId = reloid; address.objectSubId = attnum; *relp = relation; return address; }
static ObjectAddress get_object_address_opcf | ( | ObjectType | objtype, | |
List * | objname, | |||
List * | objargs, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 1084 of file objectaddress.c.
References Assert, ObjectAddress::classId, elog, ERROR, get_am_oid(), get_opclass_oid(), get_opfamily_oid(), linitial, list_length(), OBJECT_OPCLASS, OBJECT_OPFAMILY, ObjectAddress::objectId, ObjectAddress::objectSubId, and strVal.
Referenced by get_object_address().
{ Oid amoid; ObjectAddress address; Assert(list_length(objargs) == 1); amoid = get_am_oid(strVal(linitial(objargs)), false); switch (objtype) { case OBJECT_OPCLASS: address.classId = OperatorClassRelationId; address.objectId = get_opclass_oid(amoid, objname, missing_ok); address.objectSubId = 0; break; case OBJECT_OPFAMILY: address.classId = OperatorFamilyRelationId; address.objectId = get_opfamily_oid(amoid, objname, missing_ok); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ address.classId = InvalidOid; address.objectId = InvalidOid; address.objectSubId = 0; } return address; }
static ObjectAddress get_object_address_relobject | ( | ObjectType | objtype, | |
List * | objname, | |||
Relation * | relp, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 899 of file objectaddress.c.
References AccessShareLock, ObjectAddress::classId, elog, ERROR, get_relation_constraint_oid(), get_rewrite_oid(), get_rewrite_oid_without_relid(), get_trigger_oid(), heap_close, heap_open(), heap_openrv(), lfirst, list_copy(), list_length(), list_tail(), list_truncate(), makeRangeVarFromNameList(), OBJECT_CONSTRAINT, OBJECT_RULE, OBJECT_TRIGGER, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, RelationGetRelid, and strVal.
Referenced by get_object_address().
{ ObjectAddress address; Relation relation = NULL; int nnames; const char *depname; /* Extract name of dependent object. */ depname = strVal(lfirst(list_tail(objname))); /* Separate relation name from dependent object name. */ nnames = list_length(objname); if (nnames < 2) { Oid reloid; /* * For compatibility with very old releases, we sometimes allow users * to attempt to specify a rule without mentioning the relation name. * If there's only rule by that name in the entire database, this will * work. But objects other than rules don't get this special * treatment. */ if (objtype != OBJECT_RULE) elog(ERROR, "must specify relation and object name"); address.classId = RewriteRelationId; address.objectId = get_rewrite_oid_without_relid(depname, &reloid, missing_ok); address.objectSubId = 0; /* * Caller is expecting to get back the relation, even though we didn't * end up using it to find the rule. */ if (OidIsValid(address.objectId)) relation = heap_open(reloid, AccessShareLock); } else { List *relname; Oid reloid; /* Extract relation name and open relation. */ relname = list_truncate(list_copy(objname), nnames - 1); relation = heap_openrv(makeRangeVarFromNameList(relname), AccessShareLock); reloid = RelationGetRelid(relation); switch (objtype) { case OBJECT_RULE: address.classId = RewriteRelationId; address.objectId = get_rewrite_oid(reloid, depname, missing_ok); address.objectSubId = 0; break; case OBJECT_TRIGGER: address.classId = TriggerRelationId; address.objectId = get_trigger_oid(reloid, depname, missing_ok); address.objectSubId = 0; break; case OBJECT_CONSTRAINT: address.classId = ConstraintRelationId; address.objectId = get_relation_constraint_oid(reloid, depname, missing_ok); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ address.classId = InvalidOid; address.objectId = InvalidOid; address.objectSubId = 0; } /* Avoid relcache leak when object not found. */ if (!OidIsValid(address.objectId)) { heap_close(relation, AccessShareLock); relation = NULL; /* department of accident prevention */ return address; } } /* Done. */ *relp = relation; return address; }
static ObjectAddress get_object_address_type | ( | ObjectType | objtype, | |
List * | objname, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 1041 of file objectaddress.c.
References ObjectAddress::classId, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, LookupTypeName(), makeTypeNameFromNameList(), NULL, OBJECT_DOMAIN, ObjectAddress::objectId, ObjectAddress::objectSubId, ReleaseSysCache(), TypeNameToString(), typeTypeId(), and TYPTYPE_DOMAIN.
Referenced by get_object_address().
{ ObjectAddress address; TypeName *typename; Type tup; typename = makeTypeNameFromNameList(objname); address.classId = TypeRelationId; address.objectId = InvalidOid; address.objectSubId = 0; tup = LookupTypeName(NULL, typename, NULL); if (!HeapTupleIsValid(tup)) { if (!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", TypeNameToString(typename)))); return address; } address.objectId = typeTypeId(tup); if (objtype == OBJECT_DOMAIN) { if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a domain", TypeNameToString(typename)))); } ReleaseSysCache(tup); return address; }
static ObjectAddress get_object_address_unqualified | ( | ObjectType | objtype, | |
List * | qualname, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 701 of file objectaddress.c.
References _, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, 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_role_oid(), get_tablespace_oid(), gettext_noop, linitial, list_length(), name, OBJECT_DATABASE, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_LANGUAGE, OBJECT_ROLE, OBJECT_SCHEMA, OBJECT_TABLESPACE, ObjectAddress::objectId, ObjectAddress::objectSubId, and strVal.
Referenced by get_object_address().
{ const char *name; ObjectAddress address; /* * The types of names handled by this function are not permitted to be * schema-qualified or catalog-qualified. */ if (list_length(qualname) != 1) { const char *msg; switch (objtype) { case OBJECT_DATABASE: msg = gettext_noop("database name cannot be qualified"); break; case OBJECT_EXTENSION: msg = gettext_noop("extension name cannot be qualified"); break; case OBJECT_TABLESPACE: msg = gettext_noop("tablespace name cannot be qualified"); break; case OBJECT_ROLE: msg = gettext_noop("role name cannot be qualified"); break; case OBJECT_SCHEMA: msg = gettext_noop("schema name cannot be qualified"); break; case OBJECT_LANGUAGE: msg = gettext_noop("language name cannot be qualified"); break; case OBJECT_FDW: msg = gettext_noop("foreign-data wrapper name cannot be qualified"); break; case OBJECT_FOREIGN_SERVER: msg = gettext_noop("server name cannot be qualified"); break; case OBJECT_EVENT_TRIGGER: msg = gettext_noop("event trigger name cannot be qualified"); break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); msg = NULL; /* placate compiler */ } ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("%s", _(msg)))); } /* Format is valid, extract the actual name. */ name = strVal(linitial(qualname)); /* Translate name to OID. */ switch (objtype) { case OBJECT_DATABASE: address.classId = DatabaseRelationId; address.objectId = get_database_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_EXTENSION: address.classId = ExtensionRelationId; address.objectId = get_extension_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_TABLESPACE: address.classId = TableSpaceRelationId; address.objectId = get_tablespace_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_ROLE: address.classId = AuthIdRelationId; address.objectId = get_role_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_SCHEMA: address.classId = NamespaceRelationId; address.objectId = get_namespace_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_LANGUAGE: address.classId = LanguageRelationId; address.objectId = get_language_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_FDW: address.classId = ForeignDataWrapperRelationId; address.objectId = get_foreign_data_wrapper_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_FOREIGN_SERVER: address.classId = ForeignServerRelationId; address.objectId = get_foreign_server_oid(name, missing_ok); address.objectSubId = 0; break; case OBJECT_EVENT_TRIGGER: address.classId = EventTriggerRelationId; address.objectId = get_event_trigger_oid(name, missing_ok); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ address.classId = InvalidOid; address.objectId = InvalidOid; address.objectSubId = 0; } return address; }
AttrNumber get_object_attnum_acl | ( | Oid | class_id | ) |
Definition at line 1377 of file objectaddress.c.
References ObjectPropertyType::attnum_acl, and get_object_property_data().
Referenced by AlterObjectOwner_internal().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->attnum_acl; }
AttrNumber get_object_attnum_name | ( | Oid | class_id | ) |
Definition at line 1353 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().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->attnum_name; }
AttrNumber get_object_attnum_namespace | ( | Oid | class_id | ) |
Definition at line 1361 of file objectaddress.c.
References ObjectPropertyType::attnum_namespace, and get_object_property_data().
Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), EventTriggerSQLDropAddObject(), and pg_identify_object().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->attnum_namespace; }
AttrNumber get_object_attnum_owner | ( | Oid | class_id | ) |
Definition at line 1369 of file objectaddress.c.
References ObjectPropertyType::attnum_owner, and get_object_property_data().
Referenced by AlterObjectNamespace_internal(), AlterObjectOwner_internal(), and AlterObjectRename_internal().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->attnum_owner; }
int get_object_catcache_name | ( | Oid | class_id | ) |
Definition at line 1345 of file objectaddress.c.
References get_object_property_data(), and ObjectPropertyType::name_catcache_id.
Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->name_catcache_id; }
int get_object_catcache_oid | ( | Oid | class_id | ) |
Definition at line 1337 of file objectaddress.c.
References get_object_property_data(), and ObjectPropertyType::oid_catcache_id.
Referenced by AlterObjectNamespace_internal(), AlterObjectRename_internal(), and get_catalog_object_by_oid().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->oid_catcache_id; }
Definition at line 1393 of file objectaddress.c.
References get_object_property_data(), and ObjectPropertyType::is_nsp_name_unique.
Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->is_nsp_name_unique; }
Oid get_object_namespace | ( | const ObjectAddress * | address | ) |
Definition at line 1293 of file objectaddress.c.
References Assert, ObjectPropertyType::attnum_namespace, ObjectAddress::classId, DatumGetObjectId, elog, ERROR, get_object_property_data(), HeapTupleIsValid, InvalidAttrNumber, ObjectAddress::objectId, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and SysCacheGetAttr().
Referenced by RemoveObjects().
{ int cache; HeapTuple tuple; bool isnull; Oid oid; ObjectPropertyType *property; /* If not owned by a namespace, just return InvalidOid. */ property = get_object_property_data(address->classId); if (property->attnum_namespace == InvalidAttrNumber) return InvalidOid; /* Currently, we can only handle object types with system caches. */ cache = property->oid_catcache_id; Assert(cache != -1); /* Fetch tuple from syscache and extract namespace attribute. */ tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for cache %d oid %u", cache, address->objectId); oid = DatumGetObjectId(SysCacheGetAttr(cache, tuple, property->attnum_namespace, &isnull)); Assert(!isnull); ReleaseSysCache(tuple); return oid; }
Definition at line 1329 of file objectaddress.c.
References get_object_property_data(), and ObjectPropertyType::oid_index_oid.
Referenced by get_catalog_object_by_oid().
{ ObjectPropertyType *prop = get_object_property_data(class_id); return prop->oid_index_oid; }
static ObjectPropertyType * get_object_property_data | ( | Oid | class_id | ) | [static] |
Definition at line 1422 of file objectaddress.c.
References ObjectPropertyType::class_oid, ereport, errmsg_internal(), ERROR, and lengthof.
Referenced by get_object_aclkind(), get_object_attnum_acl(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), get_object_namensp_unique(), get_object_namespace(), and get_object_oid_index().
{ static ObjectPropertyType *prop_last = NULL; int index; /* * A shortcut to speed up multiple consecutive lookups of a particular * object class. */ if (prop_last && prop_last->class_oid == class_id) return prop_last; for (index = 0; index < lengthof(ObjectProperty); index++) { if (ObjectProperty[index].class_oid == class_id) { prop_last = &ObjectProperty[index]; return &ObjectProperty[index]; } } ereport(ERROR, (errmsg_internal("unrecognized class id: %u", class_id))); return NULL; /* keep MSC compiler happy */ }
static ObjectAddress get_relation_by_qualified_name | ( | ObjectType | objtype, | |
List * | objname, | |||
Relation * | relp, | |||
LOCKMODE | lockmode, | |||
bool | missing_ok | |||
) | [static] |
Definition at line 819 of file objectaddress.c.
References ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, 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, RelationGetRelid, RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, and RELKIND_VIEW.
Referenced by get_object_address().
{ Relation relation; ObjectAddress address; address.classId = RelationRelationId; address.objectId = InvalidOid; address.objectSubId = 0; relation = relation_openrv_extended(makeRangeVarFromNameList(objname), lockmode, missing_ok); if (!relation) return address; switch (objtype) { case OBJECT_INDEX: if (relation->rd_rel->relkind != RELKIND_INDEX) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not an index", RelationGetRelationName(relation)))); break; case OBJECT_SEQUENCE: if (relation->rd_rel->relkind != RELKIND_SEQUENCE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a sequence", RelationGetRelationName(relation)))); break; case OBJECT_TABLE: if (relation->rd_rel->relkind != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table", RelationGetRelationName(relation)))); break; case OBJECT_VIEW: if (relation->rd_rel->relkind != RELKIND_VIEW) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a view", RelationGetRelationName(relation)))); break; case OBJECT_MATVIEW: if (relation->rd_rel->relkind != RELKIND_MATVIEW) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a materialized view", RelationGetRelationName(relation)))); break; case OBJECT_FOREIGN_TABLE: if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a foreign table", RelationGetRelationName(relation)))); break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); break; } /* Done. */ address.objectId = RelationGetRelid(relation); *relp = relation; return address; }
static void getConstraintTypeDescription | ( | StringInfo | buffer, | |
Oid | constroid | |||
) | [static] |
Definition at line 2621 of file objectaddress.c.
References AccessShareLock, appendStringInfoString(), ConstraintRelationId, elog, ERROR, get_catalog_object_by_oid(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, and OidIsValid.
Referenced by getObjectTypeDescription().
{ Relation constrRel; HeapTuple constrTup; Form_pg_constraint constrForm; constrRel = heap_open(ConstraintRelationId, AccessShareLock); constrTup = get_catalog_object_by_oid(constrRel, constroid); if (!HeapTupleIsValid(constrTup)) elog(ERROR, "cache lookup failed for constraint %u", constroid); constrForm = (Form_pg_constraint) GETSTRUCT(constrTup); if (OidIsValid(constrForm->conrelid)) appendStringInfoString(buffer, "table constraint"); else if (OidIsValid(constrForm->contypid)) appendStringInfoString(buffer, "domain constraint"); else elog(ERROR, "invalid constraint %u", HeapTupleGetOid(constrTup)); heap_close(constrRel, AccessShareLock); }
char* getObjectDescription | ( | const ObjectAddress * | object | ) |
Definition at line 1504 of file objectaddress.c.
References _, AccessMethodOperatorOidIndexId, AccessMethodOperatorRelationId, AccessMethodProcedureOidIndexId, AccessMethodProcedureRelationId, AccessShareLock, AMOID, appendStringInfo(), AttrDefaultOidIndexId, AttrDefaultRelationId, BTEqualStrategyNumber, CastOidIndexId, CastRelationId, CLAOID, ObjectAddress::classId, COLLOID, CONSTROID, CONVOID, StringInfoData::data, DEFACLOBJ_FUNCTION, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, DefaultAclOidIndexId, DefaultAclRelationId, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator(), format_procedure(), format_type_be(), get_database_name(), get_extension_name(), get_namespace_name(), get_relid_attribute_name(), get_tablespace_name(), GetForeignDataWrapper(), GetForeignServer(), getObjectClass(), getObjectDescription(), getOpFamilyDescription(), getRelationDescription(), GETSTRUCT, GetUserNameFromId(), heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), LANGOID, NameStr, NULL, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectIdGetDatum, ObjectAddress::objectSubId, 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_PROC, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_TBLSPACE, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, OCLASS_USER_MAPPING, OidIsValid, OpclassIsVisible(), pfree(), quote_qualified_identifier(), ReleaseSysCache(), RewriteOidIndexId, RewriteRelationId, ScanKeyInit(), SearchSysCache1, ForeignServer::servername, SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), TriggerOidIndexId, TriggerRelationId, TSCONFIGOID, TSDICTOID, TSPARSEROID, TSTEMPLATEOID, and USERMAPPINGOID.
Referenced by AlterExtensionNamespace(), ATExecAlterColumnType(), changeDependencyFor(), check_relation_privileges(), checkSharedDependencies(), ExecAlterExtensionContentsStmt(), findDependentObjects(), getObjectDescription(), getObjectDescriptionOids(), pg_describe_object(), recordDependencyOnCurrentExtension(), reportDependentObjects(), sepgsql_fmgr_hook(), shdepDropOwned(), shdepReassignOwned(), and storeObjectDescription().
{ StringInfoData buffer; initStringInfo(&buffer); switch (getObjectClass(object)) { case OCLASS_CLASS: getRelationDescription(&buffer, object->objectId); if (object->objectSubId != 0) appendStringInfo(&buffer, _(" column %s"), get_relid_attribute_name(object->objectId, object->objectSubId)); break; case OCLASS_PROC: appendStringInfo(&buffer, _("function %s"), format_procedure(object->objectId)); break; case OCLASS_TYPE: appendStringInfo(&buffer, _("type %s"), format_type_be(object->objectId)); break; case OCLASS_CAST: { Relation castDesc; ScanKeyData skey[1]; SysScanDesc rcscan; HeapTuple tup; Form_pg_cast castForm; castDesc = heap_open(CastRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); rcscan = systable_beginscan(castDesc, CastOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(rcscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for cast %u", object->objectId); castForm = (Form_pg_cast) GETSTRUCT(tup); appendStringInfo(&buffer, _("cast from %s to %s"), format_type_be(castForm->castsource), format_type_be(castForm->casttarget)); systable_endscan(rcscan); heap_close(castDesc, AccessShareLock); break; } case OCLASS_COLLATION: { HeapTuple collTup; Form_pg_collation coll; collTup = SearchSysCache1(COLLOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(collTup)) elog(ERROR, "cache lookup failed for collation %u", object->objectId); coll = (Form_pg_collation) GETSTRUCT(collTup); appendStringInfo(&buffer, _("collation %s"), NameStr(coll->collname)); ReleaseSysCache(collTup); break; } case OCLASS_CONSTRAINT: { HeapTuple conTup; Form_pg_constraint con; conTup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(conTup)) elog(ERROR, "cache lookup failed for constraint %u", object->objectId); con = (Form_pg_constraint) GETSTRUCT(conTup); if (OidIsValid(con->conrelid)) { StringInfoData rel; initStringInfo(&rel); getRelationDescription(&rel, con->conrelid); appendStringInfo(&buffer, _("constraint %s on %s"), NameStr(con->conname), rel.data); pfree(rel.data); } else { appendStringInfo(&buffer, _("constraint %s"), NameStr(con->conname)); } ReleaseSysCache(conTup); break; } case OCLASS_CONVERSION: { HeapTuple conTup; conTup = SearchSysCache1(CONVOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(conTup)) elog(ERROR, "cache lookup failed for conversion %u", object->objectId); appendStringInfo(&buffer, _("conversion %s"), NameStr(((Form_pg_conversion) GETSTRUCT(conTup))->conname)); ReleaseSysCache(conTup); break; } case OCLASS_DEFAULT: { Relation attrdefDesc; ScanKeyData skey[1]; SysScanDesc adscan; HeapTuple tup; Form_pg_attrdef attrdef; ObjectAddress colobject; attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(adscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for attrdef %u", object->objectId); attrdef = (Form_pg_attrdef) GETSTRUCT(tup); colobject.classId = RelationRelationId; colobject.objectId = attrdef->adrelid; colobject.objectSubId = attrdef->adnum; appendStringInfo(&buffer, _("default for %s"), getObjectDescription(&colobject)); systable_endscan(adscan); heap_close(attrdefDesc, AccessShareLock); break; } case OCLASS_LANGUAGE: { HeapTuple langTup; langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(langTup)) elog(ERROR, "cache lookup failed for language %u", object->objectId); appendStringInfo(&buffer, _("language %s"), NameStr(((Form_pg_language) GETSTRUCT(langTup))->lanname)); ReleaseSysCache(langTup); break; } case OCLASS_LARGEOBJECT: appendStringInfo(&buffer, _("large object %u"), object->objectId); break; case OCLASS_OPERATOR: appendStringInfo(&buffer, _("operator %s"), format_operator(object->objectId)); break; case OCLASS_OPCLASS: { HeapTuple opcTup; Form_pg_opclass opcForm; HeapTuple amTup; Form_pg_am amForm; char *nspname; opcTup = SearchSysCache1(CLAOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(opcTup)) elog(ERROR, "cache lookup failed for opclass %u", object->objectId); opcForm = (Form_pg_opclass) GETSTRUCT(opcTup); amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opcForm->opcmethod)); if (!HeapTupleIsValid(amTup)) elog(ERROR, "cache lookup failed for access method %u", opcForm->opcmethod); amForm = (Form_pg_am) GETSTRUCT(amTup); /* Qualify the name if not visible in search path */ if (OpclassIsVisible(object->objectId)) nspname = NULL; else nspname = get_namespace_name(opcForm->opcnamespace); appendStringInfo(&buffer, _("operator class %s for access method %s"), quote_qualified_identifier(nspname, NameStr(opcForm->opcname)), NameStr(amForm->amname)); ReleaseSysCache(amTup); ReleaseSysCache(opcTup); break; } case OCLASS_OPFAMILY: getOpFamilyDescription(&buffer, object->objectId); break; case OCLASS_AMOP: { Relation amopDesc; HeapTuple tup; ScanKeyData skey[1]; SysScanDesc amscan; Form_pg_amop amopForm; StringInfoData opfam; amopDesc = heap_open(AccessMethodOperatorRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(amscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for amop entry %u", object->objectId); amopForm = (Form_pg_amop) GETSTRUCT(tup); initStringInfo(&opfam); getOpFamilyDescription(&opfam, amopForm->amopfamily); /*------ translator: %d is the operator strategy (a number), the first two %s's are data type names, the third %s is the description of the operator family, and the last %s is the textual form of the operator with arguments. */ appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"), amopForm->amopstrategy, format_type_be(amopForm->amoplefttype), format_type_be(amopForm->amoprighttype), opfam.data, format_operator(amopForm->amopopr)); pfree(opfam.data); systable_endscan(amscan); heap_close(amopDesc, AccessShareLock); break; } case OCLASS_AMPROC: { Relation amprocDesc; ScanKeyData skey[1]; SysScanDesc amscan; HeapTuple tup; Form_pg_amproc amprocForm; StringInfoData opfam; amprocDesc = heap_open(AccessMethodProcedureRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(amscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for amproc entry %u", object->objectId); amprocForm = (Form_pg_amproc) GETSTRUCT(tup); initStringInfo(&opfam); getOpFamilyDescription(&opfam, amprocForm->amprocfamily); /*------ translator: %d is the function number, the first two %s's are data type names, the third %s is the description of the operator family, and the last %s is the textual form of the function with arguments. */ appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"), amprocForm->amprocnum, format_type_be(amprocForm->amproclefttype), format_type_be(amprocForm->amprocrighttype), opfam.data, format_procedure(amprocForm->amproc)); pfree(opfam.data); systable_endscan(amscan); heap_close(amprocDesc, AccessShareLock); break; } case OCLASS_REWRITE: { Relation ruleDesc; ScanKeyData skey[1]; SysScanDesc rcscan; HeapTuple tup; Form_pg_rewrite rule; ruleDesc = heap_open(RewriteRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(rcscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for rule %u", object->objectId); rule = (Form_pg_rewrite) GETSTRUCT(tup); appendStringInfo(&buffer, _("rule %s on "), NameStr(rule->rulename)); getRelationDescription(&buffer, rule->ev_class); systable_endscan(rcscan); heap_close(ruleDesc, AccessShareLock); break; } case OCLASS_TRIGGER: { Relation trigDesc; ScanKeyData skey[1]; SysScanDesc tgscan; HeapTuple tup; Form_pg_trigger trig; trigDesc = heap_open(TriggerRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(tgscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for trigger %u", object->objectId); trig = (Form_pg_trigger) GETSTRUCT(tup); appendStringInfo(&buffer, _("trigger %s on "), NameStr(trig->tgname)); getRelationDescription(&buffer, trig->tgrelid); systable_endscan(tgscan); heap_close(trigDesc, AccessShareLock); break; } case OCLASS_SCHEMA: { char *nspname; nspname = get_namespace_name(object->objectId); if (!nspname) elog(ERROR, "cache lookup failed for namespace %u", object->objectId); appendStringInfo(&buffer, _("schema %s"), nspname); break; } case OCLASS_TSPARSER: { HeapTuple tup; tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search parser %u", object->objectId); appendStringInfo(&buffer, _("text search parser %s"), NameStr(((Form_pg_ts_parser) GETSTRUCT(tup))->prsname)); ReleaseSysCache(tup); break; } case OCLASS_TSDICT: { HeapTuple tup; tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search dictionary %u", object->objectId); appendStringInfo(&buffer, _("text search dictionary %s"), NameStr(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname)); ReleaseSysCache(tup); break; } case OCLASS_TSTEMPLATE: { HeapTuple tup; tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search template %u", object->objectId); appendStringInfo(&buffer, _("text search template %s"), NameStr(((Form_pg_ts_template) GETSTRUCT(tup))->tmplname)); ReleaseSysCache(tup); break; } case OCLASS_TSCONFIG: { HeapTuple tup; tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search configuration %u", object->objectId); appendStringInfo(&buffer, _("text search configuration %s"), NameStr(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname)); ReleaseSysCache(tup); break; } case OCLASS_ROLE: { appendStringInfo(&buffer, _("role %s"), GetUserNameFromId(object->objectId)); break; } case OCLASS_DATABASE: { char *datname; datname = get_database_name(object->objectId); if (!datname) elog(ERROR, "cache lookup failed for database %u", object->objectId); appendStringInfo(&buffer, _("database %s"), datname); break; } case OCLASS_TBLSPACE: { char *tblspace; tblspace = get_tablespace_name(object->objectId); if (!tblspace) elog(ERROR, "cache lookup failed for tablespace %u", object->objectId); appendStringInfo(&buffer, _("tablespace %s"), tblspace); break; } case OCLASS_FDW: { ForeignDataWrapper *fdw; fdw = GetForeignDataWrapper(object->objectId); appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname); break; } case OCLASS_FOREIGN_SERVER: { ForeignServer *srv; srv = GetForeignServer(object->objectId); appendStringInfo(&buffer, _("server %s"), srv->servername); break; } case OCLASS_USER_MAPPING: { HeapTuple tup; Oid useid; char *usename; tup = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for user mapping %u", object->objectId); useid = ((Form_pg_user_mapping) GETSTRUCT(tup))->umuser; ReleaseSysCache(tup); if (OidIsValid(useid)) usename = GetUserNameFromId(useid); else usename = "public"; appendStringInfo(&buffer, _("user mapping for %s"), usename); break; } case OCLASS_DEFACL: { Relation defaclrel; ScanKeyData skey[1]; SysScanDesc rcscan; HeapTuple tup; Form_pg_default_acl defacl; defaclrel = heap_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(rcscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for default ACL %u", object->objectId); defacl = (Form_pg_default_acl) GETSTRUCT(tup); switch (defacl->defaclobjtype) { case DEFACLOBJ_RELATION: appendStringInfo(&buffer, _("default privileges on new relations belonging to role %s"), GetUserNameFromId(defacl->defaclrole)); break; case DEFACLOBJ_SEQUENCE: appendStringInfo(&buffer, _("default privileges on new sequences belonging to role %s"), GetUserNameFromId(defacl->defaclrole)); break; case DEFACLOBJ_FUNCTION: appendStringInfo(&buffer, _("default privileges on new functions belonging to role %s"), GetUserNameFromId(defacl->defaclrole)); break; case DEFACLOBJ_TYPE: appendStringInfo(&buffer, _("default privileges on new types belonging to role %s"), GetUserNameFromId(defacl->defaclrole)); break; default: /* shouldn't get here */ appendStringInfo(&buffer, _("default privileges belonging to role %s"), GetUserNameFromId(defacl->defaclrole)); break; } if (OidIsValid(defacl->defaclnamespace)) { appendStringInfo(&buffer, _(" in schema %s"), get_namespace_name(defacl->defaclnamespace)); } systable_endscan(rcscan); heap_close(defaclrel, AccessShareLock); break; } case OCLASS_EXTENSION: { char *extname; extname = get_extension_name(object->objectId); if (!extname) elog(ERROR, "cache lookup failed for extension %u", object->objectId); appendStringInfo(&buffer, _("extension %s"), extname); break; } case OCLASS_EVENT_TRIGGER: { HeapTuple tup; tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for event trigger %u", object->objectId); appendStringInfo(&buffer, _("event trigger %s"), NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname)); ReleaseSysCache(tup); break; } default: appendStringInfo(&buffer, "unrecognized object %u %u %d", object->classId, object->objectId, object->objectSubId); break; } return buffer.data; }
Definition at line 2160 of file objectaddress.c.
References ObjectAddress::classId, getObjectDescription(), ObjectAddress::objectId, and ObjectAddress::objectSubId.
Referenced by AlterObjectNamespace_internal(), AlterObjectRename_internal(), and CheckSetNamespace().
{ ObjectAddress address; address.classId = classid; address.objectId = objid; address.objectSubId = 0; return getObjectDescription(&address); }
char* getObjectIdentity | ( | const ObjectAddress * | object | ) |
Definition at line 2674 of file objectaddress.c.
References AccessMethodOperatorOidIndexId, AccessMethodOperatorRelationId, AccessMethodProcedureOidIndexId, AccessMethodProcedureRelationId, AccessShareLock, AMOID, appendStringInfo(), appendStringInfoString(), AttrDefaultOidIndexId, AttrDefaultRelationId, BTEqualStrategyNumber, CastRelationId, CLAOID, ObjectAddress::classId, COLLOID, CONSTROID, CONVOID, StringInfoData::data, DEFACLOBJ_FUNCTION, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, DefaultAclOidIndexId, DefaultAclRelationId, elog, ERROR, EVENTTRIGGEROID, ForeignDataWrapper::fdwname, format_operator_qualified(), format_procedure_qualified(), format_type_be_qualified(), get_catalog_object_by_oid(), get_database_name(), get_extension_name(), get_namespace_name(), get_relid_attribute_name(), get_tablespace_name(), GetForeignDataWrapper(), GetForeignServer(), getObjectClass(), getObjectIdentity(), getOpFamilyIdentity(), getRelationIdentity(), GETSTRUCT, GetUserNameFromId(), heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), LANGOID, NameStr, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectIdGetDatum, ObjectAddress::objectSubId, 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_PROC, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_TBLSPACE, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, OCLASS_USER_MAPPING, OidIsValid, pfree(), quote_identifier(), quote_qualified_identifier(), ReleaseSysCache(), RewriteRelationId, ScanKeyInit(), SearchSysCache1, ForeignServer::servername, SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), TriggerRelationId, TSCONFIGOID, TSDICTOID, TSPARSEROID, TSTEMPLATEOID, USERMAPPINGOID, and username.
Referenced by check_relation_privileges(), check_schema_perms(), EventTriggerSQLDropAddObject(), getObjectIdentity(), pg_identify_object(), sepgsql_attribute_drop(), sepgsql_attribute_post_create(), sepgsql_attribute_relabel(), sepgsql_attribute_setattr(), sepgsql_database_drop(), sepgsql_database_relabel(), sepgsql_database_setattr(), sepgsql_proc_drop(), sepgsql_proc_execute(), sepgsql_proc_post_create(), sepgsql_proc_relabel(), sepgsql_proc_setattr(), sepgsql_relation_drop(), sepgsql_relation_post_create(), sepgsql_relation_relabel(), sepgsql_relation_setattr(), sepgsql_schema_drop(), and sepgsql_schema_relabel().
{ StringInfoData buffer; initStringInfo(&buffer); switch (getObjectClass(object)) { case OCLASS_CLASS: getRelationIdentity(&buffer, object->objectId); if (object->objectSubId != 0) { char *attr; attr = get_relid_attribute_name(object->objectId, object->objectSubId); appendStringInfo(&buffer, ".%s", quote_identifier(attr)); } break; case OCLASS_PROC: appendStringInfo(&buffer, "%s", format_procedure_qualified(object->objectId)); break; case OCLASS_TYPE: appendStringInfo(&buffer, "%s", format_type_be_qualified(object->objectId)); break; case OCLASS_CAST: { Relation castRel; HeapTuple tup; Form_pg_cast castForm; castRel = heap_open(CastRelationId, AccessShareLock); tup = get_catalog_object_by_oid(castRel, object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for cast %u", object->objectId); castForm = (Form_pg_cast) GETSTRUCT(tup); appendStringInfo(&buffer, "(%s AS %s)", format_type_be_qualified(castForm->castsource), format_type_be_qualified(castForm->casttarget)); heap_close(castRel, AccessShareLock); break; } case OCLASS_COLLATION: { HeapTuple collTup; Form_pg_collation coll; char *schema; collTup = SearchSysCache1(COLLOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(collTup)) elog(ERROR, "cache lookup failed for collation %u", object->objectId); coll = (Form_pg_collation) GETSTRUCT(collTup); schema = get_namespace_name(coll->collnamespace); appendStringInfoString(&buffer, quote_qualified_identifier(schema, NameStr(coll->collname))); ReleaseSysCache(collTup); break; } case OCLASS_CONSTRAINT: { HeapTuple conTup; Form_pg_constraint con; conTup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(conTup)) elog(ERROR, "cache lookup failed for constraint %u", object->objectId); con = (Form_pg_constraint) GETSTRUCT(conTup); if (OidIsValid(con->conrelid)) { appendStringInfo(&buffer, "%s on ", quote_identifier(NameStr(con->conname))); getRelationIdentity(&buffer, con->conrelid); } else { ObjectAddress domain; domain.classId = TypeRelationId; domain.objectId = con->contypid; domain.objectSubId = 0; appendStringInfo(&buffer, "%s on %s", quote_identifier(NameStr(con->conname)), getObjectIdentity(&domain)); } ReleaseSysCache(conTup); break; } case OCLASS_CONVERSION: { HeapTuple conTup; Form_pg_conversion conForm; conTup = SearchSysCache1(CONVOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(conTup)) elog(ERROR, "cache lookup failed for conversion %u", object->objectId); conForm = (Form_pg_conversion) GETSTRUCT(conTup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(conForm->conname))); ReleaseSysCache(conTup); break; } case OCLASS_DEFAULT: { Relation attrdefDesc; ScanKeyData skey[1]; SysScanDesc adscan; HeapTuple tup; Form_pg_attrdef attrdef; ObjectAddress colobject; attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(adscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for attrdef %u", object->objectId); attrdef = (Form_pg_attrdef) GETSTRUCT(tup); colobject.classId = RelationRelationId; colobject.objectId = attrdef->adrelid; colobject.objectSubId = attrdef->adnum; appendStringInfo(&buffer, "for %s", getObjectIdentity(&colobject)); systable_endscan(adscan); heap_close(attrdefDesc, AccessShareLock); break; } case OCLASS_LANGUAGE: { HeapTuple langTup; Form_pg_language langForm; langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(langTup)) elog(ERROR, "cache lookup failed for language %u", object->objectId); langForm = (Form_pg_language) GETSTRUCT(langTup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(langForm->lanname))); ReleaseSysCache(langTup); break; } case OCLASS_LARGEOBJECT: appendStringInfo(&buffer, "%u", object->objectId); break; case OCLASS_OPERATOR: appendStringInfo(&buffer, "%s", format_operator_qualified(object->objectId)); break; case OCLASS_OPCLASS: { HeapTuple opcTup; Form_pg_opclass opcForm; HeapTuple amTup; Form_pg_am amForm; char *schema; opcTup = SearchSysCache1(CLAOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(opcTup)) elog(ERROR, "cache lookup failed for opclass %u", object->objectId); opcForm = (Form_pg_opclass) GETSTRUCT(opcTup); schema = get_namespace_name(opcForm->opcnamespace); amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opcForm->opcmethod)); if (!HeapTupleIsValid(amTup)) elog(ERROR, "cache lookup failed for access method %u", opcForm->opcmethod); amForm = (Form_pg_am) GETSTRUCT(amTup); appendStringInfo(&buffer, "%s", quote_qualified_identifier(schema, NameStr(opcForm->opcname))); appendStringInfo(&buffer, " for %s", quote_identifier(NameStr(amForm->amname))); ReleaseSysCache(amTup); ReleaseSysCache(opcTup); break; } case OCLASS_OPFAMILY: getOpFamilyIdentity(&buffer, object->objectId); break; case OCLASS_AMOP: { Relation amopDesc; HeapTuple tup; ScanKeyData skey[1]; SysScanDesc amscan; Form_pg_amop amopForm; StringInfoData opfam; amopDesc = heap_open(AccessMethodOperatorRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(amscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for amop entry %u", object->objectId); amopForm = (Form_pg_amop) GETSTRUCT(tup); initStringInfo(&opfam); getOpFamilyIdentity(&opfam, amopForm->amopfamily); appendStringInfo(&buffer, "operator %d (%s, %s) of %s", amopForm->amopstrategy, format_type_be_qualified(amopForm->amoplefttype), format_type_be_qualified(amopForm->amoprighttype), opfam.data); pfree(opfam.data); systable_endscan(amscan); heap_close(amopDesc, AccessShareLock); break; } case OCLASS_AMPROC: { Relation amprocDesc; ScanKeyData skey[1]; SysScanDesc amscan; HeapTuple tup; Form_pg_amproc amprocForm; StringInfoData opfam; amprocDesc = heap_open(AccessMethodProcedureRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(amscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for amproc entry %u", object->objectId); amprocForm = (Form_pg_amproc) GETSTRUCT(tup); initStringInfo(&opfam); getOpFamilyIdentity(&opfam, amprocForm->amprocfamily); appendStringInfo(&buffer, "function %d (%s, %s) of %s", amprocForm->amprocnum, format_type_be_qualified(amprocForm->amproclefttype), format_type_be_qualified(amprocForm->amprocrighttype), opfam.data); pfree(opfam.data); systable_endscan(amscan); heap_close(amprocDesc, AccessShareLock); break; } case OCLASS_REWRITE: { Relation ruleDesc; HeapTuple tup; Form_pg_rewrite rule; ruleDesc = heap_open(RewriteRelationId, AccessShareLock); tup = get_catalog_object_by_oid(ruleDesc, object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for rule %u", object->objectId); rule = (Form_pg_rewrite) GETSTRUCT(tup); appendStringInfo(&buffer, "%s on ", quote_identifier(NameStr(rule->rulename))); getRelationIdentity(&buffer, rule->ev_class); heap_close(ruleDesc, AccessShareLock); break; } case OCLASS_TRIGGER: { Relation trigDesc; HeapTuple tup; Form_pg_trigger trig; trigDesc = heap_open(TriggerRelationId, AccessShareLock); tup = get_catalog_object_by_oid(trigDesc, object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for trigger %u", object->objectId); trig = (Form_pg_trigger) GETSTRUCT(tup); appendStringInfo(&buffer, "%s on ", quote_identifier(NameStr(trig->tgname))); getRelationIdentity(&buffer, trig->tgrelid); heap_close(trigDesc, AccessShareLock); break; } case OCLASS_SCHEMA: { char *nspname; nspname = get_namespace_name(object->objectId); if (!nspname) elog(ERROR, "cache lookup failed for namespace %u", object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(nspname)); break; } case OCLASS_TSPARSER: { HeapTuple tup; Form_pg_ts_parser formParser; tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search parser %u", object->objectId); formParser = (Form_pg_ts_parser) GETSTRUCT(tup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(formParser->prsname))); ReleaseSysCache(tup); break; } case OCLASS_TSDICT: { HeapTuple tup; Form_pg_ts_dict formDict; tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search dictionary %u", object->objectId); formDict = (Form_pg_ts_dict) GETSTRUCT(tup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(formDict->dictname))); ReleaseSysCache(tup); break; } case OCLASS_TSTEMPLATE: { HeapTuple tup; Form_pg_ts_template formTmpl; tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search template %u", object->objectId); formTmpl = (Form_pg_ts_template) GETSTRUCT(tup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(formTmpl->tmplname))); ReleaseSysCache(tup); break; } case OCLASS_TSCONFIG: { HeapTuple tup; Form_pg_ts_config formCfg; tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search configuration %u", object->objectId); formCfg = (Form_pg_ts_config) GETSTRUCT(tup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(formCfg->cfgname))); ReleaseSysCache(tup); break; } case OCLASS_ROLE: { char *username; username = GetUserNameFromId(object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(username)); break; } case OCLASS_DATABASE: { char *datname; datname = get_database_name(object->objectId); if (!datname) elog(ERROR, "cache lookup failed for database %u", object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(datname)); break; } case OCLASS_TBLSPACE: { char *tblspace; tblspace = get_tablespace_name(object->objectId); if (!tblspace) elog(ERROR, "cache lookup failed for tablespace %u", object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(tblspace)); break; } case OCLASS_FDW: { ForeignDataWrapper *fdw; fdw = GetForeignDataWrapper(object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(fdw->fdwname)); break; } case OCLASS_FOREIGN_SERVER: { ForeignServer *srv; srv = GetForeignServer(object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(srv->servername)); break; } case OCLASS_USER_MAPPING: { HeapTuple tup; Oid useid; const char *usename; tup = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for user mapping %u", object->objectId); useid = ((Form_pg_user_mapping) GETSTRUCT(tup))->umuser; ReleaseSysCache(tup); if (OidIsValid(useid)) usename = quote_identifier(GetUserNameFromId(useid)); else usename = "public"; appendStringInfo(&buffer, "%s", usename); break; } case OCLASS_DEFACL: { Relation defaclrel; ScanKeyData skey[1]; SysScanDesc rcscan; HeapTuple tup; Form_pg_default_acl defacl; defaclrel = heap_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); tup = systable_getnext(rcscan); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for default ACL %u", object->objectId); defacl = (Form_pg_default_acl) GETSTRUCT(tup); appendStringInfo(&buffer, "for role %s", quote_identifier(GetUserNameFromId(defacl->defaclrole))); if (OidIsValid(defacl->defaclnamespace)) { char *schema; schema = get_namespace_name(defacl->defaclnamespace); appendStringInfo(&buffer, " in schema %s", quote_identifier(schema)); } switch (defacl->defaclobjtype) { case DEFACLOBJ_RELATION: appendStringInfoString(&buffer, " on tables"); break; case DEFACLOBJ_SEQUENCE: appendStringInfoString(&buffer, " on sequences"); break; case DEFACLOBJ_FUNCTION: appendStringInfoString(&buffer, " on functions"); break; case DEFACLOBJ_TYPE: appendStringInfoString(&buffer, " on types"); break; } systable_endscan(rcscan); heap_close(defaclrel, AccessShareLock); break; } case OCLASS_EXTENSION: { char *extname; extname = get_extension_name(object->objectId); if (!extname) elog(ERROR, "cache lookup failed for extension %u", object->objectId); appendStringInfo(&buffer, "%s", quote_identifier(extname)); break; } case OCLASS_EVENT_TRIGGER: { HeapTuple tup; Form_pg_event_trigger trigForm; tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for event trigger %u", object->objectId); trigForm = (Form_pg_event_trigger) GETSTRUCT(tup); appendStringInfo(&buffer, "%s", quote_identifier(NameStr(trigForm->evtname))); ReleaseSysCache(tup); break; } default: appendStringInfo(&buffer, "unrecognized object %u %u %d", object->classId, object->objectId, object->objectSubId); break; } return buffer.data; }
char* getObjectTypeDescription | ( | const ObjectAddress * | object | ) |
Definition at line 2423 of file objectaddress.c.
References appendStringInfo(), ObjectAddress::classId, StringInfoData::data, getConstraintTypeDescription(), getObjectClass(), getProcedureTypeDescription(), getRelationTypeDescription(), initStringInfo(), ObjectAddress::objectId, ObjectAddress::objectSubId, 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_PROC, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_TBLSPACE, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, and OCLASS_USER_MAPPING.
Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().
{ StringInfoData buffer; initStringInfo(&buffer); switch (getObjectClass(object)) { case OCLASS_CLASS: getRelationTypeDescription(&buffer, object->objectId, object->objectSubId); break; case OCLASS_PROC: getProcedureTypeDescription(&buffer, object->objectId); break; case OCLASS_TYPE: appendStringInfo(&buffer, "type"); break; case OCLASS_CAST: appendStringInfo(&buffer, "cast"); break; case OCLASS_COLLATION: appendStringInfo(&buffer, "collation"); break; case OCLASS_CONSTRAINT: getConstraintTypeDescription(&buffer, object->objectId); break; case OCLASS_CONVERSION: appendStringInfo(&buffer, "conversion"); break; case OCLASS_DEFAULT: appendStringInfo(&buffer, "default value"); break; case OCLASS_LANGUAGE: appendStringInfo(&buffer, "language"); break; case OCLASS_LARGEOBJECT: appendStringInfo(&buffer, "large object"); break; case OCLASS_OPERATOR: appendStringInfo(&buffer, "operator"); break; case OCLASS_OPCLASS: appendStringInfo(&buffer, "operator class"); break; case OCLASS_OPFAMILY: appendStringInfo(&buffer, "operator family"); break; case OCLASS_AMOP: appendStringInfo(&buffer, "operator of access method"); break; case OCLASS_AMPROC: appendStringInfo(&buffer, "function of access method"); break; case OCLASS_REWRITE: appendStringInfo(&buffer, "rule"); break; case OCLASS_TRIGGER: appendStringInfo(&buffer, "trigger"); break; case OCLASS_SCHEMA: appendStringInfo(&buffer, "schema"); break; case OCLASS_TSPARSER: appendStringInfo(&buffer, "text search parser"); break; case OCLASS_TSDICT: appendStringInfo(&buffer, "text search dictionary"); break; case OCLASS_TSTEMPLATE: appendStringInfo(&buffer, "text search template"); break; case OCLASS_TSCONFIG: appendStringInfo(&buffer, "text search configuration"); break; case OCLASS_ROLE: appendStringInfo(&buffer, "role"); break; case OCLASS_DATABASE: appendStringInfo(&buffer, "database"); break; case OCLASS_TBLSPACE: appendStringInfo(&buffer, "tablespace"); break; case OCLASS_FDW: appendStringInfo(&buffer, "foreign-data wrapper"); break; case OCLASS_FOREIGN_SERVER: appendStringInfo(&buffer, "server"); break; case OCLASS_USER_MAPPING: appendStringInfo(&buffer, "user mapping"); break; case OCLASS_DEFACL: appendStringInfo(&buffer, "default acl"); break; case OCLASS_EXTENSION: appendStringInfo(&buffer, "extension"); break; case OCLASS_EVENT_TRIGGER: appendStringInfo(&buffer, "event trigger"); break; default: appendStringInfo(&buffer, "unrecognized %u", object->classId); break; } return buffer.data; }
static void getOpFamilyDescription | ( | StringInfo | buffer, | |
Oid | opfid | |||
) | [static] |
Definition at line 2244 of file objectaddress.c.
References _, AMOID, appendStringInfo(), elog, ERROR, get_namespace_name(), GETSTRUCT, HeapTupleIsValid, NameStr, NULL, ObjectIdGetDatum, OpfamilyIsVisible(), OPFAMILYOID, quote_qualified_identifier(), ReleaseSysCache(), and SearchSysCache1.
Referenced by getObjectDescription().
{ HeapTuple opfTup; Form_pg_opfamily opfForm; HeapTuple amTup; Form_pg_am amForm; char *nspname; opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid)); if (!HeapTupleIsValid(opfTup)) elog(ERROR, "cache lookup failed for opfamily %u", opfid); opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup); amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod)); if (!HeapTupleIsValid(amTup)) elog(ERROR, "cache lookup failed for access method %u", opfForm->opfmethod); amForm = (Form_pg_am) GETSTRUCT(amTup); /* Qualify the name if not visible in search path */ if (OpfamilyIsVisible(opfid)) nspname = NULL; else nspname = get_namespace_name(opfForm->opfnamespace); appendStringInfo(buffer, _("operator family %s for access method %s"), quote_qualified_identifier(nspname, NameStr(opfForm->opfname)), NameStr(amForm->amname)); ReleaseSysCache(amTup); ReleaseSysCache(opfTup); }
static void getOpFamilyIdentity | ( | StringInfo | buffer, | |
Oid | opfid | |||
) | [static] |
Definition at line 3311 of file objectaddress.c.
References AMOID, appendStringInfo(), elog, ERROR, get_namespace_name(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, OPFAMILYOID, quote_qualified_identifier(), ReleaseSysCache(), and SearchSysCache1.
Referenced by getObjectIdentity().
{ HeapTuple opfTup; Form_pg_opfamily opfForm; HeapTuple amTup; Form_pg_am amForm; char *schema; opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid)); if (!HeapTupleIsValid(opfTup)) elog(ERROR, "cache lookup failed for opfamily %u", opfid); opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup); amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod)); if (!HeapTupleIsValid(amTup)) elog(ERROR, "cache lookup failed for access method %u", opfForm->opfmethod); amForm = (Form_pg_am) GETSTRUCT(amTup); schema = get_namespace_name(opfForm->opfnamespace); appendStringInfo(buffer, "%s for %s", quote_qualified_identifier(schema, NameStr(opfForm->opfname)), NameStr(amForm->amname)); ReleaseSysCache(amTup); ReleaseSysCache(opfTup); }
static void getProcedureTypeDescription | ( | StringInfo | buffer, | |
Oid | procid | |||
) | [static] |
Definition at line 2648 of file objectaddress.c.
References appendStringInfo(), elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, PROCOID, ReleaseSysCache(), and SearchSysCache1.
Referenced by getObjectTypeDescription().
{ HeapTuple procTup; Form_pg_proc procForm; procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procid)); if (!HeapTupleIsValid(procTup)) elog(ERROR, "cache lookup failed for procedure %u", procid); procForm = (Form_pg_proc) GETSTRUCT(procTup); if (procForm->proisagg) appendStringInfo(buffer, "aggregate"); else appendStringInfo(buffer, "function"); ReleaseSysCache(procTup); }
static void getRelationDescription | ( | StringInfo | buffer, | |
Oid | relid | |||
) | [static] |
Definition at line 2175 of file objectaddress.c.
References _, appendStringInfo(), elog, ERROR, get_namespace_name(), GETSTRUCT, HeapTupleIsValid, NameStr, NULL, ObjectIdGetDatum, quote_qualified_identifier(), RelationIsVisible(), ReleaseSysCache(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, RELOID, and SearchSysCache1.
Referenced by getObjectDescription().
{ HeapTuple relTup; Form_pg_class relForm; char *nspname; char *relname; relTup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(relTup)) elog(ERROR, "cache lookup failed for relation %u", relid); relForm = (Form_pg_class) GETSTRUCT(relTup); /* Qualify the name if not visible in search path */ if (RelationIsVisible(relid)) nspname = NULL; else nspname = get_namespace_name(relForm->relnamespace); relname = quote_qualified_identifier(nspname, NameStr(relForm->relname)); switch (relForm->relkind) { case RELKIND_RELATION: appendStringInfo(buffer, _("table %s"), relname); break; case RELKIND_INDEX: appendStringInfo(buffer, _("index %s"), relname); break; case RELKIND_SEQUENCE: appendStringInfo(buffer, _("sequence %s"), relname); break; case RELKIND_TOASTVALUE: appendStringInfo(buffer, _("toast table %s"), relname); break; case RELKIND_VIEW: appendStringInfo(buffer, _("view %s"), relname); break; case RELKIND_MATVIEW: appendStringInfo(buffer, _("materialized view %s"), relname); break; case RELKIND_COMPOSITE_TYPE: appendStringInfo(buffer, _("composite type %s"), relname); break; case RELKIND_FOREIGN_TABLE: appendStringInfo(buffer, _("foreign table %s"), relname); break; default: /* shouldn't get here */ appendStringInfo(buffer, _("relation %s"), relname); break; } ReleaseSysCache(relTup); }
static void getRelationIdentity | ( | StringInfo | buffer, | |
Oid | relid | |||
) | [static] |
Definition at line 3345 of file objectaddress.c.
References appendStringInfo(), elog, ERROR, get_namespace_name(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, quote_qualified_identifier(), ReleaseSysCache(), RELOID, and SearchSysCache1.
Referenced by getObjectIdentity().
{ HeapTuple relTup; Form_pg_class relForm; char *schema; relTup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(relTup)) elog(ERROR, "cache lookup failed for relation %u", relid); relForm = (Form_pg_class) GETSTRUCT(relTup); schema = get_namespace_name(relForm->relnamespace); appendStringInfo(buffer, "%s", quote_qualified_identifier(schema, NameStr(relForm->relname))); ReleaseSysCache(relTup); }
static void getRelationTypeDescription | ( | StringInfo | buffer, | |
Oid | relid, | |||
int32 | objectSubId | |||
) | [static] |
Definition at line 2568 of file objectaddress.c.
References appendStringInfo(), elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, RELOID, and SearchSysCache1.
Referenced by getObjectTypeDescription().
{ HeapTuple relTup; Form_pg_class relForm; relTup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(relTup)) elog(ERROR, "cache lookup failed for relation %u", relid); relForm = (Form_pg_class) GETSTRUCT(relTup); switch (relForm->relkind) { case RELKIND_RELATION: appendStringInfo(buffer, "table"); break; case RELKIND_INDEX: appendStringInfo(buffer, "index"); break; case RELKIND_SEQUENCE: appendStringInfo(buffer, "sequence"); break; case RELKIND_TOASTVALUE: appendStringInfo(buffer, "toast table"); break; case RELKIND_VIEW: appendStringInfo(buffer, "view"); break; case RELKIND_MATVIEW: appendStringInfo(buffer, "materialized view"); break; case RELKIND_COMPOSITE_TYPE: appendStringInfo(buffer, "composite type"); break; case RELKIND_FOREIGN_TABLE: appendStringInfo(buffer, "foreign table"); break; default: /* shouldn't get here */ appendStringInfo(buffer, "relation"); break; } if (objectSubId != 0) appendStringInfo(buffer, " column"); ReleaseSysCache(relTup); }
Definition at line 1405 of file objectaddress.c.
References lengthof.
Referenced by EventTriggerSQLDropAddObject(), and pg_identify_object().
{ int index; for (index = 0; index < lengthof(ObjectProperty); index++) { if (ObjectProperty[index].class_oid == class_id) return true; } return false; }
Datum pg_describe_object | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2282 of file objectaddress.c.
References ObjectAddress::classId, cstring_to_text(), getObjectDescription(), ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_NULL, and PG_RETURN_TEXT_P.
{ Oid classid = PG_GETARG_OID(0); Oid objid = PG_GETARG_OID(1); int32 subobjid = PG_GETARG_INT32(2); char *description; ObjectAddress address; /* for "pinned" items in pg_depend, return null */ if (!OidIsValid(classid) && !OidIsValid(objid)) PG_RETURN_NULL(); address.classId = classid; address.objectId = objid; address.objectSubId = subobjid; description = getObjectDescription(&address); PG_RETURN_TEXT_P(cstring_to_text(description)); }
Datum pg_identify_object | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2306 of file objectaddress.c.
References AccessShareLock, BlessTupleDesc(), ObjectAddress::classId, CreateTemplateTupleDesc(), CStringGetTextDatum, DatumGetName, elog, ERROR, get_catalog_object_by_oid(), get_namespace_name(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_namensp_unique(), getObjectIdentity(), getObjectTypeDescription(), heap_close, heap_form_tuple(), heap_getattr, heap_open(), HeapTupleGetDatum, InvalidAttrNumber, is_objectclass_supported(), NameStr, NULL, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_DATUM, quote_identifier(), RelationGetDescr, TEXTOID, TupleDescInitEntry(), and values.
{ Oid classid = PG_GETARG_OID(0); Oid objid = PG_GETARG_OID(1); int32 subobjid = PG_GETARG_INT32(2); Oid schema_oid = InvalidOid; const char *objname = NULL; ObjectAddress address; Datum values[4]; bool nulls[4]; TupleDesc tupdesc; HeapTuple htup; address.classId = classid; address.objectId = objid; address.objectSubId = subobjid; /* * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ tupdesc = CreateTemplateTupleDesc(4, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schema", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "identity", TEXTOID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); if (is_objectclass_supported(address.classId)) { HeapTuple objtup; Relation catalog = heap_open(address.classId, AccessShareLock); objtup = get_catalog_object_by_oid(catalog, address.objectId); if (objtup != NULL) { bool isnull; AttrNumber nspAttnum; AttrNumber nameAttnum; nspAttnum = get_object_attnum_namespace(address.classId); if (nspAttnum != InvalidAttrNumber) { schema_oid = heap_getattr(objtup, nspAttnum, RelationGetDescr(catalog), &isnull); if (isnull) elog(ERROR, "invalid null namespace in object %u/%u/%d", address.classId, address.objectId, address.objectSubId); } /* * We only return the object name if it can be used (together * with the schema name, if any) as an unique identifier. */ if (get_object_namensp_unique(address.classId)) { nameAttnum = get_object_attnum_name(address.classId); if (nameAttnum != InvalidAttrNumber) { Datum nameDatum; nameDatum = heap_getattr(objtup, nameAttnum, RelationGetDescr(catalog), &isnull); if (isnull) elog(ERROR, "invalid null name in object %u/%u/%d", address.classId, address.objectId, address.objectSubId); objname = quote_identifier(NameStr(*(DatumGetName(nameDatum)))); } } } heap_close(catalog, AccessShareLock); } /* object type */ values[0] = CStringGetTextDatum(getObjectTypeDescription(&address)); nulls[0] = false; /* schema name */ if (OidIsValid(schema_oid)) { const char *schema = quote_identifier(get_namespace_name(schema_oid)); values[1] = CStringGetTextDatum(schema); nulls[1] = false; } else nulls[1] = true; /* object name */ if (objname) { values[2] = CStringGetTextDatum(objname); nulls[2] = false; } else nulls[2] = true; /* object identity */ values[3] = CStringGetTextDatum(getObjectIdentity(&address)); nulls[3] = false; htup = heap_form_tuple(tupdesc, values, nulls); PG_RETURN_DATUM(HeapTupleGetDatum(htup)); }
ObjectPropertyType ObjectProperty[] [static] |
Definition at line 103 of file objectaddress.c.