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 + -
显示快捷键?