Esempio n. 1
0
/*
 * op_volatile
 *
 * Get the provolatile flag for the operator's underlying function.
 */
char
op_volatile(Oid opno)
{
	RegProcedure funcid = get_opcode(opno);

	if (funcid == (RegProcedure) InvalidOid)
		elog(ERROR, "operator %u does not exist", opno);

	return func_volatile((Oid) funcid);
}
Esempio n. 2
0
/*
 * ValidateProtocolFunction -- common code for finding readfn, writefn or validatorfn
 */
static Oid
ValidateProtocolFunction(List *fnName, ExtPtcFuncType fntype)
{
	Oid			fnOid;
	bool		retset;
	bool        retstrict;
	bool        retordered;
	Oid		   *true_oid_array;
	Oid 	    actual_rettype;
	Oid			desired_rettype;
	FuncDetailCode fdresult;
	AclResult	aclresult;
	Oid 		inputTypes[1] = {InvalidOid}; /* dummy */
	int			nargs = 0; /* true for all 3 function types at the moment */
	int			nvargs;
	
	if (fntype == EXTPTC_FUNC_VALIDATOR)
		desired_rettype = VOIDOID;
	else
		desired_rettype = INT4OID;

	/*
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  it also returns the true argument types to
	 * the function.
	 */
	fdresult = func_get_detail(fnName, NIL, nargs, inputTypes, false, false,
							   &fnOid, &actual_rettype, &retset, &retstrict,
							   &retordered, &nvargs, &true_oid_array, NULL);

	/* only valid case is a normal function not returning a set */
	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("function %s does not exist",
						func_signature_string(fnName, nargs, inputTypes))));
	
	if (retset)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("Invalid protocol function"),
				 errdetail("Protocol functions cannot return sets.")));		

	if (actual_rettype != desired_rettype)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("%s protocol function %s must return %s",
						func_type_to_name(fntype),
						func_signature_string(fnName, nargs, inputTypes),
						(fntype == EXTPTC_FUNC_VALIDATOR ? "void" : "an integer"))));
	
	if (func_volatile(fnOid) == PROVOLATILE_IMMUTABLE)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
				 errmsg("%s protocol function %s is declared IMMUTABLE",
						func_type_to_name(fntype),
						func_signature_string(fnName, nargs, inputTypes)),
				 errhint("PROTOCOL functions must be declared STABLE or VOLATILE")));

	
	/* Check protocol creator has permission to call the function */
	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fnOid));

	return fnOid;
}
Esempio n. 3
0
/*
 * Checks if the results of a function can be cached.
 * Only IMMUTABLE functions can be cached.
 *
 * Returns true if function results can be cached, false otherwise.
 */
static bool
isFuncCacheable(Oid fn_oid)
{
	char fn_provolatile = func_volatile(fn_oid);
	return (fn_provolatile == PROVOLATILE_IMMUTABLE);
}