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;