From bd9b4a9d46600eeadbb8420d45a29b819c73bba7 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 22 Mar 2005 20:13:09 +0000 Subject: [PATCH] Use InitFunctionCallInfoData() macro instead of MemSet in performance critical places in execQual. By Atsushi Ogawa; some minor cleanup by moi. --- src/backend/executor/execQual.c | 25 ++++------ src/backend/executor/nodeAgg.c | 21 ++------- src/backend/utils/fmgr/fmgr.c | 73 ++++++++++++------------------ src/backend/utils/sort/tuplesort.c | 8 +--- src/include/fmgr.h | 18 +++++++- 5 files changed, 61 insertions(+), 84 deletions(-) diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 3613d31a05..63a734ea0f 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.173 2005/03/16 21:38:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.174 2005/03/22 20:13:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -832,8 +832,7 @@ ExecMakeFunctionResult(FuncExprState *fcache, if (!fcache->setArgsValid) { /* Need to prep callinfo structure */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.flinfo = &(fcache->func); + InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL); argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext); if (argDone == ExprEndResult) { @@ -1046,9 +1045,6 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache, if (isDone) *isDone = ExprSingleResult; - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.flinfo = &(fcache->func); - /* inlined, simplified version of ExecEvalFuncArgs */ i = 0; foreach(arg, fcache->args) @@ -1067,7 +1063,8 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache, errmsg("set-valued function called in context that cannot accept a set"))); i++; } - fcinfo.nargs = i; + + InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL); /* * If function is strict, and there are any NULL arguments, skip @@ -1084,7 +1081,7 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache, } } } - /* fcinfo.isnull = false; */ /* handled by MemSet */ + /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */ result = FunctionCallInvoke(&fcinfo); *isNull = fcinfo.isnull; @@ -1132,8 +1129,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr, * doesn't actually get to see the resultinfo, but set it up anyway * because we use some of the fields as our own state variables. */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.resultinfo = (Node *) &rsinfo; + InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo); rsinfo.type = T_ReturnSetInfo; rsinfo.econtext = econtext; rsinfo.expectedDesc = expectedDesc; @@ -1499,8 +1495,7 @@ ExecEvalDistinct(FuncExprState *fcache, argList = fcache->args; /* Need to prep callinfo structure */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.flinfo = &(fcache->func); + InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, @@ -1573,8 +1568,7 @@ ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate, } /* Need to prep callinfo structure */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.flinfo = &(sstate->fxprstate.func); + InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL); argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext); if (argDone != ExprSingleResult) ereport(ERROR, @@ -2287,8 +2281,7 @@ ExecEvalNullIf(FuncExprState *nullIfExpr, argList = nullIfExpr->args; /* Need to prep callinfo structure */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.flinfo = &(nullIfExpr->func); + InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 1e211803df..1756f35e7b 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -61,7 +61,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.130 2005/03/16 21:38:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.131 2005/03/22 20:13:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -373,18 +373,9 @@ advance_transition_function(AggState *aggstate, /* * OK to call the transition function - * - * This is heavily-used code, so manually zero just the necessary fields - * instead of using MemSet(). Compare FunctionCall2(). */ - - /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */ - fcinfo.context = (void *) aggstate; - fcinfo.resultinfo = NULL; - fcinfo.isnull = false; - - fcinfo.flinfo = &peraggstate->transfn; - fcinfo.nargs = 2; + InitFunctionCallInfoData(fcinfo, &(peraggstate->transfn), 2, + (void *) aggstate, NULL); fcinfo.arg[0] = pergroupstate->transValue; fcinfo.argnull[0] = pergroupstate->transValueIsNull; fcinfo.arg[1] = newVal; @@ -556,10 +547,8 @@ finalize_aggregate(AggState *aggstate, { FunctionCallInfoData fcinfo; - MemSet(&fcinfo, 0, sizeof(fcinfo)); - fcinfo.context = (void *) aggstate; - fcinfo.flinfo = &peraggstate->finalfn; - fcinfo.nargs = 1; + InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1, + (void *) aggstate, NULL); fcinfo.arg[0] = pergroupstate->transValue; fcinfo.argnull[0] = pergroupstate->transValueIsNull; if (fcinfo.flinfo->fn_strict && pergroupstate->transValueIsNull) diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 849594bccc..e34a942aba 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.89 2005/02/02 22:40:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.90 2005/03/22 20:13:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -845,23 +845,6 @@ fmgr_security_definer(PG_FUNCTION_ARGS) *------------------------------------------------------------------------- */ -/* - * This macro initializes all the fields of a FunctionCallInfoData except - * for the arg[] and argnull[] arrays. Performance testing has shown that - * the fastest way to set up argnull[] for small numbers of arguments is to - * explicitly set each required element to false, so we don't try to zero - * out the argnull[] array in the macro. - */ -#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs) \ - do { \ - (Fcinfo).flinfo = (Flinfo); \ - (Fcinfo).context = NULL; \ - (Fcinfo).resultinfo = NULL; \ - (Fcinfo).isnull = false; \ - (Fcinfo).nargs = (Nargs); \ - } while (0) - - /* * These are for invocation of a specifically named function with a * directly-computed parameter list. Note that neither arguments nor result @@ -874,7 +857,7 @@ DirectFunctionCall1(PGFunction func, Datum arg1) FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 1); + InitFunctionCallInfoData(fcinfo, NULL, 1, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.argnull[0] = false; @@ -894,7 +877,7 @@ DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2) FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 2); + InitFunctionCallInfoData(fcinfo, NULL, 2, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -917,7 +900,7 @@ DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 3); + InitFunctionCallInfoData(fcinfo, NULL, 3, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -942,7 +925,7 @@ DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 4); + InitFunctionCallInfoData(fcinfo, NULL, 4, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -969,7 +952,7 @@ DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 5); + InitFunctionCallInfoData(fcinfo, NULL, 5, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -999,7 +982,7 @@ DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 6); + InitFunctionCallInfoData(fcinfo, NULL, 6, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1031,7 +1014,7 @@ DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 7); + InitFunctionCallInfoData(fcinfo, NULL, 7, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1065,7 +1048,7 @@ DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 8); + InitFunctionCallInfoData(fcinfo, NULL, 8, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1102,7 +1085,7 @@ DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 9); + InitFunctionCallInfoData(fcinfo, NULL, 9, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1144,7 +1127,7 @@ FunctionCall1(FmgrInfo *flinfo, Datum arg1) FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 1); + InitFunctionCallInfoData(fcinfo, flinfo, 1, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.argnull[0] = false; @@ -1168,7 +1151,7 @@ FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2) FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 2); + InitFunctionCallInfoData(fcinfo, flinfo, 2, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1191,7 +1174,7 @@ FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 3); + InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1216,7 +1199,7 @@ FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 4); + InitFunctionCallInfoData(fcinfo, flinfo, 4, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1243,7 +1226,7 @@ FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 5); + InitFunctionCallInfoData(fcinfo, flinfo, 5, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1273,7 +1256,7 @@ FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 6); + InitFunctionCallInfoData(fcinfo, flinfo, 6, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1305,7 +1288,7 @@ FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 7); + InitFunctionCallInfoData(fcinfo, flinfo, 7, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1339,7 +1322,7 @@ FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 8); + InitFunctionCallInfoData(fcinfo, flinfo, 8, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1376,7 +1359,7 @@ FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2, FunctionCallInfoData fcinfo; Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 9); + InitFunctionCallInfoData(fcinfo, flinfo, 9, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1423,7 +1406,7 @@ OidFunctionCall1(Oid functionId, Datum arg1) fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 1); + InitFunctionCallInfoData(fcinfo, &flinfo, 1, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.argnull[0] = false; @@ -1446,7 +1429,7 @@ OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2) fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 2); + InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1472,7 +1455,7 @@ OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 3); + InitFunctionCallInfoData(fcinfo, &flinfo, 3, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1500,7 +1483,7 @@ OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 4); + InitFunctionCallInfoData(fcinfo, &flinfo, 4, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1530,7 +1513,7 @@ OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 5); + InitFunctionCallInfoData(fcinfo, &flinfo, 5, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1563,7 +1546,7 @@ OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 6); + InitFunctionCallInfoData(fcinfo, &flinfo, 6, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1598,7 +1581,7 @@ OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 7); + InitFunctionCallInfoData(fcinfo, &flinfo, 7, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1635,7 +1618,7 @@ OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 8); + InitFunctionCallInfoData(fcinfo, &flinfo, 8, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; @@ -1675,7 +1658,7 @@ OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2, fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 9); + InitFunctionCallInfoData(fcinfo, &flinfo, 9, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 8c01f2efb0..ac0fe7a100 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -78,7 +78,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.46 2005/02/02 22:40:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.47 2005/03/22 20:13:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1804,11 +1804,7 @@ myFunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2) FunctionCallInfoData fcinfo; Datum result; - fcinfo.flinfo = flinfo; - fcinfo.context = NULL; - fcinfo.resultinfo = NULL; - fcinfo.isnull = false; - fcinfo.nargs = 2; + InitFunctionCallInfoData(fcinfo, flinfo, 2, NULL, NULL); fcinfo.arg[0] = arg1; fcinfo.arg[1] = arg2; diff --git a/src/include/fmgr.h b/src/include/fmgr.h index c366cf965c..0c11130053 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -11,7 +11,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.36 2004/12/31 22:03:19 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.37 2005/03/22 20:13:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -86,6 +86,22 @@ extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt); +/* + * This macro initializes all the fields of a FunctionCallInfoData except + * for the arg[] and argnull[] arrays. Performance testing has shown that + * the fastest way to set up argnull[] for small numbers of arguments is to + * explicitly set each required element to false, so we don't try to zero + * out the argnull[] array in the macro. + */ +#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Context, Resultinfo) \ + do { \ + (Fcinfo).flinfo = (Flinfo); \ + (Fcinfo).context = (Context); \ + (Fcinfo).resultinfo = (Resultinfo); \ + (Fcinfo).isnull = false; \ + (Fcinfo).nargs = (Nargs); \ + } while (0) + /* * This macro invokes a function given a filled-in FunctionCallInfoData * struct. The macro result is the returned Datum --- but note that