fmgr.c

来自「PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统」· C语言 代码 · 共 1,918 行 · 第 1/4 页

C
1,918
字号
DatumOidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 3, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 4, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4, Datum arg5){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 5, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.arg[4] = arg5;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	fcinfo.argnull[4] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4, Datum arg5,				 Datum arg6){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 6, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.arg[4] = arg5;	fcinfo.arg[5] = arg6;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	fcinfo.argnull[4] = false;	fcinfo.argnull[5] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4, Datum arg5,				 Datum arg6, Datum arg7){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 7, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.arg[4] = arg5;	fcinfo.arg[5] = arg6;	fcinfo.arg[6] = arg7;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	fcinfo.argnull[4] = false;	fcinfo.argnull[5] = false;	fcinfo.argnull[6] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4, Datum arg5,				 Datum arg6, Datum arg7, Datum arg8){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 8, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.arg[4] = arg5;	fcinfo.arg[5] = arg6;	fcinfo.arg[6] = arg7;	fcinfo.arg[7] = arg8;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	fcinfo.argnull[4] = false;	fcinfo.argnull[5] = false;	fcinfo.argnull[6] = false;	fcinfo.argnull[7] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}DatumOidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,				 Datum arg3, Datum arg4, Datum arg5,				 Datum arg6, Datum arg7, Datum arg8,				 Datum arg9){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	Datum		result;	fmgr_info(functionId, &flinfo);	InitFunctionCallInfoData(fcinfo, &flinfo, 9, NULL, NULL);	fcinfo.arg[0] = arg1;	fcinfo.arg[1] = arg2;	fcinfo.arg[2] = arg3;	fcinfo.arg[3] = arg4;	fcinfo.arg[4] = arg5;	fcinfo.arg[5] = arg6;	fcinfo.arg[6] = arg7;	fcinfo.arg[7] = arg8;	fcinfo.arg[8] = arg9;	fcinfo.argnull[0] = false;	fcinfo.argnull[1] = false;	fcinfo.argnull[2] = false;	fcinfo.argnull[3] = false;	fcinfo.argnull[4] = false;	fcinfo.argnull[5] = false;	fcinfo.argnull[6] = false;	fcinfo.argnull[7] = false;	fcinfo.argnull[8] = false;	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return result;}/* * !!! OLD INTERFACE !!! * * fmgr() is the only remaining vestige of the old-style caller support * functions.  It's no longer used anywhere in the Postgres distribution, * but we should leave it around for a release or two to ease the transition * for user-supplied C functions.  OidFunctionCallN() replaces it for new * code. * * DEPRECATED, DO NOT USE IN NEW CODE */char *fmgr(Oid procedureId,...){	FmgrInfo	flinfo;	FunctionCallInfoData fcinfo;	int			n_arguments;	Datum		result;	fmgr_info(procedureId, &flinfo);	MemSet(&fcinfo, 0, sizeof(fcinfo));	fcinfo.flinfo = &flinfo;	fcinfo.nargs = flinfo.fn_nargs;	n_arguments = fcinfo.nargs;	if (n_arguments > 0)	{		va_list		pvar;		int			i;		if (n_arguments > FUNC_MAX_ARGS)			ereport(ERROR,					(errcode(ERRCODE_TOO_MANY_ARGUMENTS),			 errmsg("function %u has too many arguments (%d, maximum is %d)",					flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS)));		va_start(pvar, procedureId);		for (i = 0; i < n_arguments; i++)			fcinfo.arg[i] = (Datum) va_arg(pvar, char *);		va_end(pvar);	}	result = FunctionCallInvoke(&fcinfo);	/* Check for null result, since caller is clearly not expecting one */	if (fcinfo.isnull)		elog(ERROR, "function %u returned NULL", flinfo.fn_oid);	return (char *) result;}/*------------------------------------------------------------------------- *		Support routines for standard pass-by-reference datatypes * * Note: at some point, at least on some platforms, these might become * pass-by-value types.  Obviously Datum must be >= 8 bytes to allow * int64 or float8 to be pass-by-value.  I think that Float4GetDatum * and Float8GetDatum will need to be out-of-line routines anyway, * since just casting from float to Datum will not do the right thing; * some kind of trick with pointer-casting or a union will be needed. *------------------------------------------------------------------------- */DatumInt64GetDatum(int64 X){#ifndef INT64_IS_BUSTED	int64	   *retval = (int64 *) palloc(sizeof(int64));	*retval = X;	return PointerGetDatum(retval);#else							/* INT64_IS_BUSTED */	/*	 * On a machine with no 64-bit-int C datatype, sizeof(int64) will not be	 * 8, but we want Int64GetDatum to return an 8-byte object anyway, with	 * zeroes in the unused bits.  This is needed so that, for example, hash	 * join of int8 will behave properly.	 */	int64	   *retval = (int64 *) palloc0(Max(sizeof(int64), 8));	*retval = X;	return PointerGetDatum(retval);#endif   /* INT64_IS_BUSTED */}DatumFloat4GetDatum(float4 X){	float4	   *retval = (float4 *) palloc(sizeof(float4));	*retval = X;	return PointerGetDatum(retval);}DatumFloat8GetDatum(float8 X){	float8	   *retval = (float8 *) palloc(sizeof(float8));	*retval = X;	return PointerGetDatum(retval);}/*------------------------------------------------------------------------- *		Support routines for toastable datatypes *------------------------------------------------------------------------- */struct varlena *pg_detoast_datum(struct varlena * datum){	if (VARATT_IS_EXTENDED(datum))		return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);	else		return datum;}struct varlena *pg_detoast_datum_copy(struct varlena * datum){	if (VARATT_IS_EXTENDED(datum))		return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);	else	{		/* Make a modifiable copy of the varlena object */		Size		len = VARSIZE(datum);		struct varlena *result = (struct varlena *) palloc(len);		memcpy(result, datum, len);		return result;	}}struct varlena *pg_detoast_datum_slice(struct varlena * datum, int32 first, int32 count){	/* Only get the specified portion from the toast rel */	return (struct varlena *) heap_tuple_untoast_attr_slice((varattrib *) datum, first, count);}/*------------------------------------------------------------------------- *		Support routines for extracting info from fn_expr parse tree * * These are needed by polymorphic functions, which accept multiple possible * input types and need help from the parser to know what they've got. *------------------------------------------------------------------------- *//* * Get the actual type OID of the function return type * * Returns InvalidOid if information is not available */Oidget_fn_expr_rettype(FmgrInfo *flinfo){	Node	   *expr;	/*	 * can't return anything useful if we have no FmgrInfo or if its fn_expr	 * node has not been initialized	 */	if (!flinfo || !flinfo->fn_expr)		return InvalidOid;	expr = flinfo->fn_expr;	return exprType(expr);}/* * Get the actual type OID of a specific function argument (counting from 0) * * Returns InvalidOid if information is not available */Oidget_fn_expr_argtype(FmgrInfo *flinfo, int argnum){	/*	 * can't return anything useful if we have no FmgrInfo or if its fn_expr	 * node has not been initialized	 */	if (!flinfo || !flinfo->fn_expr)		return InvalidOid;	return get_call_expr_argtype(flinfo->fn_expr, argnum);}/* * Get the actual type OID of a specific function argument (counting from 0), * but working from the calling expression tree instead of FmgrInfo * * Returns InvalidOid if information is not available */Oidget_call_expr_argtype(Node *expr, int argnum){	List	   *args;	Oid			argtype;	if (expr == NULL)		return InvalidOid;	if (IsA(expr, FuncExpr))		args = ((FuncExpr *) expr)->args;	else if (IsA(expr, OpExpr))		args = ((OpExpr *) expr)->args;	else if (IsA(expr, DistinctExpr))		args = ((DistinctExpr *) expr)->args;	else if (IsA(expr, ScalarArrayOpExpr))		args = ((ScalarArrayOpExpr *) expr)->args;	else if (IsA(expr, NullIfExpr))		args = ((NullIfExpr *) expr)->args;	else		return InvalidOid;	if (argnum < 0 || argnum >= list_length(args))		return InvalidOid;	argtype = exprType((Node *) list_nth(args, argnum));	/*	 * special hack for ScalarArrayOpExpr: what the underlying function will	 * actually get passed is the element type of the array.	 */	if (IsA(expr, ScalarArrayOpExpr) &&		argnum == 1)		argtype = get_element_type(argtype);	return argtype;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?