示例#1
0
/*
 * 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;
}
示例#2
0
/*
 * 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;
}