/* * Find object address for an object that is attached to a relation. * * Note that we take only an ACCESS_SHR_LOCK on the relation. We need not * pass down the lockmode_t from get_object_address(), because that is the lock * mode for the object itself, not the relation to which it is attached. */ static struct objaddr get_objaddr_relobj( objtype_e objtype, struct list *objname, struct relation** relp) { struct objaddr address; struct relation* relation = NULL; int nnames; const char *depname; /* Extract name of dependent object. */ depname = str_value(lfirst(list_tail(objname))); /* Separate relation name from dependent object name. */ nnames = list_length(objname); if (nnames < 2) { oid_t 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); address.objectSubId = 0; /* * Caller is expecting to get back the relation, even though we * didn't end up using it to find the rule. */ relation = heap_open(reloid, ACCESS_SHR_LOCK); } else { struct list* relname; oid_t reloid; /* Extract relation name and open relation. */ relname = list_truncate(list_copy(objname), nnames - 1); relation = heap_open_rngv(nl_to_range_var(relname), ACCESS_SHR_LOCK); reloid = REL_ID(relation); switch (objtype) { case OBJECT_RULE: address.classId = RewriteRelationId; address.objectId = get_rewrite_oid(reloid, depname, false); address.objectSubId = 0; break; case OBJECT_TRIGGER: address.classId = TriggerRelationId; address.objectId = get_trigger_oid(reloid, depname, false); address.objectSubId = 0; break; case OBJECT_CONSTRAINT: address.classId = ConstraintRelationId; address.objectId = get_constraint_oid(reloid, depname, false); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ address.classId = INVALID_OID; address.objectId = INVALID_OID; address.objectSubId = 0; } } /* Done. */ *relp = relation; return address; }
/* * Find object address for an object that is attached to a relation. * * Note that we take only an AccessShareLock on the relation. We need not * pass down the LOCKMODE from get_object_address(), because that is the lock * mode for the object itself, not the relation to which it is attached. */ static ObjectAddress get_object_address_relobject(ObjectType objtype, List *objname, Relation *relp) { 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); address.objectSubId = 0; 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, false); address.objectSubId = 0; break; case OBJECT_TRIGGER: address.classId = TriggerRelationId; address.objectId = get_trigger_oid(reloid, depname, false); address.objectSubId = 0; break; case OBJECT_CONSTRAINT: address.classId = ConstraintRelationId; address.objectId = get_constraint_oid(reloid, depname, false); 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; } } /* Done. */ *relp = relation; return address; }