Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

objectaddress.c File Reference

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

Data Structures

struct  ObjectPropertyType

Functions

static ObjectAddress get_object_address_unqualified (ObjectType objtype, List *qualname, bool missing_ok)
static ObjectAddress get_relation_by_qualified_name (ObjectType objtype, List *objname, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static ObjectAddress get_object_address_relobject (ObjectType objtype, List *objname, Relation *relp, bool missing_ok)
static ObjectAddress get_object_address_attribute (ObjectType objtype, List *objname, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static ObjectAddress get_object_address_type (ObjectType objtype, List *objname, bool missing_ok)
static ObjectAddress get_object_address_opcf (ObjectType objtype, List *objname, List *objargs, bool missing_ok)
static ObjectPropertyTypeget_object_property_data (Oid class_id)
static void getRelationDescription (StringInfo buffer, Oid relid)
static void getOpFamilyDescription (StringInfo buffer, Oid opfid)
static void getRelationTypeDescription (StringInfo buffer, Oid relid, int32 objectSubId)
static void getProcedureTypeDescription (StringInfo buffer, Oid procid)
static void getConstraintTypeDescription (StringInfo buffer, Oid constroid)
static void getOpFamilyIdentity (StringInfo buffer, Oid opfid)
static void getRelationIdentity (StringInfo buffer, Oid relid)
ObjectAddress get_object_address (ObjectType objtype, List *objname, List *objargs, Relation *relp, LOCKMODE lockmode, bool missing_ok)
void check_object_ownership (Oid roleid, ObjectType objtype, ObjectAddress address, List *objname, List *objargs, Relation relation)
Oid get_object_namespace (const ObjectAddress *address)
Oid get_object_oid_index (Oid class_id)
int get_object_catcache_oid (Oid class_id)
int get_object_catcache_name (Oid class_id)
AttrNumber get_object_attnum_name (Oid class_id)
AttrNumber get_object_attnum_namespace (Oid class_id)
AttrNumber get_object_attnum_owner (Oid class_id)
AttrNumber get_object_attnum_acl (Oid class_id)
AclObjectKind get_object_aclkind (Oid class_id)
bool get_object_namensp_unique (Oid class_id)
bool is_objectclass_supported (Oid class_id)
HeapTuple get_catalog_object_by_oid (Relation catalog, Oid objectId)
char * getObjectDescription (const ObjectAddress *object)
char * getObjectDescriptionOids (Oid classid, Oid objid)
Datum pg_describe_object (PG_FUNCTION_ARGS)
Datum pg_identify_object (PG_FUNCTION_ARGS)
char * getObjectTypeDescription (const ObjectAddress *object)
char * getObjectIdentity (const ObjectAddress *object)

Variables

static ObjectPropertyType ObjectProperty []

Function Documentation

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);
    }
}

HeapTuple get_catalog_object_by_oid ( Relation  catalog,
Oid  objectId 
)

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  ) 
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  ) 
AttrNumber get_object_attnum_namespace ( Oid  class_id  ) 
AttrNumber get_object_attnum_owner ( Oid  class_id  ) 
int get_object_catcache_name ( Oid  class_id  ) 
int get_object_catcache_oid ( Oid  class_id  ) 
bool get_object_namensp_unique ( Oid  class_id  ) 
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;
}

Oid get_object_oid_index ( Oid  class_id  ) 
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;
}

char* getObjectDescriptionOids ( Oid  classid,
Oid  objid 
)
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);
}

bool is_objectclass_supported ( Oid  class_id  ) 

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));
}


Variable Documentation

Definition at line 103 of file objectaddress.c.