($INBOX_DIR/description missing)
help / color / mirror / Atom feedFrom: Andres Freund <[email protected]>
Subject: [PATCH v2 1/2] Variable length FunctionCallInfoData.
Date: Tue, 5 Jun 2018 10:24:31 -0700
Author: Andres Freund
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
src/backend/commands/event_trigger.c | 8 +-
src/backend/commands/functioncmds.c | 14 +-
src/backend/commands/tablecmds.c | 8 +-
src/backend/commands/trigger.c | 12 +-
src/backend/executor/execExpr.c | 81 +--
src/backend/executor/execExprInterp.c | 127 ++--
src/backend/executor/execSRF.c | 39 +-
src/backend/executor/functions.c | 4 +-
src/backend/executor/nodeAgg.c | 74 +--
src/backend/executor/nodeWindowAgg.c | 65 +-
src/backend/jit/llvm/llvmjit_expr.c | 20 +-
src/backend/tcop/fastpath.c | 43 +-
src/backend/utils/adt/arrayfuncs.c | 123 ++--
src/backend/utils/adt/int.c | 20 +-
src/backend/utils/adt/oid.c | 20 +-
src/backend/utils/adt/rowtypes.c | 32 +-
src/backend/utils/fmgr/fmgr.c | 848 ++++++++++----------------
src/backend/utils/sort/sortsupport.c | 13 +-
src/include/executor/execExpr.h | 6 +-
src/include/executor/nodeAgg.h | 6 +-
src/include/fmgr.h | 30 +-
src/include/nodes/execnodes.h | 2 +-
src/include/postgres.h | 7 +
src/pl/plperl/plperl.c | 20 +-
src/pl/plpgsql/src/pl_exec.c | 8 +-
src/pl/plpython/plpy_exec.c | 4 +-
src/pl/tcl/pltcl.c | 17 +-
27 files changed, 764 insertions(+), 887 deletions(-)
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 9a702e4097e..6564cd7fe11 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -1050,7 +1050,7 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
{
Oid fnoid = lfirst_oid(lc);
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 0);
PgStat_FunctionCallUsage fcusage;
elog(DEBUG1, "EventTriggerInvoke %u", fnoid);
@@ -1070,10 +1070,10 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
fmgr_info(fnoid, &flinfo);
/* Call the function, passing no arguments but setting a context. */
- InitFunctionCallInfoData(fcinfo, &flinfo, 0,
+ InitFunctionCallInfoData(*fcinfo, &flinfo, 0,
InvalidOid, (Node *) trigdata, NULL);
- pgstat_init_function_usage(&fcinfo, &fcusage);
- FunctionCallInvoke(&fcinfo);
+ pgstat_init_function_usage(fcinfo, &fcusage);
+ FunctionCallInvoke(fcinfo);
pgstat_end_function_usage(&fcusage, true);
/* Reclaim memory. */
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3fd73a69f04..1eaf8011a96 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -2215,7 +2215,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
int i;
AclResult aclresult;
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
CallContext *callcontext;
EState *estate;
ExprContext *econtext;
@@ -2277,7 +2277,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
InvokeFunctionExecuteHook(fexpr->funcid);
fmgr_info(fexpr->funcid, &flinfo);
fmgr_info_set_expr((Node *) fexpr, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, (Node *) callcontext, NULL);
+ InitFunctionCallInfoData(*fcinfo, &flinfo, nargs, fexpr->inputcollid, (Node *) callcontext, NULL);
/*
* Evaluate procedure arguments inside a suitable execution context. Note
@@ -2298,14 +2298,14 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
val = ExecEvalExprSwitchContext(exprstate, econtext, &isnull);
- fcinfo.arg[i] = val;
- fcinfo.argnull[i] = isnull;
+ fcinfo->args[i].datum = val;
+ fcinfo->args[i].isnull = isnull;
i++;
}
- pgstat_init_function_usage(&fcinfo, &fcusage);
- retval = FunctionCallInvoke(&fcinfo);
+ pgstat_init_function_usage(fcinfo, &fcusage);
+ retval = FunctionCallInvoke(fcinfo);
pgstat_end_function_usage(&fcusage, true);
if (fexpr->funcresulttype == VOIDOID)
@@ -2326,7 +2326,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
TupOutputState *tstate;
TupleTableSlot *slot;
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "procedure returned null record");
td = DatumGetHeapTupleHeader(retval);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index e10d3dbf3dd..9a1a3895522 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8600,7 +8600,7 @@ validateForeignKeyConstraint(char *conname,
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 0);
TriggerData trigdata;
/*
@@ -8608,7 +8608,7 @@ validateForeignKeyConstraint(char *conname,
*
* No parameters are passed, but we do set a context
*/
- MemSet(&fcinfo, 0, sizeof(fcinfo));
+ MemSet(&fcinfodata, 0, sizeof(fcinfodata));
/*
* We assume RI_FKey_check_ins won't look at flinfo...
@@ -8622,9 +8622,9 @@ validateForeignKeyConstraint(char *conname,
trigdata.tg_trigtuplebuf = scan->rs_cbuf;
trigdata.tg_newtuplebuf = InvalidBuffer;
- fcinfo.context = (Node *) &trigdata;
+ fcinfo->context = (Node *) &trigdata;
- RI_FKey_check_ins(&fcinfo);
+ RI_FKey_check_ins(fcinfo);
}
heap_endscan(scan);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 240e85e3910..19fcd543caf 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -2358,7 +2358,7 @@ ExecCallTriggerFunc(TriggerData *trigdata,
Instrumentation *instr,
MemoryContext per_tuple_context)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 0);
PgStat_FunctionCallUsage fcusage;
Datum result;
MemoryContext oldContext;
@@ -2403,15 +2403,15 @@ ExecCallTriggerFunc(TriggerData *trigdata,
/*
* Call the function, passing no arguments but setting a context.
*/
- InitFunctionCallInfoData(fcinfo, finfo, 0,
+ InitFunctionCallInfoData(*fcinfo, finfo, 0,
InvalidOid, (Node *) trigdata, NULL);
- pgstat_init_function_usage(&fcinfo, &fcusage);
+ pgstat_init_function_usage(fcinfo, &fcusage);
MyTriggerDepth++;
PG_TRY();
{
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
}
PG_CATCH();
{
@@ -2429,11 +2429,11 @@ ExecCallTriggerFunc(TriggerData *trigdata,
* Trigger protocol allows function to return a null pointer, but NOT to
* set the isnull result flag.
*/
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
ereport(ERROR,
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
errmsg("trigger function %u returned null value",
- fcinfo.flinfo->fn_oid)));
+ fcinfo->flinfo->fn_oid)));
/*
* If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index e284fd71d75..a39c3eabf35 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -965,7 +965,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* Set up the primary fmgr lookup information */
finfo = palloc0(sizeof(FmgrInfo));
- fcinfo = palloc0(sizeof(FunctionCallInfoData));
+ fcinfo = palloc0(SizeForFunctionCallInfoData(2));
fmgr_info(opexpr->opfuncid, finfo);
fmgr_info_set_expr((Node *) node, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
@@ -973,7 +973,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* Evaluate scalar directly into left function argument */
ExecInitExprRec(scalararg, state,
- &fcinfo->arg[0], &fcinfo->argnull[0]);
+ &fcinfo->args[0].datum, &fcinfo->args[0].isnull);
/*
* Evaluate array argument into our return value. There's no
@@ -1262,7 +1262,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* lookup the source type's output function */
scratch.d.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo));
- scratch.d.iocoerce.fcinfo_data_out = palloc0(sizeof(FunctionCallInfoData));
+ scratch.d.iocoerce.fcinfo_data_out = palloc0(SizeForFunctionCallInfoData(1));
getTypeOutputInfo(exprType((Node *) iocoerce->arg),
&iofunc, &typisvarlena);
@@ -1274,7 +1274,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* lookup the result type's input function */
scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
- scratch.d.iocoerce.fcinfo_data_in = palloc0(sizeof(FunctionCallInfoData));
+ scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfoData(3));
getTypeInputInfo(iocoerce->resulttype,
&iofunc, &typioparam);
@@ -1289,10 +1289,10 @@ ExecInitExprRec(Expr *node, ExprState *state,
* function, since they're constants.
*/
fcinfo_in = scratch.d.iocoerce.fcinfo_data_in;
- fcinfo_in->arg[1] = ObjectIdGetDatum(typioparam);
- fcinfo_in->argnull[1] = false;
- fcinfo_in->arg[2] = Int32GetDatum(-1);
- fcinfo_in->argnull[2] = false;
+ fcinfo_in->args[1].datum = ObjectIdGetDatum(typioparam);
+ fcinfo_in->args[1].isnull = false;
+ fcinfo_in->args[2].datum = Int32GetDatum(-1);
+ fcinfo_in->args[2].isnull = false;
ExprEvalPushStep(state, &scratch);
break;
@@ -1733,7 +1733,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* Set up the primary fmgr lookup information */
finfo = palloc0(sizeof(FmgrInfo));
- fcinfo = palloc0(sizeof(FunctionCallInfoData));
+ fcinfo = palloc0(SizeForFunctionCallInfoData(2));
fmgr_info(proc, finfo);
fmgr_info_set_expr((Node *) node, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
@@ -1748,9 +1748,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* evaluate left and right args directly into fcinfo */
ExecInitExprRec(left_expr, state,
- &fcinfo->arg[0], &fcinfo->argnull[0]);
+ &fcinfo->args[0].datum, &fcinfo->args[0].isnull);
ExecInitExprRec(right_expr, state,
- &fcinfo->arg[1], &fcinfo->argnull[1]);
+ &fcinfo->args[1].datum, &fcinfo->args[1].isnull);
scratch.opcode = EEOP_ROWCOMPARE_STEP;
scratch.d.rowcompare_step.finfo = finfo;
@@ -1876,7 +1876,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* Perform function lookup */
finfo = palloc0(sizeof(FmgrInfo));
- fcinfo = palloc0(sizeof(FunctionCallInfoData));
+ fcinfo = palloc0(SizeForFunctionCallInfoData(2));
fmgr_info(typentry->cmp_proc, finfo);
fmgr_info_set_expr((Node *) node, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
@@ -2185,7 +2185,7 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
/* Allocate function lookup data and parameter workspace for this call */
scratch->d.func.finfo = palloc0(sizeof(FmgrInfo));
- scratch->d.func.fcinfo_data = palloc0(sizeof(FunctionCallInfoData));
+ scratch->d.func.fcinfo_data = palloc0(SizeForFunctionCallInfoData(nargs));
flinfo = scratch->d.func.finfo;
fcinfo = scratch->d.func.fcinfo_data;
@@ -2224,13 +2224,14 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
*/
Const *con = (Const *) arg;
- fcinfo->arg[argno] = con->constvalue;
- fcinfo->argnull[argno] = con->constisnull;
+ fcinfo->args[argno].datum = con->constvalue;
+ fcinfo->args[argno].isnull = con->constisnull;
}
else
{
ExecInitExprRec(arg, state,
- &fcinfo->arg[argno], &fcinfo->argnull[argno]);
+ &fcinfo->args[argno].datum,
+ &fcinfo->args[argno].isnull);
}
argno++;
}
@@ -2863,10 +2864,11 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
int numInputs = pertrans->numInputs;
int argno;
int setno;
- FunctionCallInfo trans_fcinfo = &pertrans->transfn_fcinfo;
+ FunctionCallInfo trans_fcinfo = pertrans->transfn_fcinfo;
ListCell *arg;
ListCell *bail;
List *adjust_bailout = NIL;
+ NullableDatum *strictargs = NULL;
bool *strictnulls = NULL;
/*
@@ -2904,7 +2906,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
Assert(pertrans->numSortCols == 0);
Assert(list_length(pertrans->aggref->args) == 1);
- strictnulls = trans_fcinfo->argnull + 1;
+ strictargs = trans_fcinfo->args + 1;
source_tle = (TargetEntry *) linitial(pertrans->aggref->args);
/*
@@ -2918,21 +2920,21 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
* value
*/
ExecInitExprRec(source_tle->expr, state,
- &trans_fcinfo->arg[argno + 1],
- &trans_fcinfo->argnull[argno + 1]);
+ &trans_fcinfo->args[argno + 1].datum,
+ &trans_fcinfo->args[argno + 1].isnull);
}
else
{
- FunctionCallInfo ds_fcinfo = &pertrans->deserialfn_fcinfo;
+ FunctionCallInfo ds_fcinfo = pertrans->deserialfn_fcinfo;
/* evaluate argument */
ExecInitExprRec(source_tle->expr, state,
- &ds_fcinfo->arg[0],
- &ds_fcinfo->argnull[0]);
+ &ds_fcinfo->args[0].datum,
+ &ds_fcinfo->args[0].isnull);
/* Dummy second argument for type-safety reasons */
- ds_fcinfo->arg[1] = PointerGetDatum(NULL);
- ds_fcinfo->argnull[1] = false;
+ ds_fcinfo->args[1].datum = PointerGetDatum(NULL);
+ ds_fcinfo->args[1].isnull = false;
/*
* Don't call a strict deserialization function with NULL
@@ -2946,8 +2948,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
scratch.d.agg_deserialize.aggstate = aggstate;
scratch.d.agg_deserialize.fcinfo_data = ds_fcinfo;
scratch.d.agg_deserialize.jumpnull = -1; /* adjust later */
- scratch.resvalue = &trans_fcinfo->arg[argno + 1];
- scratch.resnull = &trans_fcinfo->argnull[argno + 1];
+ scratch.resvalue = &trans_fcinfo->args[argno + 1].datum;
+ scratch.resnull = &trans_fcinfo->args[argno + 1].isnull;
ExprEvalPushStep(state, &scratch);
adjust_bailout = lappend_int(adjust_bailout,
@@ -2964,7 +2966,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
/*
* Normal transition function without ORDER BY / DISTINCT.
*/
- strictnulls = trans_fcinfo->argnull + 1;
+ strictargs = trans_fcinfo->args + 1;
foreach(arg, pertrans->aggref->args)
{
@@ -2975,8 +2977,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
* value
*/
ExecInitExprRec(source_tle->expr, state,
- &trans_fcinfo->arg[argno + 1],
- &trans_fcinfo->argnull[argno + 1]);
+ &trans_fcinfo->args[argno + 1].datum,
+ &trans_fcinfo->args[argno + 1].isnull);
argno++;
}
}
@@ -3024,8 +3026,12 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
*/
if (trans_fcinfo->flinfo->fn_strict && numInputs > 0)
{
- scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK;
+ if (strictnulls)
+ scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_NULLS;
+ else
+ scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_ARGS;
scratch.d.agg_strict_input_check.nulls = strictnulls;
+ scratch.d.agg_strict_input_check.args = strictargs;
scratch.d.agg_strict_input_check.jumpnull = -1; /* adjust later */
scratch.d.agg_strict_input_check.nargs = numInputs;
ExprEvalPushStep(state, &scratch);
@@ -3079,7 +3085,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
Assert(as->d.jump.jumpdone == -1);
as->d.jump.jumpdone = state->steps_len;
}
- else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK)
+ else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_ARGS ||
+ as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
{
Assert(as->d.agg_strict_input_check.jumpnull == -1);
as->d.agg_strict_input_check.jumpnull = state->steps_len;
@@ -3284,7 +3291,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
/* Set up the primary fmgr lookup information */
finfo = palloc0(sizeof(FmgrInfo));
- fcinfo = palloc0(sizeof(FunctionCallInfoData));
+ fcinfo = palloc0(SizeForFunctionCallInfoData(2));
fmgr_info(foid, finfo);
fmgr_info_set_expr(NULL, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
@@ -3294,16 +3301,16 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
scratch.opcode = EEOP_INNER_VAR;
scratch.d.var.attnum = attno - 1;
scratch.d.var.vartype = latt->atttypid;
- scratch.resvalue = &fcinfo->arg[0];
- scratch.resnull = &fcinfo->argnull[0];
+ scratch.resvalue = &fcinfo->args[0].datum;
+ scratch.resnull = &fcinfo->args[0].isnull;
ExprEvalPushStep(state, &scratch);
/* right arg */
scratch.opcode = EEOP_OUTER_VAR;
scratch.d.var.attnum = attno - 1;
scratch.d.var.vartype = ratt->atttypid;
- scratch.resvalue = &fcinfo->arg[1];
- scratch.resnull = &fcinfo->argnull[1];
+ scratch.resvalue = &fcinfo->args[1].datum;
+ scratch.resnull = &fcinfo->args[1].isnull;
ExprEvalPushStep(state, &scratch);
/* evaluate distinctness */
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 1b0946b02f2..3716585901e 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -386,7 +386,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
&&CASE_EEOP_ALTERNATIVE_SUBPLAN,
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
&&CASE_EEOP_AGG_DESERIALIZE,
- &&CASE_EEOP_AGG_STRICT_INPUT_CHECK,
+ &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
+ &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
&&CASE_EEOP_AGG_INIT_TRANS,
&&CASE_EEOP_AGG_STRICT_TRANS_CHECK,
&&CASE_EEOP_AGG_PLAIN_TRANS_BYVAL,
@@ -661,14 +662,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE(EEOP_FUNCEXPR_STRICT)
{
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
- bool *argnull = fcinfo->argnull;
+ NullableDatum *args = fcinfo->args;
int argno;
Datum d;
/* strict function, so check for NULL args */
for (argno = 0; argno < op->d.func.nargs; argno++)
{
- if (argnull[argno])
+ if (args[argno].isnull)
{
*op->resnull = true;
goto strictfail;
@@ -1084,8 +1085,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
FunctionCallInfo fcinfo_out;
fcinfo_out = op->d.iocoerce.fcinfo_data_out;
- fcinfo_out->arg[0] = *op->resvalue;
- fcinfo_out->argnull[0] = false;
+ fcinfo_out->args[0].datum = *op->resvalue;
+ fcinfo_out->args[0].isnull = false;
fcinfo_out->isnull = false;
str = DatumGetCString(FunctionCallInvoke(fcinfo_out));
@@ -1101,8 +1102,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Datum d;
fcinfo_in = op->d.iocoerce.fcinfo_data_in;
- fcinfo_in->arg[0] = PointerGetDatum(str);
- fcinfo_in->argnull[0] = *op->resnull;
+ fcinfo_in->args[0].datum = PointerGetDatum(str);
+ fcinfo_in->args[0].isnull = *op->resnull;
/* second and third arguments are already set up */
fcinfo_in->isnull = false;
@@ -1139,13 +1140,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
/* check function arguments for NULLness */
- if (fcinfo->argnull[0] && fcinfo->argnull[1])
+ if (fcinfo->args[0].isnull && fcinfo->args[1].isnull)
{
/* Both NULL? Then is not distinct... */
*op->resvalue = BoolGetDatum(false);
*op->resnull = false;
}
- else if (fcinfo->argnull[0] || fcinfo->argnull[1])
+ else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull)
{
/* Only one is NULL? Then is distinct... */
*op->resvalue = BoolGetDatum(true);
@@ -1171,12 +1172,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
{
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
- if (fcinfo->argnull[0] && fcinfo->argnull[1])
+ if (fcinfo->args[0].isnull && fcinfo->args[1].isnull)
{
*op->resvalue = BoolGetDatum(true);
*op->resnull = false;
}
- else if (fcinfo->argnull[0] || fcinfo->argnull[1])
+ else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull)
{
*op->resvalue = BoolGetDatum(false);
*op->resnull = false;
@@ -1202,7 +1203,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
/* if either argument is NULL they can't be equal */
- if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
+ if (!fcinfo->args[0].isnull && !fcinfo->args[1].isnull)
{
Datum result;
@@ -1220,8 +1221,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
}
/* Arguments aren't equal, so return the first one */
- *op->resvalue = fcinfo->arg[0];
- *op->resnull = fcinfo->argnull[0];
+ *op->resvalue = fcinfo->args[0].datum;
+ *op->resnull = fcinfo->args[0].isnull;
EEO_NEXT();
}
@@ -1287,7 +1288,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* force NULL result if strict fn and NULL input */
if (op->d.rowcompare_step.finfo->fn_strict &&
- (fcinfo->argnull[0] || fcinfo->argnull[1]))
+ (fcinfo->args[0].isnull || fcinfo->args[1].isnull))
{
*op->resnull = true;
EEO_JUMP(op->d.rowcompare_step.jumpnull);
@@ -1526,10 +1527,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* evaluate a strict aggregate deserialization function */
EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE)
{
- bool *argnull = op->d.agg_deserialize.fcinfo_data->argnull;
-
/* Don't call a strict deserialization function with NULL input */
- if (argnull[0])
+ if (op->d.agg_deserialize.fcinfo_data->args[0].isnull)
EEO_JUMP(op->d.agg_deserialize.jumpnull);
/* fallthrough */
@@ -1559,15 +1558,29 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
* Check that a strict aggregate transition / combination function's
* input is not NULL.
*/
- EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK)
+ EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS)
{
int argno;
- bool *nulls = op->d.agg_strict_input_check.nulls;
+ NullableDatum *args = op->d.agg_strict_input_check.args;
int nargs = op->d.agg_strict_input_check.nargs;
for (argno = 0; argno < nargs; argno++)
{
- if (nulls[argno])
+ if (args[argno].isnull)
+ EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
+ }
+ EEO_NEXT();
+ }
+
+ EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
+ {
+ int argno;
+ bool *isnull = op->d.agg_strict_input_check.nulls;
+ int nargs = op->d.agg_strict_input_check.nargs;
+
+ for (argno = 0; argno < nargs; argno++)
+ {
+ if (isnull[argno])
EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
}
EEO_NEXT();
@@ -1643,7 +1656,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Assert(pertrans->transtypeByVal);
- fcinfo = &pertrans->transfn_fcinfo;
+ fcinfo = pertrans->transfn_fcinfo;
/* cf. select_current_set() */
aggstate->curaggcontext = op->d.agg_trans.aggcontext;
@@ -1655,8 +1668,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* invoke transition function in per-tuple context */
oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
- fcinfo->arg[0] = pergroup->transValue;
- fcinfo->argnull[0] = pergroup->transValueIsNull;
+ fcinfo->args[0].datum = pergroup->transValue;
+ fcinfo->args[0].isnull = pergroup->transValueIsNull;
fcinfo->isnull = false; /* just in case transfn doesn't set it */
newVal = FunctionCallInvoke(fcinfo);
@@ -1694,7 +1707,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Assert(!pertrans->transtypeByVal);
- fcinfo = &pertrans->transfn_fcinfo;
+ fcinfo = pertrans->transfn_fcinfo;
/* cf. select_current_set() */
aggstate->curaggcontext = op->d.agg_trans.aggcontext;
@@ -1706,8 +1719,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* invoke transition function in per-tuple context */
oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
- fcinfo->arg[0] = pergroup->transValue;
- fcinfo->argnull[0] = pergroup->transValueIsNull;
+ fcinfo->args[0].datum = pergroup->transValue;
+ fcinfo->args[0].isnull = pergroup->transValueIsNull;
fcinfo->isnull = false; /* just in case transfn doesn't set it */
newVal = FunctionCallInvoke(fcinfo);
@@ -2060,7 +2073,7 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
{
ExprEvalStep *op = &state->steps[0];
FunctionCallInfo fcinfo;
- bool *argnull;
+ NullableDatum *args;
int argno;
Datum d;
@@ -2074,12 +2087,12 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
op++;
fcinfo = op->d.func.fcinfo_data;
- argnull = fcinfo->argnull;
+ args = fcinfo->args;
/* strict function, so check for NULL args */
for (argno = 0; argno < op->d.func.nargs; argno++)
{
- if (argnull[argno])
+ if (args[argno].isnull)
{
*isnull = true;
return (Datum) 0;
@@ -2205,14 +2218,14 @@ ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
PgStat_FunctionCallUsage fcusage;
- bool *argnull = fcinfo->argnull;
+ NullableDatum *args = fcinfo->args;
int argno;
Datum d;
/* strict function, so check for NULL args */
for (argno = 0; argno < op->d.func.nargs; argno++)
{
- if (argnull[argno])
+ if (args[argno].isnull)
{
*op->resnull = true;
return;
@@ -2303,7 +2316,7 @@ void
ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
{
SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 0);
*op->resnull = false;
@@ -2335,24 +2348,24 @@ ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
case SVFOP_CURRENT_ROLE:
case SVFOP_CURRENT_USER:
case SVFOP_USER:
- InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
- *op->resvalue = current_user(&fcinfo);
- *op->resnull = fcinfo.isnull;
+ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+ *op->resvalue = current_user(fcinfo);
+ *op->resnull = fcinfo->isnull;
break;
case SVFOP_SESSION_USER:
- InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
- *op->resvalue = session_user(&fcinfo);
- *op->resnull = fcinfo.isnull;
+ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+ *op->resvalue = session_user(fcinfo);
+ *op->resnull = fcinfo->isnull;
break;
case SVFOP_CURRENT_CATALOG:
- InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
- *op->resvalue = current_database(&fcinfo);
- *op->resnull = fcinfo.isnull;
+ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+ *op->resvalue = current_database(fcinfo);
+ *op->resnull = fcinfo->isnull;
break;
case SVFOP_CURRENT_SCHEMA:
- InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
- *op->resvalue = current_schema(&fcinfo);
- *op->resnull = fcinfo.isnull;
+ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+ *op->resvalue = current_schema(fcinfo);
+ *op->resnull = fcinfo->isnull;
break;
}
}
@@ -2785,8 +2798,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
int off;
/* set at initialization */
- Assert(fcinfo->argnull[0] == false);
- Assert(fcinfo->argnull[1] == false);
+ Assert(fcinfo->args[0].isnull == false);
+ Assert(fcinfo->args[1].isnull == false);
/* default to null result */
*op->resnull = true;
@@ -2808,8 +2821,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
int cmpresult;
/* apply comparison function */
- fcinfo->arg[0] = *op->resvalue;
- fcinfo->arg[1] = values[off];
+ fcinfo->args[0].datum = *op->resvalue;
+ fcinfo->args[1].datum = values[off];
fcinfo->isnull = false;
cmpresult = DatumGetInt32(FunctionCallInvoke(fcinfo));
@@ -3361,7 +3374,7 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
* If the scalar is NULL, and the function is strict, return NULL; no
* point in iterating the loop.
*/
- if (fcinfo->argnull[0] && strictfunc)
+ if (fcinfo->args[0].isnull && strictfunc)
{
*op->resnull = true;
return;
@@ -3401,20 +3414,20 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
/* Get array element, checking for NULL */
if (bitmap && (*bitmap & bitmask) == 0)
{
- fcinfo->arg[1] = (Datum) 0;
- fcinfo->argnull[1] = true;
+ fcinfo->args[1].datum = (Datum) 0;
+ fcinfo->args[1].isnull = true;
}
else
{
elt = fetch_att(s, typbyval, typlen);
s = att_addlength_pointer(s, typlen, s);
s = (char *) att_align_nominal(s, typalign);
- fcinfo->arg[1] = elt;
- fcinfo->argnull[1] = false;
+ fcinfo->args[1].datum = elt;
+ fcinfo->args[1].isnull = false;
}
/* Call comparison function */
- if (fcinfo->argnull[1] && strictfunc)
+ if (fcinfo->args[1].isnull && strictfunc)
{
fcinfo->isnull = true;
thisresult = (Datum) 0;
@@ -4013,7 +4026,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
void
ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup)
{
- FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
+ FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
MemoryContext oldContext;
/*
@@ -4024,7 +4037,7 @@ ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup
*/
oldContext = MemoryContextSwitchTo(
aggstate->curaggcontext->ecxt_per_tuple_memory);
- pergroup->transValue = datumCopy(fcinfo->arg[1],
+ pergroup->transValue = datumCopy(fcinfo->args[1].datum,
pertrans->transtypeByVal,
pertrans->transtypeLen);
pergroup->transValueIsNull = false;
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index b97b8d797ec..a50670f537a 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -109,7 +109,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
Oid funcrettype;
bool returnsTuple;
bool returnsSet = false;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
PgStat_FunctionCallUsage fcusage;
ReturnSetInfo rsinfo;
HeapTupleData tmptup;
@@ -157,9 +157,9 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
* This path is similar to ExecMakeFunctionResultSet.
*/
returnsSet = setexpr->funcReturnsSet;
- InitFunctionCallInfoData(fcinfo, &(setexpr->func),
+ InitFunctionCallInfoData(*fcinfo, &(setexpr->func),
list_length(setexpr->args),
- setexpr->fcinfo_data.fncollation,
+ setexpr->fcinfo->fncollation,
NULL, (Node *) &rsinfo);
/*
@@ -174,7 +174,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
*/
MemoryContextReset(argContext);
oldcontext = MemoryContextSwitchTo(argContext);
- ExecEvalFuncArgs(&fcinfo, setexpr->args, econtext);
+ ExecEvalFuncArgs(fcinfo, setexpr->args, econtext);
MemoryContextSwitchTo(oldcontext);
/*
@@ -186,9 +186,9 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
{
int i;
- for (i = 0; i < fcinfo.nargs; i++)
+ for (i = 0; i < fcinfo->nargs; i++)
{
- if (fcinfo.argnull[i])
+ if (fcinfo->args[i].isnull)
goto no_function_result;
}
}
@@ -196,7 +196,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
else
{
/* Treat setexpr as a generic expression */
- InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
}
/*
@@ -224,11 +224,11 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
/* Call the function or expression one time */
if (!setexpr->elidedFuncState)
{
- pgstat_init_function_usage(&fcinfo, &fcusage);
+ pgstat_init_function_usage(fcinfo, &fcusage);
- fcinfo.isnull = false;
+ fcinfo->isnull = false;
rsinfo.isDone = ExprSingleResult;
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
pgstat_end_function_usage(&fcusage,
rsinfo.isDone != ExprMultipleResult);
@@ -236,7 +236,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
else
{
result =
- ExecEvalExpr(setexpr->elidedFuncState, econtext, &fcinfo.isnull);
+ ExecEvalExpr(setexpr->elidedFuncState, econtext, &fcinfo->isnull);
rsinfo.isDone = ExprSingleResult;
}
@@ -277,7 +277,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
*/
if (returnsTuple)
{
- if (!fcinfo.isnull)
+ if (!fcinfo->isnull)
{
HeapTupleHeader td = DatumGetHeapTupleHeader(result);
@@ -338,7 +338,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
else
{
/* Scalar-type case: just store the function result */
- tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
+ tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo->isnull);
}
/*
@@ -547,7 +547,7 @@ restart:
* rows from this SRF have been returned, otherwise ValuePerCall SRFs
* would reference freed memory after the first returned row.
*/
- fcinfo = &fcache->fcinfo_data;
+ fcinfo = fcache->fcinfo;
arguments = fcache->args;
if (!fcache->setArgsValid)
{
@@ -587,7 +587,7 @@ restart:
{
for (i = 0; i < fcinfo->nargs; i++)
{
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
{
callit = false;
break;
@@ -704,7 +704,8 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
fmgr_info_set_expr((Node *) sexpr->expr, &(sexpr->func));
/* Initialize the function call parameter struct as well */
- InitFunctionCallInfoData(sexpr->fcinfo_data, &(sexpr->func),
+ sexpr->fcinfo = (FunctionCallInfo) palloc(SizeForFunctionCallInfoData(list_length(sexpr->args)));
+ InitFunctionCallInfoData(*sexpr->fcinfo, &(sexpr->func),
list_length(sexpr->args),
input_collation, NULL, NULL);
@@ -820,9 +821,9 @@ ExecEvalFuncArgs(FunctionCallInfo fcinfo,
{
ExprState *argstate = (ExprState *) lfirst(arg);
- fcinfo->arg[i] = ExecEvalExpr(argstate,
- econtext,
- &fcinfo->argnull[i]);
+ fcinfo->args[i].datum = ExecEvalExpr(argstate,
+ econtext,
+ &fcinfo->args[i].isnull);
i++;
}
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 23545896d4d..672dcd981cd 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -933,8 +933,8 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
{
ParamExternData *prm = ¶mLI->params[i];
- prm->value = fcinfo->arg[i];
- prm->isnull = fcinfo->argnull[i];
+ prm->value = fcinfo->args[i].datum;
+ prm->isnull = fcinfo->args[i].isnull;
prm->pflags = 0;
prm->ptype = fcache->pinfo->argtypes[i];
}
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 98d8483b720..e9bea4a46a2 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -553,7 +553,7 @@ advance_transition_function(AggState *aggstate,
AggStatePerTrans pertrans,
AggStatePerGroup pergroupstate)
{
- FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
+ FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
MemoryContext oldContext;
Datum newVal;
@@ -568,7 +568,7 @@ advance_transition_function(AggState *aggstate,
for (i = 1; i <= numTransInputs; i++)
{
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
return;
}
if (pergroupstate->noTransValue)
@@ -584,7 +584,7 @@ advance_transition_function(AggState *aggstate,
*/
oldContext = MemoryContextSwitchTo(
aggstate->curaggcontext->ecxt_per_tuple_memory);
- pergroupstate->transValue = datumCopy(fcinfo->arg[1],
+ pergroupstate->transValue = datumCopy(fcinfo->args[1].datum,
pertrans->transtypeByVal,
pertrans->transtypeLen);
pergroupstate->transValueIsNull = false;
@@ -613,8 +613,8 @@ advance_transition_function(AggState *aggstate,
/*
* OK to call the transition function
*/
- fcinfo->arg[0] = pergroupstate->transValue;
- fcinfo->argnull[0] = pergroupstate->transValueIsNull;
+ fcinfo->args[0].datum = pergroupstate->transValue;
+ fcinfo->args[0].isnull = pergroupstate->transValueIsNull;
fcinfo->isnull = false; /* just in case transfn doesn't set it */
newVal = FunctionCallInvoke(fcinfo);
@@ -717,7 +717,7 @@ process_ordered_aggregate_single(AggState *aggstate,
bool isDistinct = (pertrans->numDistinctCols > 0);
Datum newAbbrevVal = (Datum) 0;
Datum oldAbbrevVal = (Datum) 0;
- FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
+ FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
Datum *newVal;
bool *isNull;
@@ -726,8 +726,8 @@ process_ordered_aggregate_single(AggState *aggstate,
tuplesort_performsort(pertrans->sortstates[aggstate->current_set]);
/* Load the column into argument 1 (arg 0 will be transition value) */
- newVal = fcinfo->arg + 1;
- isNull = fcinfo->argnull + 1;
+ newVal = &fcinfo->args[1].datum;
+ isNull = &fcinfo->args[1].isnull;
/*
* Note: if input type is pass-by-ref, the datums returned by the sort are
@@ -803,7 +803,7 @@ process_ordered_aggregate_multi(AggState *aggstate,
AggStatePerGroup pergroupstate)
{
ExprContext *tmpcontext = aggstate->tmpcontext;
- FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
+ FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
TupleTableSlot *slot1 = pertrans->sortslot;
TupleTableSlot *slot2 = pertrans->uniqslot;
int numTransInputs = pertrans->numTransInputs;
@@ -843,8 +843,8 @@ process_ordered_aggregate_multi(AggState *aggstate,
/* Start from 1, since the 0th arg will be the transition value */
for (i = 0; i < numTransInputs; i++)
{
- fcinfo->arg[i + 1] = slot1->tts_values[i];
- fcinfo->argnull[i + 1] = slot1->tts_isnull[i];
+ fcinfo->args[i + 1].datum = slot1->tts_values[i];
+ fcinfo->args[i + 1].isnull = slot1->tts_isnull[i];
}
advance_transition_function(aggstate, pertrans, pergroupstate);
@@ -897,7 +897,7 @@ finalize_aggregate(AggState *aggstate,
AggStatePerGroup pergroupstate,
Datum *resultVal, bool *resultIsNull)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
bool anynull = false;
MemoryContext oldContext;
int i;
@@ -917,10 +917,10 @@ finalize_aggregate(AggState *aggstate,
{
ExprState *expr = (ExprState *) lfirst(lc);
- fcinfo.arg[i] = ExecEvalExpr(expr,
- aggstate->ss.ps.ps_ExprContext,
- &fcinfo.argnull[i]);
- anynull |= fcinfo.argnull[i];
+ fcinfo->args[i].datum = ExecEvalExpr(expr,
+ aggstate->ss.ps.ps_ExprContext,
+ &fcinfo->args[i].isnull);
+ anynull |= fcinfo->args[i].isnull;
i++;
}
@@ -934,27 +934,27 @@ finalize_aggregate(AggState *aggstate,
/* set up aggstate->curperagg for AggGetAggref() */
aggstate->curperagg = peragg;
- InitFunctionCallInfoData(fcinfo, &peragg->finalfn,
+ InitFunctionCallInfoData(*fcinfo, &peragg->finalfn,
numFinalArgs,
pertrans->aggCollation,
(void *) aggstate, NULL);
/* Fill in the transition state value */
- fcinfo.arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
- pergroupstate->transValueIsNull,
- pertrans->transtypeLen);
- fcinfo.argnull[0] = pergroupstate->transValueIsNull;
+ fcinfo->args[0].datum = MakeExpandedObjectReadOnly(pergroupstate->transValue,
+ pergroupstate->transValueIsNull,
+ pertrans->transtypeLen);
+ fcinfo->args[0].isnull = pergroupstate->transValueIsNull;
anynull |= pergroupstate->transValueIsNull;
/* Fill any remaining argument positions with nulls */
for (; i < numFinalArgs; i++)
{
- fcinfo.arg[i] = (Datum) 0;
- fcinfo.argnull[i] = true;
+ fcinfo->args[i].datum = (Datum) 0;
+ fcinfo->args[i].isnull = true;
anynull = true;
}
- if (fcinfo.flinfo->fn_strict && anynull)
+ if (fcinfo->flinfo->fn_strict && anynull)
{
/* don't call a strict function with NULL inputs */
*resultVal = (Datum) 0;
@@ -962,8 +962,8 @@ finalize_aggregate(AggState *aggstate,
}
else
{
- *resultVal = FunctionCallInvoke(&fcinfo);
- *resultIsNull = fcinfo.isnull;
+ *resultVal = FunctionCallInvoke(fcinfo);
+ *resultIsNull = fcinfo->isnull;
}
aggstate->curperagg = NULL;
}
@@ -1018,12 +1018,12 @@ finalize_partialaggregate(AggState *aggstate,
}
else
{
- FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo;
+ FunctionCallInfo fcinfo = pertrans->serialfn_fcinfo;
- fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
- pergroupstate->transValueIsNull,
- pertrans->transtypeLen);
- fcinfo->argnull[0] = pergroupstate->transValueIsNull;
+ fcinfo->args[0].datum = MakeExpandedObjectReadOnly(pergroupstate->transValue,
+ pergroupstate->transValueIsNull,
+ pertrans->transtypeLen);
+ fcinfo->args[0].isnull = pergroupstate->transValueIsNull;
*resultVal = FunctionCallInvoke(fcinfo);
*resultIsNull = fcinfo->isnull;
@@ -2925,7 +2925,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
fmgr_info(aggtransfn, &pertrans->transfn);
fmgr_info_set_expr((Node *) combinefnexpr, &pertrans->transfn);
- InitFunctionCallInfoData(pertrans->transfn_fcinfo,
+ pertrans->transfn_fcinfo = (FunctionCallInfo) palloc(SizeForFunctionCallInfoData(2));
+ InitFunctionCallInfoData(*pertrans->transfn_fcinfo,
&pertrans->transfn,
2,
pertrans->aggCollation,
@@ -2963,7 +2964,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
fmgr_info(aggtransfn, &pertrans->transfn);
fmgr_info_set_expr((Node *) transfnexpr, &pertrans->transfn);
- InitFunctionCallInfoData(pertrans->transfn_fcinfo,
+ pertrans->transfn_fcinfo = (FunctionCallInfo) palloc(SizeForFunctionCallInfoData(pertrans->numTransInputs + 1));
+ InitFunctionCallInfoData(*pertrans->transfn_fcinfo,
&pertrans->transfn,
pertrans->numTransInputs + 1,
pertrans->aggCollation,
@@ -3001,7 +3003,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
fmgr_info(aggserialfn, &pertrans->serialfn);
fmgr_info_set_expr((Node *) serialfnexpr, &pertrans->serialfn);
- InitFunctionCallInfoData(pertrans->serialfn_fcinfo,
+ pertrans->serialfn_fcinfo = (FunctionCallInfo) palloc(SizeForFunctionCallInfoData(1));
+ InitFunctionCallInfoData(*pertrans->serialfn_fcinfo,
&pertrans->serialfn,
1,
InvalidOid,
@@ -3015,7 +3018,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
fmgr_info(aggdeserialfn, &pertrans->deserialfn);
fmgr_info_set_expr((Node *) deserialfnexpr, &pertrans->deserialfn);
- InitFunctionCallInfoData(pertrans->deserialfn_fcinfo,
+ pertrans->deserialfn_fcinfo = (FunctionCallInfo) palloc(SizeForFunctionCallInfoData(2));
+ InitFunctionCallInfoData(*pertrans->deserialfn_fcinfo,
&pertrans->deserialfn,
2,
InvalidOid,
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 729c376d86b..032598bd5bb 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -243,8 +243,7 @@ advance_windowaggregate(WindowAggState *winstate,
{
WindowFuncExprState *wfuncstate = perfuncstate->wfuncstate;
int numArguments = perfuncstate->numArguments;
- FunctionCallInfoData fcinfodata;
- FunctionCallInfo fcinfo = &fcinfodata;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum newVal;
ListCell *arg;
int i;
@@ -273,8 +272,8 @@ advance_windowaggregate(WindowAggState *winstate,
{
ExprState *argstate = (ExprState *) lfirst(arg);
- fcinfo->arg[i] = ExecEvalExpr(argstate, econtext,
- &fcinfo->argnull[i]);
+ fcinfo->args[i].datum = ExecEvalExpr(argstate, econtext,
+ &fcinfo->args[i].isnull);
i++;
}
@@ -287,7 +286,7 @@ advance_windowaggregate(WindowAggState *winstate,
*/
for (i = 1; i <= numArguments; i++)
{
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
{
MemoryContextSwitchTo(oldContext);
return;
@@ -306,7 +305,7 @@ advance_windowaggregate(WindowAggState *winstate,
if (peraggstate->transValueCount == 0 && peraggstate->transValueIsNull)
{
MemoryContextSwitchTo(peraggstate->aggcontext);
- peraggstate->transValue = datumCopy(fcinfo->arg[1],
+ peraggstate->transValue = datumCopy(fcinfo->args[1].datum,
peraggstate->transtypeByVal,
peraggstate->transtypeLen);
peraggstate->transValueIsNull = false;
@@ -339,8 +338,8 @@ advance_windowaggregate(WindowAggState *winstate,
numArguments + 1,
perfuncstate->winCollation,
(void *) winstate, NULL);
- fcinfo->arg[0] = peraggstate->transValue;
- fcinfo->argnull[0] = peraggstate->transValueIsNull;
+ fcinfo->args[0].datum = peraggstate->transValue;
+ fcinfo->args[0].isnull = peraggstate->transValueIsNull;
winstate->curaggcontext = peraggstate->aggcontext;
newVal = FunctionCallInvoke(fcinfo);
winstate->curaggcontext = NULL;
@@ -420,8 +419,7 @@ advance_windowaggregate_base(WindowAggState *winstate,
{
WindowFuncExprState *wfuncstate = perfuncstate->wfuncstate;
int numArguments = perfuncstate->numArguments;
- FunctionCallInfoData fcinfodata;
- FunctionCallInfo fcinfo = &fcinfodata;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum newVal;
ListCell *arg;
int i;
@@ -450,8 +448,8 @@ advance_windowaggregate_base(WindowAggState *winstate,
{
ExprState *argstate = (ExprState *) lfirst(arg);
- fcinfo->arg[i] = ExecEvalExpr(argstate, econtext,
- &fcinfo->argnull[i]);
+ fcinfo->args[i].datum = ExecEvalExpr(argstate, econtext,
+ &fcinfo->args[i].isnull);
i++;
}
@@ -464,7 +462,7 @@ advance_windowaggregate_base(WindowAggState *winstate,
*/
for (i = 1; i <= numArguments; i++)
{
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
{
MemoryContextSwitchTo(oldContext);
return true;
@@ -510,8 +508,8 @@ advance_windowaggregate_base(WindowAggState *winstate,
numArguments + 1,
perfuncstate->winCollation,
(void *) winstate, NULL);
- fcinfo->arg[0] = peraggstate->transValue;
- fcinfo->argnull[0] = peraggstate->transValueIsNull;
+ fcinfo->args[0].datum = peraggstate->transValue;
+ fcinfo->args[0].isnull = peraggstate->transValueIsNull;
winstate->curaggcontext = peraggstate->aggcontext;
newVal = FunctionCallInvoke(fcinfo);
winstate->curaggcontext = NULL;
@@ -592,29 +590,29 @@ finalize_windowaggregate(WindowAggState *winstate,
if (OidIsValid(peraggstate->finalfn_oid))
{
int numFinalArgs = peraggstate->numFinalArgs;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
bool anynull;
int i;
- InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn),
+ InitFunctionCallInfoData(fcinfodata.fcinfo, &(peraggstate->finalfn),
numFinalArgs,
perfuncstate->winCollation,
(void *) winstate, NULL);
- fcinfo.arg[0] = MakeExpandedObjectReadOnly(peraggstate->transValue,
- peraggstate->transValueIsNull,
- peraggstate->transtypeLen);
- fcinfo.argnull[0] = peraggstate->transValueIsNull;
+ fcinfo->args[0].datum = MakeExpandedObjectReadOnly(peraggstate->transValue,
+ peraggstate->transValueIsNull,
+ peraggstate->transtypeLen);
+ fcinfo->args[0].isnull = peraggstate->transValueIsNull;
anynull = peraggstate->transValueIsNull;
/* Fill any remaining argument positions with nulls */
for (i = 1; i < numFinalArgs; i++)
{
- fcinfo.arg[i] = (Datum) 0;
- fcinfo.argnull[i] = true;
+ fcinfo->args[i].datum = (Datum) 0;
+ fcinfo->args[i].isnull = true;
anynull = true;
}
- if (fcinfo.flinfo->fn_strict && anynull)
+ if (fcinfo->flinfo->fn_strict && anynull)
{
/* don't call a strict function with NULL inputs */
*result = (Datum) 0;
@@ -623,9 +621,9 @@ finalize_windowaggregate(WindowAggState *winstate,
else
{
winstate->curaggcontext = peraggstate->aggcontext;
- *result = FunctionCallInvoke(&fcinfo);
+ *result = FunctionCallInvoke(fcinfo);
winstate->curaggcontext = NULL;
- *isnull = fcinfo.isnull;
+ *isnull = fcinfo->isnull;
}
}
else
@@ -1032,8 +1030,9 @@ static void
eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate,
Datum *result, bool *isnull)
{
- FunctionCallInfoData fcinfo;
+ FunctionCallInfo fcinfo;
MemoryContext oldContext;
+ int argno;
oldContext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory);
@@ -1043,24 +1042,26 @@ eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate,
* implementations to support varying numbers of arguments. The real info
* goes through the WindowObject, which is passed via fcinfo->context.
*/
- InitFunctionCallInfoData(fcinfo, &(perfuncstate->flinfo),
+ fcinfo = palloc(SizeForFunctionCallInfoData(perfuncstate->numArguments));
+ InitFunctionCallInfoData(*fcinfo, &(perfuncstate->flinfo),
perfuncstate->numArguments,
perfuncstate->winCollation,
(void *) perfuncstate->winobj, NULL);
/* Just in case, make all the regular argument slots be null */
- memset(fcinfo.argnull, true, perfuncstate->numArguments);
+ for (argno = 0; argno < perfuncstate->numArguments; argno++)
+ fcinfo->args[argno].isnull = true;
/* Window functions don't have a current aggregate context, either */
winstate->curaggcontext = NULL;
- *result = FunctionCallInvoke(&fcinfo);
- *isnull = fcinfo.isnull;
+ *result = FunctionCallInvoke(fcinfo);
+ *isnull = fcinfo->isnull;
/*
* Make sure pass-by-ref data is allocated in the appropriate context. (We
* need this in case the function returns a pointer into some short-lived
* tuple, as is entirely possible.)
*/
- if (!perfuncstate->resulttypeByVal && !fcinfo.isnull &&
+ if (!perfuncstate->resulttypeByVal && !fcinfo->isnull &&
!MemoryContextContains(CurrentMemoryContext,
DatumGetPointer(*result)))
*result = datumCopy(*result,
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 99e0cee157f..13aedc93016 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -2117,15 +2117,16 @@ llvm_compile_expr(ExprState *state)
case EEOP_AGG_STRICT_INPUT_CHECK:
{
int nargs = op->d.agg_strict_input_check.nargs;
- bool *nulls = op->d.agg_strict_input_check.nulls;
+ NullableDatum *args = op->d.agg_strict_input_check.args;
int jumpnull;
int argno;
- LLVMValueRef v_nullp;
+ LLVMValueRef v_argp;
LLVMBasicBlockRef *b_checknulls;
jumpnull = op->d.agg_strict_input_check.jumpnull;
- v_nullp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
+ /* FIXME: This isn't correct, it's a NullableDatum now */
+ v_argp = l_ptr_const(args, l_ptr(TypeStorageBool));
/* create blocks for checking args */
b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs);
@@ -2153,7 +2154,8 @@ llvm_compile_expr(ExprState *state)
else
b_argnotnull = b_checknulls[argno + 1];
- v_argisnull = l_load_gep1(b, v_nullp, v_argno, "");
+ /* FIXME: This isn't correct */
+ v_argisnull = l_load_gep1(b, v_argp, v_argno, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b,
@@ -2352,7 +2354,7 @@ llvm_compile_expr(ExprState *state)
aggstate = op->d.agg_trans.aggstate;
pertrans = op->d.agg_trans.pertrans;
- fcinfo = &pertrans->transfn_fcinfo;
+ fcinfo = pertrans->transfn_fcinfo;
v_aggstatep = l_ptr_const(aggstate,
l_ptr(StructAggState));
@@ -2622,12 +2624,8 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
LLVMValueRef params[2];
- params[0] = l_int64_const(sizeof(fcinfo->arg));
- params[1] = l_ptr_const(fcinfo->arg, l_ptr(LLVMInt8Type()));
- LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
-
- params[0] = l_int64_const(sizeof(fcinfo->argnull));
- params[1] = l_ptr_const(fcinfo->argnull, l_ptr(LLVMInt8Type()));
+ params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs);
+ params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type()));
LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
params[0] = l_int64_const(sizeof(fcinfo->isnull));
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index d16ba5ec927..4d2b687fb1f 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -260,7 +260,7 @@ HandleFunctionRequest(StringInfo msgBuf)
{
Oid fid;
AclResult aclresult;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
int16 rformat;
Datum retval;
struct fp_info my_fp;
@@ -332,12 +332,12 @@ HandleFunctionRequest(StringInfo msgBuf)
* functions can't be called this way. Perhaps we should pass
* DEFAULT_COLLATION_OID, instead?
*/
- InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
- rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);
+ rformat = parse_fcall_arguments(msgBuf, fip, fcinfo);
else
- rformat = parse_fcall_arguments_20(msgBuf, fip, &fcinfo);
+ rformat = parse_fcall_arguments_20(msgBuf, fip, fcinfo);
/* Verify we reached the end of the message where expected. */
pq_getmsgend(msgBuf);
@@ -350,9 +350,9 @@ HandleFunctionRequest(StringInfo msgBuf)
{
int i;
- for (i = 0; i < fcinfo.nargs; i++)
+ for (i = 0; i < fcinfo->nargs; i++)
{
- if (fcinfo.argnull[i])
+ if (fcinfo->args[i].isnull)
{
callit = false;
break;
@@ -363,18 +363,18 @@ HandleFunctionRequest(StringInfo msgBuf)
if (callit)
{
/* Okay, do it ... */
- retval = FunctionCallInvoke(&fcinfo);
+ retval = FunctionCallInvoke(fcinfo);
}
else
{
- fcinfo.isnull = true;
+ fcinfo->isnull = true;
retval = (Datum) 0;
}
/* ensure we do at least one CHECK_FOR_INTERRUPTS per function call */
CHECK_FOR_INTERRUPTS();
- SendFunctionResult(retval, fcinfo.isnull, fip->rettype, rformat);
+ SendFunctionResult(retval, fcinfo->isnull, fip->rettype, rformat);
/* We no longer need the snapshot */
PopActiveSnapshot();
@@ -450,11 +450,11 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
argsize = pq_getmsgint(msgBuf, 4);
if (argsize == -1)
{
- fcinfo->argnull[i] = true;
+ fcinfo->args[i].isnull = true;
}
else
{
- fcinfo->argnull[i] = false;
+ fcinfo->args[i].isnull = false;
if (argsize < 0)
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
@@ -494,8 +494,8 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
else
pstring = pg_client_to_server(abuf.data, argsize);
- fcinfo->arg[i] = OidInputFunctionCall(typinput, pstring,
- typioparam, -1);
+ fcinfo->args[i].datum = OidInputFunctionCall(typinput, pstring,
+ typioparam, -1);
/* Free result of encoding conversion, if any */
if (pstring && pstring != abuf.data)
pfree(pstring);
@@ -514,8 +514,8 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
else
bufptr = &abuf;
- fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, bufptr,
- typioparam, -1);
+ fcinfo->args[i].datum = OidReceiveFunctionCall(typreceive, bufptr,
+ typioparam, -1);
/* Trouble if it didn't eat the whole buffer */
if (argsize != -1 && abuf.cursor != abuf.len)
@@ -579,12 +579,13 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip,
argsize = pq_getmsgint(msgBuf, 4);
if (argsize == -1)
{
- fcinfo->argnull[i] = true;
- fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, NULL,
- typioparam, -1);
+ /* FIXME: huh? */
+ fcinfo->args[i].isnull = true;
+ fcinfo->args[i].datum = OidReceiveFunctionCall(typreceive, NULL,
+ typioparam, -1);
continue;
}
- fcinfo->argnull[i] = false;
+ fcinfo->args[i].isnull = false;
if (argsize < 0)
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
@@ -597,8 +598,8 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip,
pq_getmsgbytes(msgBuf, argsize),
argsize);
- fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, &abuf,
- typioparam, -1);
+ fcinfo->args[i].datum = OidReceiveFunctionCall(typreceive, &abuf,
+ typioparam, -1);
/* Trouble if it didn't eat the whole buffer */
if (abuf.cursor != abuf.len)
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index ce1ded888f1..577e8637768 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3590,7 +3590,7 @@ array_eq(PG_FUNCTION_ARGS)
array_iter it1;
array_iter it2;
int i;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 3);
if (element_type != AARR_ELEMTYPE(array2))
ereport(ERROR,
@@ -3630,7 +3630,7 @@ array_eq(PG_FUNCTION_ARGS)
/*
* apply the operator to each pair of array elements.
*/
- InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2,
collation, NULL, NULL);
/* Loop over source data */
@@ -3666,12 +3666,12 @@ array_eq(PG_FUNCTION_ARGS)
/*
* Apply the operator to the element pair
*/
- locfcinfo.arg[0] = elt1;
- locfcinfo.arg[1] = elt2;
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt1;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = elt2;
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
if (!oprresult)
{
result = false;
@@ -3761,7 +3761,7 @@ array_cmp(FunctionCallInfo fcinfo)
array_iter it1;
array_iter it2;
int i;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
if (element_type != AARR_ELEMTYPE(array2))
ereport(ERROR,
@@ -3794,7 +3794,7 @@ array_cmp(FunctionCallInfo fcinfo)
/*
* apply the operator to each pair of array elements.
*/
- InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2,
collation, NULL, NULL);
/* Loop over source data */
@@ -3833,12 +3833,12 @@ array_cmp(FunctionCallInfo fcinfo)
}
/* Compare the pair of elements */
- locfcinfo.arg[0] = elt1;
- locfcinfo.arg[1] = elt2;
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt1;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = elt2;
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
if (cmpresult == 0)
continue; /* equal */
@@ -3925,7 +3925,7 @@ hash_array(PG_FUNCTION_ARGS)
char typalign;
int i;
array_iter iter;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 1);
/*
* We arrange to look up the hash function only once per series of calls,
@@ -3953,7 +3953,7 @@ hash_array(PG_FUNCTION_ARGS)
/*
* apply the hash function to each array element.
*/
- InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->hash_proc_finfo, 1,
InvalidOid, NULL, NULL);
/* Loop over source data */
@@ -3977,10 +3977,10 @@ hash_array(PG_FUNCTION_ARGS)
else
{
/* Apply the hash function */
- locfcinfo.arg[0] = elt;
- locfcinfo.argnull[0] = false;
- locfcinfo.isnull = false;
- elthash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->isnull = false;
+ elthash = DatumGetUInt32(FunctionCallInvoke(locfcinfo));
}
/*
@@ -4023,7 +4023,7 @@ hash_array_extended(PG_FUNCTION_ARGS)
char typalign;
int i;
array_iter iter;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
if (typentry == NULL ||
@@ -4042,7 +4042,7 @@ hash_array_extended(PG_FUNCTION_ARGS)
typbyval = typentry->typbyval;
typalign = typentry->typalign;
- InitFunctionCallInfoData(locfcinfo, &typentry->hash_extended_proc_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->hash_extended_proc_finfo, 2,
InvalidOid, NULL, NULL);
/* Loop over source data */
@@ -4065,12 +4065,11 @@ hash_array_extended(PG_FUNCTION_ARGS)
else
{
/* Apply the hash function */
- locfcinfo.arg[0] = elt;
- locfcinfo.arg[1] = Int64GetDatum(seed);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- elthash = DatumGetUInt64(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = Int64GetDatum(seed);
+ locfcinfo->args[1].isnull = false;
+ elthash = DatumGetUInt64(FunctionCallInvoke(locfcinfo));
}
result = (result << 5) - result + elthash;
@@ -4113,7 +4112,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
int i;
int j;
array_iter it1;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
if (element_type != AARR_ELEMTYPE(array2))
ereport(ERROR,
@@ -4164,7 +4163,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
/*
* Apply the comparison operator to each pair of array elements.
*/
- InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2,
collation, NULL, NULL);
/* Loop over source data */
@@ -4206,12 +4205,12 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
/*
* Apply the operator to the element pair
*/
- locfcinfo.arg[0] = elt1;
- locfcinfo.arg[1] = elt2;
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt1;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = elt2;
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
if (oprresult)
break;
}
@@ -6062,7 +6061,7 @@ array_replace_internal(ArrayType *array,
int bitmask;
bool changed = false;
TypeCacheEntry *typentry;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
element_type = ARR_ELEMTYPE(array);
ndim = ARR_NDIM(array);
@@ -6117,7 +6116,7 @@ array_replace_internal(ArrayType *array,
}
/* Prepare to apply the comparison operator */
- InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2,
collation, NULL, NULL);
/* Allocate temporary arrays for new values */
@@ -6175,12 +6174,12 @@ array_replace_internal(ArrayType *array,
/*
* Apply the operator to the element pair
*/
- locfcinfo.arg[0] = elt;
- locfcinfo.arg[1] = search;
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = elt;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = search;
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
if (!oprresult)
{
/* no match, keep element */
@@ -6460,7 +6459,8 @@ width_bucket_array_fixed(Datum operand,
char *thresholds_data;
int typlen = typentry->typlen;
bool typbyval = typentry->typbyval;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
+
int left;
int right;
@@ -6470,7 +6470,7 @@ width_bucket_array_fixed(Datum operand,
*/
thresholds_data = (char *) ARR_DATA_PTR(thresholds);
- InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2,
collation, NULL, NULL);
/* Find the bucket */
@@ -6484,13 +6484,13 @@ width_bucket_array_fixed(Datum operand,
ptr = thresholds_data + mid * typlen;
- locfcinfo.arg[0] = operand;
- locfcinfo.arg[1] = fetch_att(ptr, typbyval, typlen);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
+ locfcinfo->args[0].datum = operand;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = fetch_att(ptr, typbyval, typlen);
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
- cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
+ cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
if (cmpresult < 0)
right = mid;
@@ -6514,13 +6514,13 @@ width_bucket_array_variable(Datum operand,
int typlen = typentry->typlen;
bool typbyval = typentry->typbyval;
char typalign = typentry->typalign;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 2);
int left;
int right;
thresholds_data = (char *) ARR_DATA_PTR(thresholds);
- InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2,
collation, NULL, NULL);
/* Find the bucket */
@@ -6541,13 +6541,12 @@ width_bucket_array_variable(Datum operand,
ptr = (char *) att_align_nominal(ptr, typalign);
}
- locfcinfo.arg[0] = operand;
- locfcinfo.arg[1] = fetch_att(ptr, typbyval, typlen);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
+ locfcinfo->args[0].datum = operand;
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = fetch_att(ptr, typbyval, typlen);
+ locfcinfo->args[1].isnull = false;
- cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
+ cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
if (cmpresult < 0)
right = mid;
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 8149dc1369b..cb92b0f98bb 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -202,7 +202,7 @@ Datum
int2vectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 3);
int2vector *result;
/*
@@ -211,19 +211,19 @@ int2vectorrecv(PG_FUNCTION_ARGS)
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
* parameter.
*/
- InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
+ InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
InvalidOid, NULL, NULL);
- locfcinfo.arg[0] = PointerGetDatum(buf);
- locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
- locfcinfo.arg[2] = Int32GetDatum(-1);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.argnull[2] = false;
+ locfcinfo->args[0].datum = PointerGetDatum(buf);
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = ObjectIdGetDatum(INT2OID);
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->args[2].datum = Int32GetDatum(-1);
+ locfcinfo->args[2].isnull = false;
- result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));
+ result = (int2vector *) DatumGetPointer(array_recv(locfcinfo));
- Assert(!locfcinfo.isnull);
+ Assert(!locfcinfo->isnull);
/* sanity checks: int2vector must be 1-D, 0-based, no nulls */
if (ARR_NDIM(result) != 1 ||
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index b0670e0d9f7..cf50f843115 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -257,7 +257,7 @@ Datum
oidvectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 3);
oidvector *result;
/*
@@ -266,19 +266,19 @@ oidvectorrecv(PG_FUNCTION_ARGS)
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
* parameter.
*/
- InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
+ InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
InvalidOid, NULL, NULL);
- locfcinfo.arg[0] = PointerGetDatum(buf);
- locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID);
- locfcinfo.arg[2] = Int32GetDatum(-1);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.argnull[2] = false;
+ locfcinfo->args[0].datum = PointerGetDatum(buf);
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = ObjectIdGetDatum(OIDOID);
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->args[2].datum = Int32GetDatum(-1);
+ locfcinfo->args[2].isnull = false;
- result = (oidvector *) DatumGetPointer(array_recv(&locfcinfo));
+ result = (oidvector *) DatumGetPointer(array_recv(locfcinfo));
- Assert(!locfcinfo.isnull);
+ Assert(!locfcinfo->isnull);
/* sanity checks: oidvector must be 1-D, 0-based, no nulls */
if (ARR_NDIM(result) != 1 ||
diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c
index 5f729342f8d..de2bd560eea 100644
--- a/src/backend/utils/adt/rowtypes.c
+++ b/src/backend/utils/adt/rowtypes.c
@@ -942,7 +942,7 @@ record_cmp(FunctionCallInfo fcinfo)
*/
if (!nulls1[i1] || !nulls2[i2])
{
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 3);
int32 cmpresult;
if (nulls1[i1])
@@ -959,14 +959,14 @@ record_cmp(FunctionCallInfo fcinfo)
}
/* Compare the pair of elements */
- InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2,
collation, NULL, NULL);
- locfcinfo.arg[0] = values1[i1];
- locfcinfo.arg[1] = values2[i2];
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = values1[i1];
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = values2[i2];
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
if (cmpresult < 0)
{
@@ -1123,7 +1123,7 @@ record_eq(PG_FUNCTION_ARGS)
Form_pg_attribute att2;
TypeCacheEntry *typentry;
Oid collation;
- FunctionCallInfoData locfcinfo;
+ STACK_FCINFO_FOR_ARGS(locfcinfo, 3);
bool oprresult;
/*
@@ -1193,14 +1193,14 @@ record_eq(PG_FUNCTION_ARGS)
}
/* Compare the pair of elements */
- InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
+ InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2,
collation, NULL, NULL);
- locfcinfo.arg[0] = values1[i1];
- locfcinfo.arg[1] = values2[i2];
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.isnull = false;
- oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
+ locfcinfo->args[0].datum = values1[i1];
+ locfcinfo->args[0].isnull = false;
+ locfcinfo->args[1].datum = values2[i2];
+ locfcinfo->args[1].isnull = false;
+ locfcinfo->isnull = false;
+ oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
if (!oprresult)
{
result = false;
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 6cbbd5b78b0..86d5cef8108 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -782,7 +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
@@ -792,18 +791,18 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
Datum
DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 1);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.argnull[0] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
- result = (*func) (&fcinfo);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -812,20 +811,20 @@ DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
Datum
DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 2);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.arg[1] = arg2;
- fcinfo.argnull[0] = false;
- fcinfo.argnull[1] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
+ fcinfo->args[1].datum = arg2;
+ fcinfo->args[1].isnull = false;
- result = (*func) (&fcinfo);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -835,22 +834,22 @@ Datum
DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -860,24 +859,24 @@ Datum
DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 4);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -887,26 +886,26 @@ Datum
DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 5);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -917,28 +916,28 @@ DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 6);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -949,30 +948,30 @@ DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6, Datum arg7)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 7);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -983,32 +982,32 @@ DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6, Datum arg7, Datum arg8)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 8);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -1020,34 +1019,34 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum arg6, Datum arg7, Datum arg8,
Datum arg9)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 9);
Datum result;
- InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, 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;
+ 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);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -1065,18 +1064,18 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
Datum
CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 1);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.argnull[0] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
- result = (*func) (&fcinfo);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "function %p returned NULL", (void *) func);
return result;
@@ -1085,25 +1084,47 @@ CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum
Datum
CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 2);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.arg[1] = arg2;
- fcinfo.argnull[0] = false;
- fcinfo.argnull[1] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
+ fcinfo->args[1].datum = arg2;
+ fcinfo->args[1].isnull = false;
- result = (*func) (&fcinfo);
+ result = (*func) (fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
+ 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
@@ -1112,19 +1133,19 @@ CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum
Datum
FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 1);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.argnull[0] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1132,21 +1153,21 @@ FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Datum
FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 2);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
- fcinfo.arg[0] = arg1;
- fcinfo.arg[1] = arg2;
- fcinfo.argnull[0] = false;
- fcinfo.argnull[1] = false;
+ fcinfo->args[0].datum = arg1;
+ fcinfo->args[0].isnull = false;
+ fcinfo->args[1].datum = arg2;
+ fcinfo->args[1].isnull = false;
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1155,23 +1176,23 @@ Datum
FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1180,25 +1201,25 @@ Datum
FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 4);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1207,27 +1228,27 @@ Datum
FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 5);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1237,29 +1258,29 @@ FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 6);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1269,31 +1290,31 @@ FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6, Datum arg7)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 7);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1303,33 +1324,33 @@ FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5,
Datum arg6, Datum arg7, Datum arg8)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 8);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1340,35 +1361,35 @@ FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
Datum arg6, Datum arg7, Datum arg8,
Datum arg9)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 9);
Datum result;
- InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, 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;
+ 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);
+ result = FunctionCallInvoke(fcinfo);
/* Check for null result, since caller is clearly not expecting one */
- if (fcinfo.isnull)
- elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+ if (fcinfo->isnull)
+ elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
return result;
}
@@ -1385,68 +1406,30 @@ Datum
OidFunctionCall0Coll(Oid functionId, Oid collation)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- 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;
+ return FunctionCall0Coll(&flinfo, collation);
}
Datum
OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL);
-
- fcinfo.arg[0] = arg1;
- fcinfo.argnull[0] = 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;
+ return FunctionCall1Coll(&flinfo, collation, arg1);
}
Datum
OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL);
-
- fcinfo.arg[0] = arg1;
- fcinfo.arg[1] = arg2;
- fcinfo.argnull[0] = false;
- fcinfo.argnull[1] = 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;
+ return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
}
Datum
@@ -1454,27 +1437,10 @@ OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg3)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, 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;
+ return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
}
Datum
@@ -1482,29 +1448,10 @@ OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, 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;
+ return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
}
Datum
@@ -1512,31 +1459,10 @@ OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg3, Datum arg4, Datum arg5)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, 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;
+ return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
}
Datum
@@ -1545,33 +1471,11 @@ OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg6)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, 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;
+ return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+ arg6);
}
Datum
@@ -1580,35 +1484,11 @@ OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg6, Datum arg7)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, 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;
+ return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7);
}
Datum
@@ -1617,37 +1497,11 @@ OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg6, Datum arg7, Datum arg8)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, 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;
+ return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8);
}
Datum
@@ -1657,39 +1511,11 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg9)
{
FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum result;
fmgr_info(functionId, &flinfo);
- InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, 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;
+ return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8, arg9);
}
@@ -1708,35 +1534,35 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum
InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum result;
if (str == NULL && flinfo->fn_strict)
return (Datum) 0; /* just return null result */
- InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
- fcinfo.arg[0] = CStringGetDatum(str);
- fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
- fcinfo.arg[2] = Int32GetDatum(typmod);
- fcinfo.argnull[0] = (str == NULL);
- fcinfo.argnull[1] = false;
- fcinfo.argnull[2] = false;
+ fcinfo->args[0].datum = CStringGetDatum(str);
+ fcinfo->args[0].isnull = false;
+ fcinfo->args[1].datum = ObjectIdGetDatum(typioparam);
+ fcinfo->args[1].isnull = false;
+ fcinfo->args[2].datum = Int32GetDatum(typmod);
+ fcinfo->args[2].isnull = false;
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
/* Should get null result if and only if str is NULL */
if (str == NULL)
{
- if (!fcinfo.isnull)
+ if (!fcinfo->isnull)
elog(ERROR, "input function %u returned non-NULL",
- fcinfo.flinfo->fn_oid);
+ flinfo->fn_oid);
}
else
{
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "input function %u returned NULL",
- fcinfo.flinfo->fn_oid);
+ flinfo->fn_oid);
}
return result;
@@ -1767,35 +1593,35 @@ Datum
ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
Oid typioparam, int32 typmod)
{
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
Datum result;
if (buf == NULL && flinfo->fn_strict)
return (Datum) 0; /* just return null result */
- InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
+ InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
- fcinfo.arg[0] = PointerGetDatum(buf);
- fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
- fcinfo.arg[2] = Int32GetDatum(typmod);
- fcinfo.argnull[0] = (buf == NULL);
- fcinfo.argnull[1] = false;
- fcinfo.argnull[2] = false;
+ fcinfo->args[0].datum = PointerGetDatum(buf);
+ fcinfo->args[0].isnull = false;
+ fcinfo->args[1].datum = ObjectIdGetDatum(typioparam);
+ fcinfo->args[1].isnull = false;
+ fcinfo->args[2].datum = Int32GetDatum(typmod);
+ fcinfo->args[2].isnull = false;
- result = FunctionCallInvoke(&fcinfo);
+ result = FunctionCallInvoke(fcinfo);
/* Should get null result if and only if buf is NULL */
if (buf == NULL)
{
- if (!fcinfo.isnull)
+ if (!fcinfo->isnull)
elog(ERROR, "receive function %u returned non-NULL",
- fcinfo.flinfo->fn_oid);
+ flinfo->fn_oid);
}
else
{
- if (fcinfo.isnull)
+ if (fcinfo->isnull)
elog(ERROR, "receive function %u returned NULL",
- fcinfo.flinfo->fn_oid);
+ flinfo->fn_oid);
}
return result;
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index 8c09fe4a430..31aa4100d67 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -26,10 +26,11 @@
/* Info needed to use an old-style comparison function as a sort comparator */
typedef struct
{
- FunctionCallInfoData fcinfo; /* reusable callinfo structure */
FmgrInfo flinfo; /* lookup data for comparison function */
+ FunctionCallInfoData fcinfo; /* reusable callinfo structure */
} SortShimExtra;
+#define SizeForSortShimExtra(nargs) (offsetof(SortShimExtra, fcinfo) + SizeForFunctionCallInfoData(nargs))
/*
* Shim function for calling an old-style comparator
@@ -44,8 +45,8 @@ comparison_shim(Datum x, Datum y, SortSupport ssup)
SortShimExtra *extra = (SortShimExtra *) ssup->ssup_extra;
Datum result;
- extra->fcinfo.arg[0] = x;
- extra->fcinfo.arg[1] = y;
+ extra->fcinfo.args[0].datum = x;
+ extra->fcinfo.args[1].datum = y;
/* just for paranoia's sake, we reset isnull each time */
extra->fcinfo.isnull = false;
@@ -69,7 +70,7 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
SortShimExtra *extra;
extra = (SortShimExtra *) MemoryContextAlloc(ssup->ssup_cxt,
- sizeof(SortShimExtra));
+ SizeForSortShimExtra(2));
/* Lookup the comparison function */
fmgr_info_cxt(cmpFunc, &extra->flinfo, ssup->ssup_cxt);
@@ -77,8 +78,8 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
/* We can initialize the callinfo just once and re-use it */
InitFunctionCallInfoData(extra->fcinfo, &extra->flinfo, 2,
ssup->ssup_collation, NULL, NULL);
- extra->fcinfo.argnull[0] = false;
- extra->fcinfo.argnull[1] = false;
+ extra->fcinfo.args[0].isnull = false;
+ extra->fcinfo.args[1].isnull = false;
ssup->ssup_extra = extra;
ssup->comparator = comparison_shim;
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 02af68f2c25..8233a465189 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -223,7 +223,8 @@ typedef enum ExprEvalOp
/* aggregation related nodes */
EEOP_AGG_STRICT_DESERIALIZE,
EEOP_AGG_DESERIALIZE,
- EEOP_AGG_STRICT_INPUT_CHECK,
+ EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
+ EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
EEOP_AGG_INIT_TRANS,
EEOP_AGG_STRICT_TRANS_CHECK,
EEOP_AGG_PLAIN_TRANS_BYVAL,
@@ -599,7 +600,8 @@ typedef struct ExprEvalStep
/* for EEOP_AGG_STRICT_INPUT_CHECK */
struct
{
- bool *nulls;
+ NullableDatum *args;
+ bool *nulls;
int nargs;
int jumpnull;
} agg_strict_input_check;
diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h
index 8fb8c8fe802..51aec33fd8d 100644
--- a/src/include/executor/nodeAgg.h
+++ b/src/include/executor/nodeAgg.h
@@ -158,12 +158,12 @@ typedef struct AggStatePerTransData
* re-initializing the unchanging fields; which isn't much, but it seems
* worth the extra space consumption.
*/
- FunctionCallInfoData transfn_fcinfo;
+ FunctionCallInfo transfn_fcinfo;
/* Likewise for serialization and deserialization functions */
- FunctionCallInfoData serialfn_fcinfo;
+ FunctionCallInfo serialfn_fcinfo;
- FunctionCallInfoData deserialfn_fcinfo;
+ FunctionCallInfo deserialfn_fcinfo;
} AggStatePerTransData;
/*
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 101f513ba67..ee1dbd5fcbb 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -83,12 +83,28 @@ typedef struct FunctionCallInfoData
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
bool isnull; /* function must set true if result is NULL */
short nargs; /* # arguments actually passed */
-#define FIELDNO_FUNCTIONCALLINFODATA_ARG 6
- Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
-#define FIELDNO_FUNCTIONCALLINFODATA_ARGNULL 7
- bool argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */
+#define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6
+
+ NullableDatum args[FLEXIBLE_ARRAY_MEMBER];
+
} FunctionCallInfoData;
+#define SizeForFunctionCallInfoData(nargs) (offsetof(FunctionCallInfoData, args) + sizeof(NullableDatum) * (nargs))
+
+/*
+ * This macro ensures that `name` points to a stack-allocated
+ * FunctionCallInfoData struct with sufficient space for `nargs` arguments.
+ */
+#define STACK_FCINFO_FOR_ARGS(name, nargs) \
+ union \
+ { \
+ FunctionCallInfoData fcinfo; \
+ /* ensure enough space for nargs args is available */ \
+ char *fcinfo_data[SizeForFunctionCallInfoData(nargs)]; \
+ } name##data; \
+ FunctionCallInfo name = &name##data.fcinfo
+
+
/*
* This routine fills a FmgrInfo struct, given the OID
* of the function to be called.
@@ -141,7 +157,6 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn);
*/
#define FunctionCallInvoke(fcinfo) ((* (fcinfo)->flinfo->fn_addr) (fcinfo))
-
/*-------------------------------------------------------------------------
* Support macros to ease writing fmgr-compatible functions
*
@@ -176,7 +191,7 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn);
* If function is not marked "proisstrict" in pg_proc, it must check for
* null arguments using this macro. Do not try to GETARG a null argument!
*/
-#define PG_ARGISNULL(n) (fcinfo->argnull[n])
+#define PG_ARGISNULL(n) (fcinfo->args[n].isnull)
/*
* Support for fetching detoasted copies of toastable datatypes (all of
@@ -235,7 +250,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena *datum);
/* Macros for fetching arguments of standard types */
-#define PG_GETARG_DATUM(n) (fcinfo->arg[n])
+#define PG_GETARG_DATUM(n) (fcinfo->args[n].datum)
#define PG_GETARG_INT32(n) DatumGetInt32(PG_GETARG_DATUM(n))
#define PG_GETARG_UINT32(n) DatumGetUInt32(PG_GETARG_DATUM(n))
#define PG_GETARG_INT16(n) DatumGetInt16(PG_GETARG_DATUM(n))
@@ -514,6 +529,7 @@ extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo,
* 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,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 834708944bf..e04573f11ae 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -828,7 +828,7 @@ typedef struct SetExprState
* (by InitFunctionCallInfoData) if func.fn_oid is valid. It also saves
* argument values between calls, when setArgsValid is true.
*/
- FunctionCallInfoData fcinfo_data;
+ FunctionCallInfo fcinfo;
} SetExprState;
/* ----------------
diff --git a/src/include/postgres.h b/src/include/postgres.h
index b596fcb513e..b3ff25dc6e2 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -366,6 +366,13 @@ typedef struct
typedef uintptr_t Datum;
+typedef struct NullableDatum
+{
+ Datum datum;
+ bool isnull;
+ /* FIXME: space for flags? */
+} NullableDatum;
+
#define SIZEOF_DATUM SIZEOF_VOID_P
/*
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 4cfc5062531..3d4350a16c9 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -1877,7 +1877,7 @@ Datum
plperl_inline_handler(PG_FUNCTION_ARGS)
{
InlineCodeBlock *codeblock = (InlineCodeBlock *) PG_GETARG_POINTER(0);
- FunctionCallInfoData fake_fcinfo;
+ STACK_FCINFO_FOR_ARGS(fake_fcinfo, 0);
FmgrInfo flinfo;
plperl_proc_desc desc;
plperl_call_data *volatile save_call_data = current_call_data;
@@ -1899,10 +1899,10 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
* plperl_call_perl_func(). In particular note that this sets things up
* with no arguments passed, and a result type of VOID.
*/
- MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));
+ MemSet(&fake_fcinfodata, 0, sizeof(fake_fcinfodata));
MemSet(&flinfo, 0, sizeof(flinfo));
MemSet(&desc, 0, sizeof(desc));
- fake_fcinfo.flinfo = &flinfo;
+ fake_fcinfo->flinfo = &flinfo;
flinfo.fn_oid = InvalidOid;
flinfo.fn_mcxt = CurrentMemoryContext;
@@ -1920,7 +1920,7 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
desc.nargs = 0;
desc.reference = NULL;
- this_call_data.fcinfo = &fake_fcinfo;
+ this_call_data.fcinfo = fake_fcinfo;
this_call_data.prodesc = &desc;
/* we do not bother with refcounting the fake prodesc */
@@ -1940,7 +1940,7 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
if (!desc.reference) /* can this happen? */
elog(ERROR, "could not create internal procedure for anonymous code block");
- perlret = plperl_call_perl_func(&desc, &fake_fcinfo);
+ perlret = plperl_call_perl_func(&desc, fake_fcinfo);
SvREFCNT_dec_current(perlret);
@@ -2194,11 +2194,11 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
for (i = 0; i < desc->nargs; i++)
{
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
PUSHs(&PL_sv_undef);
else if (desc->arg_is_rowtype[i])
{
- SV *sv = plperl_hash_from_datum(fcinfo->arg[i]);
+ SV *sv = plperl_hash_from_datum(fcinfo->args[i].datum);
PUSHs(sv_2mortal(sv));
}
@@ -2208,15 +2208,15 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
Oid funcid;
if (OidIsValid(desc->arg_arraytype[i]))
- sv = plperl_ref_from_pg_array(fcinfo->arg[i], desc->arg_arraytype[i]);
+ sv = plperl_ref_from_pg_array(fcinfo->args[i].datum, desc->arg_arraytype[i]);
else if ((funcid = get_transform_fromsql(argtypes[i], current_call_data->prodesc->lang_oid, current_call_data->prodesc->trftypes)))
- sv = (SV *) DatumGetPointer(OidFunctionCall1(funcid, fcinfo->arg[i]));
+ sv = (SV *) DatumGetPointer(OidFunctionCall1(funcid, fcinfo->args[i].datum));
else
{
char *tmp;
tmp = OutputFunctionCall(&(desc->arg_out_func[i]),
- fcinfo->arg[i]);
+ fcinfo->args[i].datum);
sv = cstr2sv(tmp);
pfree(tmp);
}
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 45526383f25..665118cfe82 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -489,8 +489,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
assign_simple_var(&estate, var,
- fcinfo->arg[i],
- fcinfo->argnull[i],
+ fcinfo->args[i].datum,
+ fcinfo->args[i].isnull,
false);
/*
@@ -541,12 +541,12 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
{
PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n];
- if (!fcinfo->argnull[i])
+ if (!fcinfo->args[i].isnull)
{
/* Assign row value from composite datum */
exec_move_row_from_datum(&estate,
(PLpgSQL_variable *) rec,
- fcinfo->arg[i]);
+ fcinfo->args[i].datum);
}
else
{
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index 47ed95dcc60..d1a8c395ffd 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -436,10 +436,10 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
{
PLyDatumToOb *arginfo = &proc->args[i];
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
arg = NULL;
else
- arg = PLy_input_convert(arginfo, fcinfo->arg[i]);
+ arg = PLy_input_convert(arginfo, fcinfo->args[i].datum);
if (arg == NULL)
{
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index e2fa43b890d..3ee2a7fd4a2 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -601,7 +601,8 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted)
Form_pg_proc procStruct;
AclResult aclresult;
FmgrInfo finfo;
- FunctionCallInfoData fcinfo;
+ STACK_FCINFO_FOR_ARGS(fcinfo, 3);
+
PgStat_FunctionCallUsage fcusage;
/* select appropriate GUC */
@@ -662,11 +663,11 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted)
*/
InvokeFunctionExecuteHook(procOid);
fmgr_info(procOid, &finfo);
- InitFunctionCallInfoData(fcinfo, &finfo,
+ InitFunctionCallInfoData(*fcinfo, &finfo,
0,
InvalidOid, NULL, NULL);
- pgstat_init_function_usage(&fcinfo, &fcusage);
- (void) FunctionCallInvoke(&fcinfo);
+ pgstat_init_function_usage(fcinfo, &fcusage);
+ (void) FunctionCallInvoke(fcinfo);
pgstat_end_function_usage(&fcusage, true);
/* Pop the error context stack */
@@ -873,7 +874,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
/**************************************************
* For tuple values, add a list for 'array set ...'
**************************************************/
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj());
else
{
@@ -884,7 +885,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
HeapTupleData tmptup;
Tcl_Obj *list_tmp;
- td = DatumGetHeapTupleHeader(fcinfo->arg[i]);
+ td = DatumGetHeapTupleHeader(fcinfo->args[i].datum);
/* Extract rowtype info and find a tupdesc */
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
@@ -905,14 +906,14 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
* Single values are added as string element
* of their external representation
**************************************************/
- if (fcinfo->argnull[i])
+ if (fcinfo->args[i].isnull)
Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj());
else
{
char *tmp;
tmp = OutputFunctionCall(&prodesc->arg_out_func[i],
- fcinfo->arg[i]);
+ fcinfo->args[i].datum);
UTF_BEGIN;
Tcl_ListObjAppendElement(NULL, tcl_cmd,
Tcl_NewStringObj(UTF_E2U(tmp), -1));
--
2.18.0.rc2.dirty
--kkvoa4kudrvr5owc
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v2-0002-Replace-fmgr.-ch-duplication-with-macro-magic.patch"
view thread (16+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v2 1/2] Variable length FunctionCallInfoData.
In-Reply-To: <no-message-id-1202@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox