From ad354a3d1a83b2d8824d9c0502c04b8e18892d82 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 5 Oct 2018 11:36:10 -0700 Subject: [PATCH v2 2/2] Replace fmgr.[ch] duplication with macro magic. Author: Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- src/backend/utils/fmgr/fmgr.c | 737 +--------------------------------- src/include/fmgr.h | 327 ++++++++------- 2 files changed, 176 insertions(+), 888 deletions(-) diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 86d5cef8108..f7c877feb8e 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -782,741 +782,6 @@ fmgr_security_definer(PG_FUNCTION_ARGS) * Support routines for callers of fmgr-compatible functions *------------------------------------------------------------------------- */ -/* - * These are for invocation of a specifically named function with a - * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. Also, the function cannot be one that needs to - * look at FmgrInfo, since there won't be any. - */ -Datum -DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 1); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 2); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 3); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 4); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 5); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 6); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 7); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 8); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = false; - fcinfo->args[7].datum = arg8; - fcinfo->args[7].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 9); - Datum result; - - InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = false; - fcinfo->args[7].datum = arg8; - fcinfo->args[7].isnull = false; - fcinfo->args[8].datum = arg9; - fcinfo->args[8].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -/* - * These functions work like the DirectFunctionCall functions except that - * they use the flinfo parameter to initialise the fcinfo for the call. - * It's recommended that the callee only use the fn_extra and fn_mcxt - * fields, as other fields will typically describe the calling function - * not the callee. Conversely, the calling function should not have - * used fn_extra, unless its use is known to be compatible with the callee's. - */ - -Datum -CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 1); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -Datum -CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 2); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - - result = (*func) (fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo->isnull) - elog(ERROR, "function %p returned NULL", (void *) func); - - return result; -} - -/* - * These are for invocation of a previously-looked-up function with a - * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. - */ -Datum -FunctionCall0Coll(FmgrInfo *flinfo, Oid collation) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 0); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL); - - 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; -} - -/* - * These are for invocation of a previously-looked-up function with a - * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. - */ -Datum -FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 1); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = 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; -} - -Datum -FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 2); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = 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; -} - -Datum -FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 3); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = 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; -} - -Datum -FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 4); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = 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; -} - -Datum -FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 5); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = 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; -} - -Datum -FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 6); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = 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; -} - -Datum -FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 7); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = 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; -} - -Datum -FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 8); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = false; - fcinfo->args[7].datum = arg8; - fcinfo->args[7].isnull = 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; -} - -Datum -FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9) -{ - STACK_FCINFO_FOR_ARGS(fcinfo, 9); - Datum result; - - InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL); - - fcinfo->args[0].datum = arg1; - fcinfo->args[0].isnull = false; - fcinfo->args[1].datum = arg2; - fcinfo->args[1].isnull = false; - fcinfo->args[2].datum = arg3; - fcinfo->args[2].isnull = false; - fcinfo->args[3].datum = arg4; - fcinfo->args[3].isnull = false; - fcinfo->args[4].datum = arg5; - fcinfo->args[4].isnull = false; - fcinfo->args[5].datum = arg6; - fcinfo->args[5].isnull = false; - fcinfo->args[6].datum = arg7; - fcinfo->args[6].isnull = false; - fcinfo->args[7].datum = arg8; - fcinfo->args[7].isnull = false; - fcinfo->args[8].datum = arg9; - fcinfo->args[8].isnull = 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; -} - - -/* - * These are for invocation of a function identified by OID with a - * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. These are essentially fmgr_info() followed - * by FunctionCallN(). If the same function is to be invoked repeatedly, - * do the fmgr_info() once and then use FunctionCallN(). - */ -Datum -OidFunctionCall0Coll(Oid functionId, Oid collation) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall0Coll(&flinfo, collation); -} - -Datum -OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall1Coll(&flinfo, collation, arg1); -} - -Datum -OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall2Coll(&flinfo, collation, arg1, arg2); -} - -Datum -OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3); -} - -Datum -OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4); -} - -Datum -OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5); -} - -Datum -OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, - arg6); -} - -Datum -OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, - arg6, arg7); -} - -Datum -OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8); -} - -Datum -OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9) -{ - FmgrInfo flinfo; - - fmgr_info(functionId, &flinfo); - - return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9); -} /* @@ -1578,7 +843,7 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod) char * OutputFunctionCall(FmgrInfo *flinfo, Datum val) { - return DatumGetCString(FunctionCall1(flinfo, val)); + return DatumGetCString(FunctionCall1(flinfo, val)); } /* diff --git a/src/include/fmgr.h b/src/include/fmgr.h index ee1dbd5fcbb..b522f5b4633 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -480,37 +480,99 @@ extern int no_such_variable /* These are for invocation of a specifically named function with a * directly-computed parameter list. Note that neither arguments nor result * are allowed to be NULL. + * + * Call like val = DirectFunctionCallColl(func, collation, a, b, .., y) */ -extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, - Datum arg1); -extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2); -extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); -extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); -extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); -extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); -extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); -extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); -extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); + +#define DirectFunctionCallColl(func, collation, ...) \ + DirectFunctionCallCollForN(func, NULL, collation, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + +#define DirectFunctionCallCollForN(func, flinfo, collation, nargs_, ...) \ + DirectFunctionCallExec(func, \ + MemoryForFunctionCallN(flinfo, nargs_, collation, NULL, NULL), \ + nargs_, \ + (Datum[]){__VA_ARGS__}) + +#define MemoryForFunctionCallN(Flinfo, Nargs, Collation, Context, Resultinfo) \ + (&(\ + union { \ + struct FunctionCallInfoData fcinfo; \ + char *fcinfo_data[SizeForFunctionCallInfoData(Nargs)]; \ + } \ + ){.fcinfo = {.flinfo = Flinfo, .context = Context, .nargs = Nargs, .resultinfo = Resultinfo, .fncollation = Collation} \ + }.fcinfo) + +static inline Datum +DirectFunctionCallExec(PGFunction func, FunctionCallInfo fcinfo, int nargs, Datum *args) +{ + Datum result; + + for (int argno = 0; argno < nargs; argno++) + { + fcinfo->args[argno].datum = args[argno]; + Assert(!fcinfo->args[argno].isnull); + } + + result = (*func) (fcinfo); + + /* Check for null result, since caller is clearly not expecting one */ + Assert(!fcinfo->isnull); + + return result; +} + +static inline Datum +FunctionCallExec(FunctionCallInfo fcinfo, int nargs, Datum *args) +{ + Datum result; + + for (int argno = 0; argno < nargs; argno++) + { + fcinfo->args[argno].datum = args[argno]; + Assert(!fcinfo->args[argno].isnull); + } + + result = FunctionCallInvoke(fcinfo); + + /* Check for null result, since caller is clearly not expecting one */ + Assert(!fcinfo->isnull); + + return result; +} + +static inline Datum +OidFunctionCallExec(Oid functionId, FunctionCallInfo fcinfo, int nargs, Datum *args) +{ + Datum result; + FmgrInfo flinfo; + + fmgr_info(functionId, &flinfo); + fcinfo->flinfo = &flinfo; + + for (int argno = 0; argno < nargs; argno++) + { + fcinfo->args[argno].datum = args[argno]; + Assert(!fcinfo->args[argno].isnull); + } + + result = FunctionCallInvoke(fcinfo); + + /* Check for null result, since caller is clearly not expecting one */ + Assert(!fcinfo->isnull); + + return result; +} + +/* for backward compatibility */ +#define DirectFunctionCall1Coll DirectFunctionCallColl +#define DirectFunctionCall2Coll DirectFunctionCallColl +#define DirectFunctionCall3Coll DirectFunctionCallColl +#define DirectFunctionCall4Coll DirectFunctionCallColl +#define DirectFunctionCall5Coll DirectFunctionCallColl +#define DirectFunctionCall6Coll DirectFunctionCallColl +#define DirectFunctionCall7Coll DirectFunctionCallColl +#define DirectFunctionCall8Coll DirectFunctionCallColl +#define DirectFunctionCall9Coll DirectFunctionCallColl /* * These functions work like the DirectFunctionCall functions except that @@ -520,46 +582,37 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, * not the callee. Conversely, the calling function should not have * used fn_extra, unless its use is known to be compatible with the callee's. */ -extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, - Oid collation, Datum arg1); -extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, - Oid collation, Datum arg1, Datum arg2); +#define CallerFInfoFunctionCall(func, flinfo, collation, ...) \ + DirectFunctionCallCollForN(func, flinfo, collation, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + +/* for backward compatibility */ +#define CallerFInfoFunctionCall1 CallerFInfoFunctionCall +#define CallerFInfoFunctionCall2 CallerFInfoFunctionCall + /* These are for invocation of a previously-looked-up function with a * directly-computed parameter list. Note that neither arguments nor result * are allowed to be NULL. */ -extern Datum FunctionCall0Coll(FmgrInfo *flinfo, Oid collation); -extern Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1); -extern Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2); -extern Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); -extern Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); -extern Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); -extern Datum FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); -extern Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); -extern Datum FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); -extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); +#define FunctionCallColl(flinfo, collation, ...) \ + FunctionCallCollForN(flinfo, collation, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + +#define FunctionCallCollForN(flinfo, collation, nargs_, ...) \ + FunctionCallExec(MemoryForFunctionCallN(flinfo, nargs_, collation, NULL, NULL), \ + nargs_, \ + (Datum[]){__VA_ARGS__}) + +/* for backward compatibility */ +#define FunctionCall0Coll FunctionCallColl +#define FunctionCall1Coll FunctionCallColl +#define FunctionCall2Coll FunctionCallColl +#define FunctionCall3Coll FunctionCallColl +#define FunctionCall4Coll FunctionCallColl +#define FunctionCall5Coll FunctionCallColl +#define FunctionCall6Coll FunctionCallColl +#define FunctionCall7Coll FunctionCallColl +#define FunctionCall8Coll FunctionCallColl +#define FunctionCall9Coll FunctionCallColl /* These are for invocation of a function identified by OID with a * directly-computed parameter list. Note that neither arguments nor result @@ -567,98 +620,68 @@ extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, * FunctionCallN(). If the same function is to be invoked repeatedly, do the * fmgr_info() once and then use FunctionCallN(). */ -extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation); -extern Datum OidFunctionCall1Coll(Oid functionId, Oid collation, - Datum arg1); -extern Datum OidFunctionCall2Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2); -extern Datum OidFunctionCall3Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); -extern Datum OidFunctionCall4Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); -extern Datum OidFunctionCall5Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); -extern Datum OidFunctionCall6Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); -extern Datum OidFunctionCall7Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); -extern Datum OidFunctionCall8Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); -extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); + +#define OidFunctionCallColl(oid, collation, ...) \ + OidFunctionCallCollForN(oid, collation, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + +#define OidFunctionCallCollForN(oid, collation, nargs_, ...) \ + OidFunctionCallExec(oid, MemoryForFunctionCallN(NULL, nargs_, collation, NULL, NULL), \ + nargs_, \ + (Datum[]){__VA_ARGS__}) +#define OidFunctionCall0Coll OidFunctionCallColl +#define OidFunctionCall1Coll OidFunctionCallColl +#define OidFunctionCall2Coll OidFunctionCallColl +#define OidFunctionCall3Coll OidFunctionCallColl +#define OidFunctionCall4Coll OidFunctionCallColl +#define OidFunctionCall5Coll OidFunctionCallColl +#define OidFunctionCall6Coll OidFunctionCallColl +#define OidFunctionCall7Coll OidFunctionCallColl +#define OidFunctionCall8Coll OidFunctionCallColl +#define OidFunctionCall9Coll OidFunctionCallColl /* These macros allow the collation argument to be omitted (with a default of * InvalidOid, ie, no collation). They exist mostly for backwards * compatibility of source code. */ -#define DirectFunctionCall1(func, arg1) \ - DirectFunctionCall1Coll(func, InvalidOid, arg1) -#define DirectFunctionCall2(func, arg1, arg2) \ - DirectFunctionCall2Coll(func, InvalidOid, arg1, arg2) -#define DirectFunctionCall3(func, arg1, arg2, arg3) \ - DirectFunctionCall3Coll(func, InvalidOid, arg1, arg2, arg3) -#define DirectFunctionCall4(func, arg1, arg2, arg3, arg4) \ - DirectFunctionCall4Coll(func, InvalidOid, arg1, arg2, arg3, arg4) -#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5) \ - DirectFunctionCall5Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5) -#define DirectFunctionCall6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ - DirectFunctionCall6Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) -#define DirectFunctionCall7(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - DirectFunctionCall7Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -#define DirectFunctionCall8(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ - DirectFunctionCall8Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#define DirectFunctionCall9(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ - DirectFunctionCall9Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) -#define FunctionCall1(flinfo, arg1) \ - FunctionCall1Coll(flinfo, InvalidOid, arg1) -#define FunctionCall2(flinfo, arg1, arg2) \ - FunctionCall2Coll(flinfo, InvalidOid, arg1, arg2) -#define FunctionCall3(flinfo, arg1, arg2, arg3) \ - FunctionCall3Coll(flinfo, InvalidOid, arg1, arg2, arg3) -#define FunctionCall4(flinfo, arg1, arg2, arg3, arg4) \ - FunctionCall4Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4) -#define FunctionCall5(flinfo, arg1, arg2, arg3, arg4, arg5) \ - FunctionCall5Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5) -#define FunctionCall6(flinfo, arg1, arg2, arg3, arg4, arg5, arg6) \ - FunctionCall6Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) -#define FunctionCall7(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - FunctionCall7Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -#define FunctionCall8(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ - FunctionCall8Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#define FunctionCall9(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ - FunctionCall9Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) -#define OidFunctionCall0(functionId) \ - OidFunctionCall0Coll(functionId, InvalidOid) -#define OidFunctionCall1(functionId, arg1) \ - OidFunctionCall1Coll(functionId, InvalidOid, arg1) -#define OidFunctionCall2(functionId, arg1, arg2) \ - OidFunctionCall2Coll(functionId, InvalidOid, arg1, arg2) -#define OidFunctionCall3(functionId, arg1, arg2, arg3) \ - OidFunctionCall3Coll(functionId, InvalidOid, arg1, arg2, arg3) -#define OidFunctionCall4(functionId, arg1, arg2, arg3, arg4) \ - OidFunctionCall4Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4) -#define OidFunctionCall5(functionId, arg1, arg2, arg3, arg4, arg5) \ - OidFunctionCall5Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5) -#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6) \ - OidFunctionCall6Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) -#define OidFunctionCall7(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ - OidFunctionCall7Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -#define OidFunctionCall8(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ - OidFunctionCall8Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#define OidFunctionCall9(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ - OidFunctionCall9Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + +#define DirectFunctionCall(func, ...) \ + DirectFunctionCallColl(func, InvalidOid, __VA_ARGS__) +#define FunctionCall(finfo, ...) \ + FunctionCallColl(finfo, InvalidOid, __VA_ARGS__) +#define OidFunctionCall(oid, ...) \ + OidFunctionCallColl(oid, InvalidOid, __VA_ARGS__) + +#define DirectFunctionCall1 DirectFunctionCall +#define DirectFunctionCall2 DirectFunctionCall +#define DirectFunctionCall3 DirectFunctionCall +#define DirectFunctionCall4 DirectFunctionCall +#define DirectFunctionCall5 DirectFunctionCall +#define DirectFunctionCall6 DirectFunctionCall +#define DirectFunctionCall7 DirectFunctionCall +#define DirectFunctionCall8 DirectFunctionCall +#define DirectFunctionCall9 DirectFunctionCall + +#define FunctionCall1 FunctionCall +#define FunctionCall2 FunctionCall +#define FunctionCall3 FunctionCall +#define FunctionCall4 FunctionCall +#define FunctionCall5 FunctionCall +#define FunctionCall6 FunctionCall +#define FunctionCall7 FunctionCall +#define FunctionCall8 FunctionCall +#define FunctionCall9 FunctionCall + +#define OidFunctionCall0 OidFunctionCall +#define OidFunctionCall1 OidFunctionCall +#define OidFunctionCall2 OidFunctionCall +#define OidFunctionCall3 OidFunctionCall +#define OidFunctionCall4 OidFunctionCall +#define OidFunctionCall5 OidFunctionCall +#define OidFunctionCall6 OidFunctionCall +#define OidFunctionCall7 OidFunctionCall +#define OidFunctionCall8 OidFunctionCall +#define OidFunctionCall9 OidFunctionCall + /* Special cases for convenient invocation of datatype I/O functions. */ -- 2.18.0.rc2.dirty