On 02/23/2017 04:41 PM, Tom Lane wrote: > Andrew Dunstan <andrew.duns...@2ndquadrant.com> writes: >> I'm not entirely sure how I should replace those DirectFunctionCall2 calls. > Basically what we want is for the called function to be able to use the > fcinfo->flinfo->fn_extra and fcinfo->flinfo->fn_mcxt fields of the > FmgrInfo struct that GIN has set up for the btree_gin support function. > > The fast but somewhat scary way to do it would just be to pass through > the flinfo pointer as-is. Imagine that fmgr.c grows a set of functions > like > > Datum > DontKnowWhatToCallThisFunctionCall2(PGFunction func, > FmgrInfo *flinfo, Oid collation, > Datum arg1, Datum arg2) > { > FunctionCallInfoData fcinfo; > Datum result; > > InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL); > > fcinfo.arg[0] = arg1; > fcinfo.arg[1] = arg2; > fcinfo.argnull[0] = false; > fcinfo.argnull[1] = false; > > result = (*func) (&fcinfo); > > /* Check for null result, since caller is clearly not expecting one */ > if (fcinfo.isnull) > elog(ERROR, "function %p returned NULL", (void *) func); > > return result; > } > > and then you'd just pass through the fcinfo->flinfo you got. > > The reason this is kind of scary is that it's just blithely assuming > that the function won't look at the *other* fields of the FmgrInfo. > If it did, it would likely get very confused, since those fields > would be describing the GIN support function, not the function we're > calling. > > We could alternatively have this trampoline function set up a fresh, local > FmgrInfo struct that it zeroes except for copying fn_extra and fn_mcxt > from the caller's struct, and then it copies fn_extra back again on the > way out. That's a few more cycles but it would be safer, I think; if the > function tried to look at the other fields such as fn_oid it would see > obviously bogus data. > >
Do we want one or both of these? I'm prepared to code up a patch to fmgr.[ch] to provide them. I don't know what to call it either. In my test I used CallerContextFunctionCall2 - not sure if that's quite right, but should be close. The technique is somewhat similar to what we do in plperl.c where we fake up a function call for handling DO blocks. cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers