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;

Reply via email to