Big +1 on this one.
Here is what we did. It's very crude, but minimized the amount of pain:
It helps that the C compiler treats arrays and pointers the same.
I can dig for the complete patch if you want...
Cheers
Serge
/*
* This struct is the data actually passed to an fmgr-called function.
* There are three flavors:
* FunctionCallInfoData:
* Used when the number of arguments is both known and fixed small
* This structure is used for direct function calls involving
* builtin functions
* This structure must be initialized with: InitFunctionCallInfoData()
* FunctionCallInfoDataVariable:
* Used when the number of arguments is unknown and possibly large
* This structure must be allocated with allocFCInfoVar() and initialized with
* InitFunctionCallInfoData().
* FunctionCallInfoDataLarge:
* Used when the number of arguments is unknown, possibly large and
* the struct is embedded somewhere where a variable length is not acceptable
* This structure must be initialized with: InitFunctionCallInfoData()
*
* All structures have the same header and the arg/argnull fields shoule not be
* accessed directly but via the below accessor macros.
*/
typedef struct FunctionCallInfoData
{
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
fmNodePtr context; /* pass info about context of call */
fmNodePtr resultinfo; /* pass or return extra info about result */
Oid fncollation; /* collation for function to use */
bool isnull; /* function must set true if result is NULL */
bool isFixed; /* Must be true */
short nargs; /* # arguments actually passed */
Datum *arg; /* pointer to function arg array */
bool *argnull; /* pointer to null indicator array */
Datum __arg[FUNC_MAX_ARGS_FIX]; /* Arguments passed to function */
bool __argnull[FUNC_MAX_ARGS_FIX]; /* T if arg[i] is actually NULL */
} FunctionCallInfoData;
typedef struct FunctionCallInfoDataVariable
{
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
fmNodePtr context; /* pass info about context of call */
fmNodePtr resultinfo; /* pass or return extra info about result */
Oid fncollation; /* collation for function to use */
bool isnull; /* function must set true if result is NULL */
bool isFixed; /* Must be false */
short nargs; /* # arguments actually passed */
Datum *arg; /* pointer to function arg array */
bool *argnull; /* pointer to null indicator array */
} FunctionCallInfoDataVariable;
typedef struct FunctionCallInfoDataLarge
{
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
fmNodePtr context; /* pass info about context of call */
fmNodePtr resultinfo; /* pass or return extra info about result */
Oid fncollation; /* collation for function to use */
bool isnull; /* function must set true if result is NULL */
bool isFixed; /* Must be false */
short nargs; /* # arguments actually passed */
Datum *arg; /* pointer to function arg array */
bool *argnull; /* pointer to null indicator array */
Datum __arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
bool __argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */
} FunctionCallInfoDataLarge;