]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/fmgr/fmgr.c
Fix initialization of fake LSN for unlogged relations
[postgresql] / src / backend / utils / fmgr / fmgr.c
index a7b07827e01c95f032cb6ac3060d1cab55715f06..099ebd779ba26d2d2ee5f019d7d9f9e1505c0d82 100644 (file)
@@ -3,7 +3,7 @@
  * fmgr.c
  *       The Postgres function manager.
  *
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
@@ -15,7 +15,7 @@
 
 #include "postgres.h"
 
-#include "access/tuptoaster.h"
+#include "access/detoast.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_proc.h"
 #include "executor/functions.h"
@@ -53,13 +53,15 @@ static HTAB *CFuncHash = NULL;
 
 
 static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
-                                          bool ignore_security);
+                                                                  bool ignore_security);
 static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
 static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
 static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
 static void record_C_func(HeapTuple procedureTuple,
-                         PGFunction user_fn, const Pg_finfo_record *inforec);
-static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
+                                                 PGFunction user_fn, const Pg_finfo_record *inforec);
+
+/* extern so it's callable via JIT */
+extern Datum fmgr_security_definer(PG_FUNCTION_ARGS);
 
 
 /*
@@ -70,26 +72,21 @@ static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
 static const FmgrBuiltin *
 fmgr_isbuiltin(Oid id)
 {
-       int                     low = 0;
-       int                     high = fmgr_nbuiltins - 1;
+       uint16          index;
+
+       /* fast lookup only possible if original oid still assigned */
+       if (id > fmgr_last_builtin_oid)
+               return NULL;
 
        /*
-        * Loop invariant: low is the first index that could contain target entry,
-        * and high is the last index that could contain it.
+        * Lookup function data. If there's a miss in that range it's likely a
+        * nonexistent function, returning NULL here will trigger an ERROR later.
         */
-       while (low <= high)
-       {
-               int                     i = (high + low) / 2;
-               const FmgrBuiltin *ptr = &fmgr_builtins[i];
-
-               if (id == ptr->foid)
-                       return ptr;
-               else if (id > ptr->foid)
-                       low = i + 1;
-               else
-                       high = i - 1;
-       }
-       return NULL;
+       index = fmgr_builtin_oid_index[id];
+       if (index == InvalidOidBuiltinMapping)
+               return NULL;
+
+       return &fmgr_builtins[index];
 }
 
 /*
@@ -204,7 +201,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
         */
        if (!ignore_security &&
                (procedureStruct->prosecdef ||
-                !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig) ||
+                !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
                 FmgrHookIsNeeded(functionId)))
        {
                finfo->fn_addr = fmgr_security_definer;
@@ -220,7 +217,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
 
                        /*
                         * For an ordinary builtin function, we should never get here
-                        * because the isbuiltin() search above will have succeeded.
+                        * because the fmgr_isbuiltin() search above will have succeeded.
                         * However, if the user has done a CREATE FUNCTION to create an
                         * alias for a builtin function, we can end up here.  In that case
                         * we have to look up the function by name.  The name of the
@@ -265,6 +262,95 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
        ReleaseSysCache(procedureTuple);
 }
 
+/*
+ * Return module and C function name providing implementation of functionId.
+ *
+ * If *mod == NULL and *fn == NULL, no C symbol is known to implement
+ * function.
+ *
+ * If *mod == NULL and *fn != NULL, the function is implemented by a symbol in
+ * the main binary.
+ *
+ * If *mod != NULL and *fn !=NULL the function is implemented in an extension
+ * shared object.
+ *
+ * The returned module and function names are pstrdup'ed into the current
+ * memory context.
+ */
+void
+fmgr_symbol(Oid functionId, char **mod, char **fn)
+{
+       HeapTuple       procedureTuple;
+       Form_pg_proc procedureStruct;
+       bool            isnull;
+       Datum           prosrcattr;
+       Datum           probinattr;
+
+       /* Otherwise we need the pg_proc entry */
+       procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
+       if (!HeapTupleIsValid(procedureTuple))
+               elog(ERROR, "cache lookup failed for function %u", functionId);
+       procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+
+       /*
+        */
+       if (procedureStruct->prosecdef ||
+               !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
+               FmgrHookIsNeeded(functionId))
+       {
+               *mod = NULL;                    /* core binary */
+               *fn = pstrdup("fmgr_security_definer");
+               ReleaseSysCache(procedureTuple);
+               return;
+       }
+
+       /* see fmgr_info_cxt_security for the individual cases */
+       switch (procedureStruct->prolang)
+       {
+               case INTERNALlanguageId:
+                       prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
+                                                                                Anum_pg_proc_prosrc, &isnull);
+                       if (isnull)
+                               elog(ERROR, "null prosrc");
+
+                       *mod = NULL;            /* core binary */
+                       *fn = TextDatumGetCString(prosrcattr);
+                       break;
+
+               case ClanguageId:
+                       prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
+                                                                                Anum_pg_proc_prosrc, &isnull);
+                       if (isnull)
+                               elog(ERROR, "null prosrc for C function %u", functionId);
+
+                       probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
+                                                                                Anum_pg_proc_probin, &isnull);
+                       if (isnull)
+                               elog(ERROR, "null probin for C function %u", functionId);
+
+                       /*
+                        * No need to check symbol presence / API version here, already
+                        * checked in fmgr_info_cxt_security.
+                        */
+                       *mod = TextDatumGetCString(probinattr);
+                       *fn = TextDatumGetCString(prosrcattr);
+                       break;
+
+               case SQLlanguageId:
+                       *mod = NULL;            /* core binary */
+                       *fn = pstrdup("fmgr_sql");
+                       break;
+
+               default:
+                       *mod = NULL;
+                       *fn = NULL;                     /* unknown, pass pointer */
+                       break;
+       }
+
+       ReleaseSysCache(procedureTuple);
+}
+
+
 /*
  * Special fmgr_info processing for C-language functions.  Note that
  * finfo->fn_oid is not valid yet.
@@ -443,7 +529,7 @@ fetch_finfo_record(void *filehandle, const char *funcname)
 static CFuncHashTabEntry *
 lookup_C_func(HeapTuple procedureTuple)
 {
-       Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
+       Oid                     fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
        CFuncHashTabEntry *entry;
 
        if (CFuncHash == NULL)
@@ -468,7 +554,7 @@ static void
 record_C_func(HeapTuple procedureTuple,
                          PGFunction user_fn, const Pg_finfo_record *inforec)
 {
-       Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
+       Oid                     fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
        CFuncHashTabEntry *entry;
        bool            found;
 
@@ -570,7 +656,7 @@ struct fmgr_security_definer_cache
  * the actual arguments, etc.) intact.  This is not re-entrant, but then
  * the fcinfo itself can't be used reentrantly anyway.
  */
-static Datum
+extern Datum
 fmgr_security_definer(PG_FUNCTION_ARGS)
 {
        Datum           result;
@@ -706,18 +792,18 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
 Datum
 DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 1);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.argnull[0] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -726,20 +812,20 @@ DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
 Datum
 DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 2);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -749,22 +835,22 @@ Datum
 DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 3);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -774,24 +860,24 @@ Datum
 DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3, Datum arg4)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 4);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -801,26 +887,26 @@ Datum
 DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3, Datum arg4, Datum arg5)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 5);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -831,28 +917,28 @@ DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3, Datum arg4, Datum arg5,
                                                Datum arg6)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 6);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -863,30 +949,30 @@ DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3, Datum arg4, Datum arg5,
                                                Datum arg6, Datum arg7)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 7);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-
-       result = (*func) (&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -897,32 +983,32 @@ DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg3, Datum arg4, Datum arg5,
                                                Datum arg6, Datum arg7, Datum arg8)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 8);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-
-       result = (*func) (&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+       fcinfo->args[7].value = arg8;
+       fcinfo->args[7].isnull = false;
+
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -934,34 +1020,34 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                                Datum arg6, Datum arg7, Datum arg8,
                                                Datum arg9)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 9);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.arg[8] = arg9;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-       fcinfo.argnull[8] = false;
-
-       result = (*func) (&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+       fcinfo->args[7].value = arg8;
+       fcinfo->args[7].isnull = false;
+       fcinfo->args[8].value = arg9;
+       fcinfo->args[8].isnull = false;
+
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -979,18 +1065,18 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 Datum
 CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 1);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.argnull[0] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -999,20 +1085,20 @@ CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum
 Datum
 CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 2);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
 
-       result = (*func) (&fcinfo);
+       result = (*func) (fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
+       if (fcinfo->isnull)
                elog(ERROR, "function %p returned NULL", (void *) func);
 
        return result;
@@ -1023,22 +1109,39 @@ CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum
  * directly-computed parameter list.  Note that neither arguments nor result
  * are allowed to be NULL.
  */
+Datum
+FunctionCall0Coll(FmgrInfo *flinfo, Oid collation)
+{
+       LOCAL_FCINFO(fcinfo, 0);
+       Datum           result;
+
+       InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL);
+
+       result = FunctionCallInvoke(fcinfo);
+
+       /* Check for null result, since caller is clearly not expecting one */
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
+
+       return result;
+}
+
 Datum
 FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 1);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.argnull[0] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1046,21 +1149,21 @@ FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
 Datum
 FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 2);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1069,23 +1172,23 @@ Datum
 FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 3);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1094,25 +1197,25 @@ Datum
 FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3, Datum arg4)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 4);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1121,27 +1224,27 @@ Datum
 FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3, Datum arg4, Datum arg5)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 5);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1151,29 +1254,29 @@ FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3, Datum arg4, Datum arg5,
                                  Datum arg6)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 6);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL);
 
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1183,31 +1286,31 @@ FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3, Datum arg4, Datum arg5,
                                  Datum arg6, Datum arg7)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 7);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1217,33 +1320,33 @@ FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg3, Datum arg4, Datum arg5,
                                  Datum arg6, Datum arg7, Datum arg8)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 8);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+       fcinfo->args[7].value = arg8;
+       fcinfo->args[7].isnull = false;
+
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1254,35 +1357,35 @@ FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                                  Datum arg6, Datum arg7, Datum arg8,
                                  Datum arg9)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 9);
        Datum           result;
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.arg[8] = arg9;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-       fcinfo.argnull[8] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL);
+
+       fcinfo->args[0].value = arg1;
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = arg2;
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = arg3;
+       fcinfo->args[2].isnull = false;
+       fcinfo->args[3].value = arg4;
+       fcinfo->args[3].isnull = false;
+       fcinfo->args[4].value = arg5;
+       fcinfo->args[4].isnull = false;
+       fcinfo->args[5].value = arg6;
+       fcinfo->args[5].isnull = false;
+       fcinfo->args[6].value = arg7;
+       fcinfo->args[6].isnull = false;
+       fcinfo->args[7].value = arg8;
+       fcinfo->args[7].isnull = false;
+       fcinfo->args[8].value = arg9;
+       fcinfo->args[8].isnull = false;
+
+       result = FunctionCallInvoke(fcinfo);
 
        /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
+       if (fcinfo->isnull)
+               elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 
        return result;
 }
@@ -1299,68 +1402,30 @@ Datum
 OidFunctionCall0Coll(Oid functionId, Oid collation)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 0, collation, NULL, NULL);
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall0Coll(&flinfo, collation);
 }
 
 Datum
 OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.argnull[0] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall1Coll(&flinfo, collation, arg1);
 }
 
 Datum
 OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
 }
 
 Datum
@@ -1368,27 +1433,10 @@ OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg3)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
 }
 
 Datum
@@ -1396,29 +1444,10 @@ OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg3, Datum arg4)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
 }
 
 Datum
@@ -1426,31 +1455,10 @@ OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg3, Datum arg4, Datum arg5)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
 }
 
 Datum
@@ -1459,33 +1467,11 @@ OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg6)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+                                                        arg6);
 }
 
 Datum
@@ -1494,35 +1480,11 @@ OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg6, Datum arg7)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+                                                        arg6, arg7);
 }
 
 Datum
@@ -1531,37 +1493,11 @@ OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg6, Datum arg7, Datum arg8)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+                                                        arg6, arg7, arg8);
 }
 
 Datum
@@ -1571,39 +1507,11 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                                         Datum arg9)
 {
        FmgrInfo        flinfo;
-       FunctionCallInfoData fcinfo;
-       Datum           result;
 
        fmgr_info(functionId, &flinfo);
 
-       InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, NULL, NULL);
-
-       fcinfo.arg[0] = arg1;
-       fcinfo.arg[1] = arg2;
-       fcinfo.arg[2] = arg3;
-       fcinfo.arg[3] = arg4;
-       fcinfo.arg[4] = arg5;
-       fcinfo.arg[5] = arg6;
-       fcinfo.arg[6] = arg7;
-       fcinfo.arg[7] = arg8;
-       fcinfo.arg[8] = arg9;
-       fcinfo.argnull[0] = false;
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
-       fcinfo.argnull[3] = false;
-       fcinfo.argnull[4] = false;
-       fcinfo.argnull[5] = false;
-       fcinfo.argnull[6] = false;
-       fcinfo.argnull[7] = false;
-       fcinfo.argnull[8] = false;
-
-       result = FunctionCallInvoke(&fcinfo);
-
-       /* Check for null result, since caller is clearly not expecting one */
-       if (fcinfo.isnull)
-               elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
-
-       return result;
+       return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
+                                                        arg6, arg7, arg8, arg9);
 }
 
 
@@ -1622,35 +1530,35 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
 Datum
 InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 3);
        Datum           result;
 
        if (str == NULL && flinfo->fn_strict)
                return (Datum) 0;               /* just return null result */
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
 
-       fcinfo.arg[0] = CStringGetDatum(str);
-       fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
-       fcinfo.arg[2] = Int32GetDatum(typmod);
-       fcinfo.argnull[0] = (str == NULL);
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
+       fcinfo->args[0].value = CStringGetDatum(str);
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = Int32GetDatum(typmod);
+       fcinfo->args[2].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Should get null result if and only if str is NULL */
        if (str == NULL)
        {
-               if (!fcinfo.isnull)
+               if (!fcinfo->isnull)
                        elog(ERROR, "input function %u returned non-NULL",
-                                fcinfo.flinfo->fn_oid);
+                                flinfo->fn_oid);
        }
        else
        {
-               if (fcinfo.isnull)
+               if (fcinfo->isnull)
                        elog(ERROR, "input function %u returned NULL",
-                                fcinfo.flinfo->fn_oid);
+                                flinfo->fn_oid);
        }
 
        return result;
@@ -1681,35 +1589,35 @@ Datum
 ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
                                        Oid typioparam, int32 typmod)
 {
-       FunctionCallInfoData fcinfo;
+       LOCAL_FCINFO(fcinfo, 3);
        Datum           result;
 
        if (buf == NULL && flinfo->fn_strict)
                return (Datum) 0;               /* just return null result */
 
-       InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
+       InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
 
-       fcinfo.arg[0] = PointerGetDatum(buf);
-       fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
-       fcinfo.arg[2] = Int32GetDatum(typmod);
-       fcinfo.argnull[0] = (buf == NULL);
-       fcinfo.argnull[1] = false;
-       fcinfo.argnull[2] = false;
+       fcinfo->args[0].value = PointerGetDatum(buf);
+       fcinfo->args[0].isnull = false;
+       fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
+       fcinfo->args[1].isnull = false;
+       fcinfo->args[2].value = Int32GetDatum(typmod);
+       fcinfo->args[2].isnull = false;
 
-       result = FunctionCallInvoke(&fcinfo);
+       result = FunctionCallInvoke(fcinfo);
 
        /* Should get null result if and only if buf is NULL */
        if (buf == NULL)
        {
-               if (!fcinfo.isnull)
+               if (!fcinfo->isnull)
                        elog(ERROR, "receive function %u returned non-NULL",
-                                fcinfo.flinfo->fn_oid);
+                                flinfo->fn_oid);
        }
        else
        {
-               if (fcinfo.isnull)
+               if (fcinfo->isnull)
                        elog(ERROR, "receive function %u returned NULL",
-                                fcinfo.flinfo->fn_oid);
+                                flinfo->fn_oid);
        }
 
        return result;
@@ -1831,7 +1739,7 @@ struct varlena *
 pg_detoast_datum(struct varlena *datum)
 {
        if (VARATT_IS_EXTENDED(datum))
-               return heap_tuple_untoast_attr(datum);
+               return detoast_attr(datum);
        else
                return datum;
 }
@@ -1840,7 +1748,7 @@ struct varlena *
 pg_detoast_datum_copy(struct varlena *datum)
 {
        if (VARATT_IS_EXTENDED(datum))
-               return heap_tuple_untoast_attr(datum);
+               return detoast_attr(datum);
        else
        {
                /* Make a modifiable copy of the varlena object */
@@ -1856,14 +1764,14 @@ struct varlena *
 pg_detoast_datum_slice(struct varlena *datum, int32 first, int32 count)
 {
        /* Only get the specified portion from the toast rel */
-       return heap_tuple_untoast_attr_slice(datum, first, count);
+       return detoast_attr_slice(datum, first, count);
 }
 
 struct varlena *
 pg_detoast_datum_packed(struct varlena *datum)
 {
        if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
-               return heap_tuple_untoast_attr(datum);
+               return detoast_attr(datum);
        else
                return datum;
 }
@@ -1941,8 +1849,6 @@ get_call_expr_argtype(Node *expr, int argnum)
                args = ((DistinctExpr *) expr)->args;
        else if (IsA(expr, ScalarArrayOpExpr))
                args = ((ScalarArrayOpExpr *) expr)->args;
-       else if (IsA(expr, ArrayCoerceExpr))
-               args = list_make1(((ArrayCoerceExpr *) expr)->arg);
        else if (IsA(expr, NullIfExpr))
                args = ((NullIfExpr *) expr)->args;
        else if (IsA(expr, WindowFunc))
@@ -1956,16 +1862,12 @@ get_call_expr_argtype(Node *expr, int argnum)
        argtype = exprType((Node *) list_nth(args, argnum));
 
        /*
-        * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the
-        * underlying function will actually get passed is the element type of the
-        * array.
+        * special hack for ScalarArrayOpExpr: what the underlying function will
+        * actually get passed is the element type of the array.
         */
        if (IsA(expr, ScalarArrayOpExpr) &&
                argnum == 1)
                argtype = get_base_element_type(argtype);
-       else if (IsA(expr, ArrayCoerceExpr) &&
-                        argnum == 0)
-               argtype = get_base_element_type(argtype);
 
        return argtype;
 }
@@ -2012,8 +1914,6 @@ get_call_expr_arg_stable(Node *expr, int argnum)
                args = ((DistinctExpr *) expr)->args;
        else if (IsA(expr, ScalarArrayOpExpr))
                args = ((ScalarArrayOpExpr *) expr)->args;
-       else if (IsA(expr, ArrayCoerceExpr))
-               args = list_make1(((ArrayCoerceExpr *) expr)->arg);
        else if (IsA(expr, NullIfExpr))
                args = ((NullIfExpr *) expr)->args;
        else if (IsA(expr, WindowFunc))
@@ -2137,7 +2037,7 @@ CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
        aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
                                                                         ACL_USAGE);
        if (aclresult != ACLCHECK_OK)
-               aclcheck_error(aclresult, ACL_KIND_LANGUAGE,
+               aclcheck_error(aclresult, OBJECT_LANGUAGE,
                                           NameStr(langStruct->lanname));
 
        /*
@@ -2147,7 +2047,7 @@ CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
         */
        aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
        if (aclresult != ACLCHECK_OK)
-               aclcheck_error(aclresult, ACL_KIND_PROC, NameStr(procStruct->proname));
+               aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
 
        ReleaseSysCache(procTup);
        ReleaseSysCache(langTup);