*** ./src/backend/executor/execQual.c.orig Tue Mar 22 11:23:29 2005 --- ./src/backend/executor/execQual.c Tue Mar 22 14:16:54 2005 *************** *** 773,778 **** --- 773,784 ---- ExprState *argstate = (ExprState *) lfirst(arg); ExprDoneCond thisArgIsDone; + /* + * argnull is initialized here for safety. Because it might not be + * set by ExecEvalExpr. + */ + fcinfo->argnull[i] = false; + fcinfo->arg[i] = ExecEvalExpr(argstate, econtext, &fcinfo->argnull[i], *************** *** 832,839 **** if (!fcache->setArgsValid) { /* Need to prep callinfo structure */ ! MemSet(&fcinfo, 0, sizeof(fcinfo)); ! fcinfo.flinfo = &(fcache->func); argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext); if (argDone == ExprEndResult) { --- 838,844 ---- if (!fcache->setArgsValid) { /* Need to prep callinfo structure */ ! InitFunctionCallInfoData(fcinfo, &(fcache->func), 0); argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext); if (argDone == ExprEndResult) { *************** *** 1046,1053 **** if (isDone) *isDone = ExprSingleResult; ! MemSet(&fcinfo, 0, sizeof(fcinfo)); ! fcinfo.flinfo = &(fcache->func); /* inlined, simplified version of ExecEvalFuncArgs */ i = 0; --- 1051,1057 ---- if (isDone) *isDone = ExprSingleResult; ! InitFunctionCallInfoData(fcinfo, &(fcache->func), 0); /* inlined, simplified version of ExecEvalFuncArgs */ i = 0; *************** *** 1056,1061 **** --- 1060,1071 ---- ExprState *argstate = (ExprState *) lfirst(arg); ExprDoneCond thisArgIsDone; + /* + * argnull is initialized here for safety. Because it might not be + * set by ExecEvalExpr. + */ + fcinfo.argnull[i] = false; + fcinfo.arg[i] = ExecEvalExpr(argstate, econtext, &fcinfo.argnull[i], *************** *** 1084,1090 **** } } } ! /* fcinfo.isnull = false; */ /* handled by MemSet */ result = FunctionCallInvoke(&fcinfo); *isNull = fcinfo.isnull; --- 1094,1100 ---- } } } ! /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */ result = FunctionCallInvoke(&fcinfo); *isNull = fcinfo.isnull; *************** *** 1132,1138 **** * 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; rsinfo.type = T_ReturnSetInfo; rsinfo.econtext = econtext; --- 1142,1148 ---- * 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. */ ! InitFunctionCallInfoData(fcinfo, NULL, 0); fcinfo.resultinfo = (Node *) &rsinfo; rsinfo.type = T_ReturnSetInfo; rsinfo.econtext = econtext; *************** *** 1499,1506 **** argList = fcache->args; /* Need to prep callinfo structure */ ! MemSet(&fcinfo, 0, sizeof(fcinfo)); ! fcinfo.flinfo = &(fcache->func); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, --- 1509,1515 ---- argList = fcache->args; /* Need to prep callinfo structure */ ! InitFunctionCallInfoData(fcinfo, &(fcache->func), 0); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, *************** *** 1573,1580 **** } /* Need to prep callinfo structure */ ! MemSet(&fcinfo, 0, sizeof(fcinfo)); ! fcinfo.flinfo = &(sstate->fxprstate.func); argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext); if (argDone != ExprSingleResult) ereport(ERROR, --- 1582,1588 ---- } /* Need to prep callinfo structure */ ! InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0); argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext); if (argDone != ExprSingleResult) ereport(ERROR, *************** *** 2287,2294 **** argList = nullIfExpr->args; /* Need to prep callinfo structure */ ! MemSet(&fcinfo, 0, sizeof(fcinfo)); ! fcinfo.flinfo = &(nullIfExpr->func); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, --- 2295,2301 ---- argList = nullIfExpr->args; /* Need to prep callinfo structure */ ! InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0); argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext); if (argDone != ExprSingleResult) ereport(ERROR, *** ./src/backend/utils/fmgr/fmgr.c.orig Tue Mar 22 11:23:11 2005 --- ./src/backend/utils/fmgr/fmgr.c Tue Mar 22 11:23:19 2005 *************** *** 846,868 **** */ /* - * 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 * are allowed to be NULL. Also, the function cannot be one that needs to --- 846,851 ---- *** ./src/include/fmgr.h.orig Tue Mar 22 11:22:47 2005 --- ./src/include/fmgr.h Tue Mar 22 11:23:05 2005 *************** *** 67,72 **** --- 67,88 ---- } FunctionCallInfoData; /* + * 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) + + /* * This routine fills a FmgrInfo struct, given the OID * of the function to be called. */