LCOV - code coverage report
Current view: top level - src/backend/utils/fmgr - fmgr.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 532 768 69.3 %
Date: 2019-11-21 12:06:29 Functions: 54 65 83.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fmgr.c
       4             :  *    The Postgres function manager.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/utils/fmgr/fmgr.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres.h"
      17             : 
      18             : #include "access/detoast.h"
      19             : #include "catalog/pg_language.h"
      20             : #include "catalog/pg_proc.h"
      21             : #include "executor/functions.h"
      22             : #include "lib/stringinfo.h"
      23             : #include "miscadmin.h"
      24             : #include "nodes/nodeFuncs.h"
      25             : #include "pgstat.h"
      26             : #include "utils/acl.h"
      27             : #include "utils/builtins.h"
      28             : #include "utils/fmgrtab.h"
      29             : #include "utils/guc.h"
      30             : #include "utils/lsyscache.h"
      31             : #include "utils/syscache.h"
      32             : 
      33             : /*
      34             :  * Hooks for function calls
      35             :  */
      36             : PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook = NULL;
      37             : PGDLLIMPORT fmgr_hook_type fmgr_hook = NULL;
      38             : 
      39             : /*
      40             :  * Hashtable for fast lookup of external C functions
      41             :  */
      42             : typedef struct
      43             : {
      44             :     /* fn_oid is the hash key and so must be first! */
      45             :     Oid         fn_oid;         /* OID of an external C function */
      46             :     TransactionId fn_xmin;      /* for checking up-to-dateness */
      47             :     ItemPointerData fn_tid;
      48             :     PGFunction  user_fn;        /* the function's address */
      49             :     const Pg_finfo_record *inforec; /* address of its info record */
      50             : } CFuncHashTabEntry;
      51             : 
      52             : static HTAB *CFuncHash = NULL;
      53             : 
      54             : 
      55             : static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
      56             :                                    bool ignore_security);
      57             : static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
      58             : static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
      59             : static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
      60             : static void record_C_func(HeapTuple procedureTuple,
      61             :                           PGFunction user_fn, const Pg_finfo_record *inforec);
      62             : 
      63             : /* extern so it's callable via JIT */
      64             : extern Datum fmgr_security_definer(PG_FUNCTION_ARGS);
      65             : 
      66             : 
      67             : /*
      68             :  * Lookup routines for builtin-function table.  We can search by either Oid
      69             :  * or name, but search by Oid is much faster.
      70             :  */
      71             : 
      72             : static const FmgrBuiltin *
      73    51543792 : fmgr_isbuiltin(Oid id)
      74             : {
      75             :     uint16      index;
      76             : 
      77             :     /* fast lookup only possible if original oid still assigned */
      78    51543792 :     if (id > fmgr_last_builtin_oid)
      79       67452 :         return NULL;
      80             : 
      81             :     /*
      82             :      * Lookup function data. If there's a miss in that range it's likely a
      83             :      * nonexistent function, returning NULL here will trigger an ERROR later.
      84             :      */
      85    51476340 :     index = fmgr_builtin_oid_index[id];
      86    51476340 :     if (index == InvalidOidBuiltinMapping)
      87        1848 :         return NULL;
      88             : 
      89    51474492 :     return &fmgr_builtins[index];
      90             : }
      91             : 
      92             : /*
      93             :  * Lookup a builtin by name.  Note there can be more than one entry in
      94             :  * the array with the same name, but they should all point to the same
      95             :  * routine.
      96             :  */
      97             : static const FmgrBuiltin *
      98       10516 : fmgr_lookupByName(const char *name)
      99             : {
     100             :     int         i;
     101             : 
     102    17268008 :     for (i = 0; i < fmgr_nbuiltins; i++)
     103             :     {
     104    17268004 :         if (strcmp(name, fmgr_builtins[i].funcName) == 0)
     105       10512 :             return fmgr_builtins + i;
     106             :     }
     107           4 :     return NULL;
     108             : }
     109             : 
     110             : /*
     111             :  * This routine fills a FmgrInfo struct, given the OID
     112             :  * of the function to be called.
     113             :  *
     114             :  * The caller's CurrentMemoryContext is used as the fn_mcxt of the info
     115             :  * struct; this means that any subsidiary data attached to the info struct
     116             :  * (either by fmgr_info itself, or later on by a function call handler)
     117             :  * will be allocated in that context.  The caller must ensure that this
     118             :  * context is at least as long-lived as the info struct itself.  This is
     119             :  * not a problem in typical cases where the info struct is on the stack or
     120             :  * in freshly-palloc'd space.  However, if one intends to store an info
     121             :  * struct in a long-lived table, it's better to use fmgr_info_cxt.
     122             :  */
     123             : void
     124    50398128 : fmgr_info(Oid functionId, FmgrInfo *finfo)
     125             : {
     126    50398128 :     fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
     127    50398128 : }
     128             : 
     129             : /*
     130             :  * Fill a FmgrInfo struct, specifying a memory context in which its
     131             :  * subsidiary data should go.
     132             :  */
     133             : void
     134     1128448 : fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
     135             : {
     136     1128448 :     fmgr_info_cxt_security(functionId, finfo, mcxt, false);
     137     1128448 : }
     138             : 
     139             : /*
     140             :  * This one does the actual work.  ignore_security is ordinarily false
     141             :  * but is set to true when we need to avoid recursion.
     142             :  */
     143             : static void
     144    51543792 : fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
     145             :                        bool ignore_security)
     146             : {
     147             :     const FmgrBuiltin *fbp;
     148             :     HeapTuple   procedureTuple;
     149             :     Form_pg_proc procedureStruct;
     150             :     Datum       prosrcdatum;
     151             :     bool        isnull;
     152             :     char       *prosrc;
     153             : 
     154             :     /*
     155             :      * fn_oid *must* be filled in last.  Some code assumes that if fn_oid is
     156             :      * valid, the whole struct is valid.  Some FmgrInfo struct's do survive
     157             :      * elogs.
     158             :      */
     159    51543792 :     finfo->fn_oid = InvalidOid;
     160    51543792 :     finfo->fn_extra = NULL;
     161    51543792 :     finfo->fn_mcxt = mcxt;
     162    51543792 :     finfo->fn_expr = NULL;       /* caller may set this later */
     163             : 
     164    51543792 :     if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
     165             :     {
     166             :         /*
     167             :          * Fast path for builtin functions: don't bother consulting pg_proc
     168             :          */
     169    51474492 :         finfo->fn_nargs = fbp->nargs;
     170    51474492 :         finfo->fn_strict = fbp->strict;
     171    51474492 :         finfo->fn_retset = fbp->retset;
     172    51474492 :         finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
     173    51474492 :         finfo->fn_addr = fbp->func;
     174    51474492 :         finfo->fn_oid = functionId;
     175   102949030 :         return;
     176             :     }
     177             : 
     178             :     /* Otherwise we need the pg_proc entry */
     179       69300 :     procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
     180       69300 :     if (!HeapTupleIsValid(procedureTuple))
     181           0 :         elog(ERROR, "cache lookup failed for function %u", functionId);
     182       69300 :     procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
     183             : 
     184       69300 :     finfo->fn_nargs = procedureStruct->pronargs;
     185       69300 :     finfo->fn_strict = procedureStruct->proisstrict;
     186       69300 :     finfo->fn_retset = procedureStruct->proretset;
     187             : 
     188             :     /*
     189             :      * If it has prosecdef set, non-null proconfig, or if a plugin wants to
     190             :      * hook function entry/exit, use fmgr_security_definer call handler ---
     191             :      * unless we are being called again by fmgr_security_definer or
     192             :      * fmgr_info_other_lang.
     193             :      *
     194             :      * When using fmgr_security_definer, function stats tracking is always
     195             :      * disabled at the outer level, and instead we set the flag properly in
     196             :      * fmgr_security_definer's private flinfo and implement the tracking
     197             :      * inside fmgr_security_definer.  This loses the ability to charge the
     198             :      * overhead of fmgr_security_definer to the function, but gains the
     199             :      * ability to set the track_functions GUC as a local GUC parameter of an
     200             :      * interesting function and have the right things happen.
     201             :      */
     202      121384 :     if (!ignore_security &&
     203      104152 :         (procedureStruct->prosecdef ||
     204      104106 :          !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
     205       52038 :          FmgrHookIsNeeded(functionId)))
     206             :     {
     207          46 :         finfo->fn_addr = fmgr_security_definer;
     208          46 :         finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
     209          46 :         finfo->fn_oid = functionId;
     210          46 :         ReleaseSysCache(procedureTuple);
     211          46 :         return;
     212             :     }
     213             : 
     214       69254 :     switch (procedureStruct->prolang)
     215             :     {
     216             :         case INTERNALlanguageId:
     217             : 
     218             :             /*
     219             :              * For an ordinary builtin function, we should never get here
     220             :              * because the fmgr_isbuiltin() search above will have succeeded.
     221             :              * However, if the user has done a CREATE FUNCTION to create an
     222             :              * alias for a builtin function, we can end up here.  In that case
     223             :              * we have to look up the function by name.  The name of the
     224             :              * internal function is stored in prosrc (it doesn't have to be
     225             :              * the same as the name of the alias!)
     226             :              */
     227        1746 :             prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
     228             :                                           Anum_pg_proc_prosrc, &isnull);
     229        1746 :             if (isnull)
     230           0 :                 elog(ERROR, "null prosrc");
     231        1746 :             prosrc = TextDatumGetCString(prosrcdatum);
     232        1746 :             fbp = fmgr_lookupByName(prosrc);
     233        1746 :             if (fbp == NULL)
     234           0 :                 ereport(ERROR,
     235             :                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
     236             :                          errmsg("internal function \"%s\" is not in internal lookup table",
     237             :                                 prosrc)));
     238        1746 :             pfree(prosrc);
     239             :             /* Should we check that nargs, strict, retset match the table? */
     240        1746 :             finfo->fn_addr = fbp->func;
     241             :             /* note this policy is also assumed in fast path above */
     242        1746 :             finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
     243        1746 :             break;
     244             : 
     245             :         case ClanguageId:
     246       38172 :             fmgr_info_C_lang(functionId, finfo, procedureTuple);
     247       38172 :             finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */
     248       38172 :             break;
     249             : 
     250             :         case SQLlanguageId:
     251       12166 :             finfo->fn_addr = fmgr_sql;
     252       12166 :             finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */
     253       12166 :             break;
     254             : 
     255             :         default:
     256       17170 :             fmgr_info_other_lang(functionId, finfo, procedureTuple);
     257       17170 :             finfo->fn_stats = TRACK_FUNC_OFF;    /* ie, track if not OFF */
     258       17170 :             break;
     259             :     }
     260             : 
     261       69254 :     finfo->fn_oid = functionId;
     262       69254 :     ReleaseSysCache(procedureTuple);
     263             : }
     264             : 
     265             : /*
     266             :  * Return module and C function name providing implementation of functionId.
     267             :  *
     268             :  * If *mod == NULL and *fn == NULL, no C symbol is known to implement
     269             :  * function.
     270             :  *
     271             :  * If *mod == NULL and *fn != NULL, the function is implemented by a symbol in
     272             :  * the main binary.
     273             :  *
     274             :  * If *mod != NULL and *fn !=NULL the function is implemented in an extension
     275             :  * shared object.
     276             :  *
     277             :  * The returned module and function names are pstrdup'ed into the current
     278             :  * memory context.
     279             :  */
     280             : void
     281        1604 : fmgr_symbol(Oid functionId, char **mod, char **fn)
     282             : {
     283             :     HeapTuple   procedureTuple;
     284             :     Form_pg_proc procedureStruct;
     285             :     bool        isnull;
     286             :     Datum       prosrcattr;
     287             :     Datum       probinattr;
     288             : 
     289             :     /* Otherwise we need the pg_proc entry */
     290        1604 :     procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
     291        1604 :     if (!HeapTupleIsValid(procedureTuple))
     292           0 :         elog(ERROR, "cache lookup failed for function %u", functionId);
     293        1604 :     procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
     294             : 
     295             :     /*
     296             :      */
     297        3208 :     if (procedureStruct->prosecdef ||
     298        3208 :         !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
     299        1604 :         FmgrHookIsNeeded(functionId))
     300             :     {
     301           0 :         *mod = NULL;            /* core binary */
     302           0 :         *fn = pstrdup("fmgr_security_definer");
     303           0 :         ReleaseSysCache(procedureTuple);
     304           0 :         return;
     305             :     }
     306             : 
     307             :     /* see fmgr_info_cxt_security for the individual cases */
     308        1604 :     switch (procedureStruct->prolang)
     309             :     {
     310             :         case INTERNALlanguageId:
     311        1578 :             prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
     312             :                                          Anum_pg_proc_prosrc, &isnull);
     313        1578 :             if (isnull)
     314           0 :                 elog(ERROR, "null prosrc");
     315             : 
     316        1578 :             *mod = NULL;        /* core binary */
     317        1578 :             *fn = TextDatumGetCString(prosrcattr);
     318        1578 :             break;
     319             : 
     320             :         case ClanguageId:
     321          26 :             prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
     322             :                                          Anum_pg_proc_prosrc, &isnull);
     323          26 :             if (isnull)
     324           0 :                 elog(ERROR, "null prosrc for C function %u", functionId);
     325             : 
     326          26 :             probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
     327             :                                          Anum_pg_proc_probin, &isnull);
     328          26 :             if (isnull)
     329           0 :                 elog(ERROR, "null probin for C function %u", functionId);
     330             : 
     331             :             /*
     332             :              * No need to check symbol presence / API version here, already
     333             :              * checked in fmgr_info_cxt_security.
     334             :              */
     335          26 :             *mod = TextDatumGetCString(probinattr);
     336          26 :             *fn = TextDatumGetCString(prosrcattr);
     337          26 :             break;
     338             : 
     339             :         case SQLlanguageId:
     340           0 :             *mod = NULL;        /* core binary */
     341           0 :             *fn = pstrdup("fmgr_sql");
     342           0 :             break;
     343             : 
     344             :         default:
     345           0 :             *mod = NULL;
     346           0 :             *fn = NULL;         /* unknown, pass pointer */
     347           0 :             break;
     348             :     }
     349             : 
     350        1604 :     ReleaseSysCache(procedureTuple);
     351             : }
     352             : 
     353             : 
     354             : /*
     355             :  * Special fmgr_info processing for C-language functions.  Note that
     356             :  * finfo->fn_oid is not valid yet.
     357             :  */
     358             : static void
     359       38172 : fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
     360             : {
     361             :     CFuncHashTabEntry *hashentry;
     362             :     PGFunction  user_fn;
     363             :     const Pg_finfo_record *inforec;
     364             :     bool        isnull;
     365             : 
     366             :     /*
     367             :      * See if we have the function address cached already
     368             :      */
     369       38172 :     hashentry = lookup_C_func(procedureTuple);
     370       38172 :     if (hashentry)
     371             :     {
     372       34850 :         user_fn = hashentry->user_fn;
     373       34850 :         inforec = hashentry->inforec;
     374             :     }
     375             :     else
     376             :     {
     377             :         Datum       prosrcattr,
     378             :                     probinattr;
     379             :         char       *prosrcstring,
     380             :                    *probinstring;
     381             :         void       *libraryhandle;
     382             : 
     383             :         /*
     384             :          * Get prosrc and probin strings (link symbol and library filename).
     385             :          * While in general these columns might be null, that's not allowed
     386             :          * for C-language functions.
     387             :          */
     388        3322 :         prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
     389             :                                      Anum_pg_proc_prosrc, &isnull);
     390        3322 :         if (isnull)
     391           0 :             elog(ERROR, "null prosrc for C function %u", functionId);
     392        3322 :         prosrcstring = TextDatumGetCString(prosrcattr);
     393             : 
     394        3322 :         probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
     395             :                                      Anum_pg_proc_probin, &isnull);
     396        3322 :         if (isnull)
     397           0 :             elog(ERROR, "null probin for C function %u", functionId);
     398        3322 :         probinstring = TextDatumGetCString(probinattr);
     399             : 
     400             :         /* Look up the function itself */
     401        3322 :         user_fn = load_external_function(probinstring, prosrcstring, true,
     402             :                                          &libraryhandle);
     403             : 
     404             :         /* Get the function information record (real or default) */
     405        3322 :         inforec = fetch_finfo_record(libraryhandle, prosrcstring);
     406             : 
     407             :         /* Cache the addresses for later calls */
     408        3322 :         record_C_func(procedureTuple, user_fn, inforec);
     409             : 
     410        3322 :         pfree(prosrcstring);
     411        3322 :         pfree(probinstring);
     412             :     }
     413             : 
     414       38172 :     switch (inforec->api_version)
     415             :     {
     416             :         case 1:
     417             :             /* New style: call directly */
     418       38172 :             finfo->fn_addr = user_fn;
     419       38172 :             break;
     420             :         default:
     421             :             /* Shouldn't get here if fetch_finfo_record did its job */
     422           0 :             elog(ERROR, "unrecognized function API version: %d",
     423             :                  inforec->api_version);
     424             :             break;
     425             :     }
     426       38172 : }
     427             : 
     428             : /*
     429             :  * Special fmgr_info processing for other-language functions.  Note
     430             :  * that finfo->fn_oid is not valid yet.
     431             :  */
     432             : static void
     433       17170 : fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
     434             : {
     435       17170 :     Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
     436       17170 :     Oid         language = procedureStruct->prolang;
     437             :     HeapTuple   languageTuple;
     438             :     Form_pg_language languageStruct;
     439             :     FmgrInfo    plfinfo;
     440             : 
     441       17170 :     languageTuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(language));
     442       17170 :     if (!HeapTupleIsValid(languageTuple))
     443           0 :         elog(ERROR, "cache lookup failed for language %u", language);
     444       17170 :     languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
     445             : 
     446             :     /*
     447             :      * Look up the language's call handler function, ignoring any attributes
     448             :      * that would normally cause insertion of fmgr_security_definer.  We need
     449             :      * to get back a bare pointer to the actual C-language function.
     450             :      */
     451       17170 :     fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
     452             :                            CurrentMemoryContext, true);
     453       17170 :     finfo->fn_addr = plfinfo.fn_addr;
     454             : 
     455       17170 :     ReleaseSysCache(languageTuple);
     456       17170 : }
     457             : 
     458             : /*
     459             :  * Fetch and validate the information record for the given external function.
     460             :  * The function is specified by a handle for the containing library
     461             :  * (obtained from load_external_function) as well as the function name.
     462             :  *
     463             :  * If no info function exists for the given name an error is raised.
     464             :  *
     465             :  * This function is broken out of fmgr_info_C_lang so that fmgr_c_validator
     466             :  * can validate the information record for a function not yet entered into
     467             :  * pg_proc.
     468             :  */
     469             : const Pg_finfo_record *
     470        7916 : fetch_finfo_record(void *filehandle, const char *funcname)
     471             : {
     472             :     char       *infofuncname;
     473             :     PGFInfoFunction infofunc;
     474             :     const Pg_finfo_record *inforec;
     475             : 
     476        7916 :     infofuncname = psprintf("pg_finfo_%s", funcname);
     477             : 
     478             :     /* Try to look up the info function */
     479        7916 :     infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
     480             :                                                           infofuncname);
     481        7916 :     if (infofunc == NULL)
     482             :     {
     483           0 :         ereport(ERROR,
     484             :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
     485             :                  errmsg("could not find function information for function \"%s\"",
     486             :                         funcname),
     487             :                  errhint("SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname).")));
     488             :         return NULL;            /* silence compiler */
     489             :     }
     490             : 
     491             :     /* Found, so call it */
     492        7916 :     inforec = (*infofunc) ();
     493             : 
     494             :     /* Validate result as best we can */
     495        7916 :     if (inforec == NULL)
     496           0 :         elog(ERROR, "null result from info function \"%s\"", infofuncname);
     497        7916 :     switch (inforec->api_version)
     498             :     {
     499             :         case 1:
     500             :             /* OK, no additional fields to validate */
     501        7916 :             break;
     502             :         default:
     503           0 :             ereport(ERROR,
     504             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     505             :                      errmsg("unrecognized API version %d reported by info function \"%s\"",
     506             :                             inforec->api_version, infofuncname)));
     507             :             break;
     508             :     }
     509             : 
     510        7916 :     pfree(infofuncname);
     511        7916 :     return inforec;
     512             : }
     513             : 
     514             : 
     515             : /*-------------------------------------------------------------------------
     516             :  *      Routines for caching lookup information for external C functions.
     517             :  *
     518             :  * The routines in dfmgr.c are relatively slow, so we try to avoid running
     519             :  * them more than once per external function per session.  We use a hash table
     520             :  * with the function OID as the lookup key.
     521             :  *-------------------------------------------------------------------------
     522             :  */
     523             : 
     524             : /*
     525             :  * lookup_C_func: try to find a C function in the hash table
     526             :  *
     527             :  * If an entry exists and is up to date, return it; else return NULL
     528             :  */
     529             : static CFuncHashTabEntry *
     530       38172 : lookup_C_func(HeapTuple procedureTuple)
     531             : {
     532       38172 :     Oid         fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
     533             :     CFuncHashTabEntry *entry;
     534             : 
     535       38172 :     if (CFuncHash == NULL)
     536         816 :         return NULL;            /* no table yet */
     537       37356 :     entry = (CFuncHashTabEntry *)
     538       37356 :         hash_search(CFuncHash,
     539             :                     &fn_oid,
     540             :                     HASH_FIND,
     541             :                     NULL);
     542       37356 :     if (entry == NULL)
     543        2502 :         return NULL;            /* no such entry */
     544       69704 :     if (entry->fn_xmin == HeapTupleHeaderGetRawXmin(procedureTuple->t_data) &&
     545       34850 :         ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
     546       34850 :         return entry;           /* OK */
     547           4 :     return NULL;                /* entry is out of date */
     548             : }
     549             : 
     550             : /*
     551             :  * record_C_func: enter (or update) info about a C function in the hash table
     552             :  */
     553             : static void
     554        3322 : record_C_func(HeapTuple procedureTuple,
     555             :               PGFunction user_fn, const Pg_finfo_record *inforec)
     556             : {
     557        3322 :     Oid         fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
     558             :     CFuncHashTabEntry *entry;
     559             :     bool        found;
     560             : 
     561             :     /* Create the hash table if it doesn't exist yet */
     562        3322 :     if (CFuncHash == NULL)
     563             :     {
     564             :         HASHCTL     hash_ctl;
     565             : 
     566         816 :         MemSet(&hash_ctl, 0, sizeof(hash_ctl));
     567         816 :         hash_ctl.keysize = sizeof(Oid);
     568         816 :         hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
     569         816 :         CFuncHash = hash_create("CFuncHash",
     570             :                                 100,
     571             :                                 &hash_ctl,
     572             :                                 HASH_ELEM | HASH_BLOBS);
     573             :     }
     574             : 
     575        3322 :     entry = (CFuncHashTabEntry *)
     576        3322 :         hash_search(CFuncHash,
     577             :                     &fn_oid,
     578             :                     HASH_ENTER,
     579             :                     &found);
     580             :     /* OID is already filled in */
     581        3322 :     entry->fn_xmin = HeapTupleHeaderGetRawXmin(procedureTuple->t_data);
     582        3322 :     entry->fn_tid = procedureTuple->t_self;
     583        3322 :     entry->user_fn = user_fn;
     584        3322 :     entry->inforec = inforec;
     585        3322 : }
     586             : 
     587             : /*
     588             :  * clear_external_function_hash: remove entries for a library being closed
     589             :  *
     590             :  * Presently we just zap the entire hash table, but later it might be worth
     591             :  * the effort to remove only the entries associated with the given handle.
     592             :  */
     593             : void
     594           0 : clear_external_function_hash(void *filehandle)
     595             : {
     596           0 :     if (CFuncHash)
     597           0 :         hash_destroy(CFuncHash);
     598           0 :     CFuncHash = NULL;
     599           0 : }
     600             : 
     601             : 
     602             : /*
     603             :  * Copy an FmgrInfo struct
     604             :  *
     605             :  * This is inherently somewhat bogus since we can't reliably duplicate
     606             :  * language-dependent subsidiary info.  We cheat by zeroing fn_extra,
     607             :  * instead, meaning that subsidiary info will have to be recomputed.
     608             :  */
     609             : void
     610    47980288 : fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
     611             :                MemoryContext destcxt)
     612             : {
     613    47980288 :     memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
     614    47980288 :     dstinfo->fn_mcxt = destcxt;
     615    47980288 :     dstinfo->fn_extra = NULL;
     616    47980288 : }
     617             : 
     618             : 
     619             : /*
     620             :  * Specialized lookup routine for fmgr_internal_validator: given the alleged
     621             :  * name of an internal function, return the OID of the function.
     622             :  * If the name is not recognized, return InvalidOid.
     623             :  */
     624             : Oid
     625        8770 : fmgr_internal_function(const char *proname)
     626             : {
     627        8770 :     const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
     628             : 
     629        8770 :     if (fbp == NULL)
     630           4 :         return InvalidOid;
     631        8766 :     return fbp->foid;
     632             : }
     633             : 
     634             : 
     635             : /*
     636             :  * Support for security-definer and proconfig-using functions.  We support
     637             :  * both of these features using the same call handler, because they are
     638             :  * often used together and it would be inefficient (as well as notationally
     639             :  * messy) to have two levels of call handler involved.
     640             :  */
     641             : struct fmgr_security_definer_cache
     642             : {
     643             :     FmgrInfo    flinfo;         /* lookup info for target function */
     644             :     Oid         userid;         /* userid to set, or InvalidOid */
     645             :     ArrayType  *proconfig;      /* GUC values to set, or NULL */
     646             :     Datum       arg;            /* passthrough argument for plugin modules */
     647             : };
     648             : 
     649             : /*
     650             :  * Function handler for security-definer/proconfig/plugin-hooked functions.
     651             :  * We extract the OID of the actual function and do a fmgr lookup again.
     652             :  * Then we fetch the pg_proc row and copy the owner ID and proconfig fields.
     653             :  * (All this info is cached for the duration of the current query.)
     654             :  * To execute a call, we temporarily replace the flinfo with the cached
     655             :  * and looked-up one, while keeping the outer fcinfo (which contains all
     656             :  * the actual arguments, etc.) intact.  This is not re-entrant, but then
     657             :  * the fcinfo itself can't be used reentrantly anyway.
     658             :  */
     659             : extern Datum
     660          46 : fmgr_security_definer(PG_FUNCTION_ARGS)
     661             : {
     662             :     Datum       result;
     663             :     struct fmgr_security_definer_cache *volatile fcache;
     664             :     FmgrInfo   *save_flinfo;
     665             :     Oid         save_userid;
     666             :     int         save_sec_context;
     667             :     volatile int save_nestlevel;
     668             :     PgStat_FunctionCallUsage fcusage;
     669             : 
     670          46 :     if (!fcinfo->flinfo->fn_extra)
     671             :     {
     672             :         HeapTuple   tuple;
     673             :         Form_pg_proc procedureStruct;
     674             :         Datum       datum;
     675             :         bool        isnull;
     676             :         MemoryContext oldcxt;
     677             : 
     678          46 :         fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
     679             :                                         sizeof(*fcache));
     680             : 
     681          46 :         fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
     682          46 :                                fcinfo->flinfo->fn_mcxt, true);
     683          46 :         fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
     684             : 
     685          46 :         tuple = SearchSysCache1(PROCOID,
     686          46 :                                 ObjectIdGetDatum(fcinfo->flinfo->fn_oid));
     687          46 :         if (!HeapTupleIsValid(tuple))
     688           0 :             elog(ERROR, "cache lookup failed for function %u",
     689             :                  fcinfo->flinfo->fn_oid);
     690          46 :         procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
     691             : 
     692          46 :         if (procedureStruct->prosecdef)
     693          16 :             fcache->userid = procedureStruct->proowner;
     694             : 
     695          46 :         datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
     696             :                                 &isnull);
     697          46 :         if (!isnull)
     698             :         {
     699          30 :             oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
     700          30 :             fcache->proconfig = DatumGetArrayTypePCopy(datum);
     701          30 :             MemoryContextSwitchTo(oldcxt);
     702             :         }
     703             : 
     704          46 :         ReleaseSysCache(tuple);
     705             : 
     706          46 :         fcinfo->flinfo->fn_extra = fcache;
     707             :     }
     708             :     else
     709           0 :         fcache = fcinfo->flinfo->fn_extra;
     710             : 
     711             :     /* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
     712          46 :     GetUserIdAndSecContext(&save_userid, &save_sec_context);
     713          46 :     if (fcache->proconfig)       /* Need a new GUC nesting level */
     714          30 :         save_nestlevel = NewGUCNestLevel();
     715             :     else
     716          16 :         save_nestlevel = 0;     /* keep compiler quiet */
     717             : 
     718          46 :     if (OidIsValid(fcache->userid))
     719          16 :         SetUserIdAndSecContext(fcache->userid,
     720             :                                save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
     721             : 
     722          46 :     if (fcache->proconfig)
     723             :     {
     724          30 :         ProcessGUCArray(fcache->proconfig,
     725          30 :                         (superuser() ? PGC_SUSET : PGC_USERSET),
     726             :                         PGC_S_SESSION,
     727             :                         GUC_ACTION_SAVE);
     728             :     }
     729             : 
     730             :     /* function manager hook */
     731          42 :     if (fmgr_hook)
     732           0 :         (*fmgr_hook) (FHET_START, &fcache->flinfo, &fcache->arg);
     733             : 
     734             :     /*
     735             :      * We don't need to restore GUC or userid settings on error, because the
     736             :      * ensuing xact or subxact abort will do that.  The PG_TRY block is only
     737             :      * needed to clean up the flinfo link.
     738             :      */
     739          42 :     save_flinfo = fcinfo->flinfo;
     740             : 
     741          42 :     PG_TRY();
     742             :     {
     743          42 :         fcinfo->flinfo = &fcache->flinfo;
     744             : 
     745             :         /* See notes in fmgr_info_cxt_security */
     746          42 :         pgstat_init_function_usage(fcinfo, &fcusage);
     747             : 
     748          42 :         result = FunctionCallInvoke(fcinfo);
     749             : 
     750             :         /*
     751             :          * We could be calling either a regular or a set-returning function,
     752             :          * so we have to test to see what finalize flag to use.
     753             :          */
     754          30 :         pgstat_end_function_usage(&fcusage,
     755          30 :                                   (fcinfo->resultinfo == NULL ||
     756          30 :                                    !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
     757           0 :                                    ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
     758             :     }
     759          12 :     PG_CATCH();
     760             :     {
     761          12 :         fcinfo->flinfo = save_flinfo;
     762          12 :         if (fmgr_hook)
     763           0 :             (*fmgr_hook) (FHET_ABORT, &fcache->flinfo, &fcache->arg);
     764          12 :         PG_RE_THROW();
     765             :     }
     766          30 :     PG_END_TRY();
     767             : 
     768          30 :     fcinfo->flinfo = save_flinfo;
     769             : 
     770          30 :     if (fcache->proconfig)
     771          20 :         AtEOXact_GUC(true, save_nestlevel);
     772          30 :     if (OidIsValid(fcache->userid))
     773          10 :         SetUserIdAndSecContext(save_userid, save_sec_context);
     774          30 :     if (fmgr_hook)
     775           0 :         (*fmgr_hook) (FHET_END, &fcache->flinfo, &fcache->arg);
     776             : 
     777          30 :     return result;
     778             : }
     779             : 
     780             : 
     781             : /*-------------------------------------------------------------------------
     782             :  *      Support routines for callers of fmgr-compatible functions
     783             :  *-------------------------------------------------------------------------
     784             :  */
     785             : 
     786             : /*
     787             :  * These are for invocation of a specifically named function with a
     788             :  * directly-computed parameter list.  Note that neither arguments nor result
     789             :  * are allowed to be NULL.  Also, the function cannot be one that needs to
     790             :  * look at FmgrInfo, since there won't be any.
     791             :  */
     792             : Datum
     793     3952578 : DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
     794             : {
     795     3952578 :     LOCAL_FCINFO(fcinfo, 1);
     796             :     Datum       result;
     797             : 
     798     3952578 :     InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
     799             : 
     800     3952578 :     fcinfo->args[0].value = arg1;
     801     3952578 :     fcinfo->args[0].isnull = false;
     802             : 
     803     3952578 :     result = (*func) (fcinfo);
     804             : 
     805             :     /* Check for null result, since caller is clearly not expecting one */
     806     3952568 :     if (fcinfo->isnull)
     807           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     808             : 
     809     3952568 :     return result;
     810             : }
     811             : 
     812             : Datum
     813    26292064 : DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
     814             : {
     815    26292064 :     LOCAL_FCINFO(fcinfo, 2);
     816             :     Datum       result;
     817             : 
     818    26292064 :     InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
     819             : 
     820    26292064 :     fcinfo->args[0].value = arg1;
     821    26292064 :     fcinfo->args[0].isnull = false;
     822    26292064 :     fcinfo->args[1].value = arg2;
     823    26292064 :     fcinfo->args[1].isnull = false;
     824             : 
     825    26292064 :     result = (*func) (fcinfo);
     826             : 
     827             :     /* Check for null result, since caller is clearly not expecting one */
     828    26292056 :     if (fcinfo->isnull)
     829           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     830             : 
     831    26292056 :     return result;
     832             : }
     833             : 
     834             : Datum
     835       27420 : DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     836             :                         Datum arg3)
     837             : {
     838       27420 :     LOCAL_FCINFO(fcinfo, 3);
     839             :     Datum       result;
     840             : 
     841       27420 :     InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL);
     842             : 
     843       27420 :     fcinfo->args[0].value = arg1;
     844       27420 :     fcinfo->args[0].isnull = false;
     845       27420 :     fcinfo->args[1].value = arg2;
     846       27420 :     fcinfo->args[1].isnull = false;
     847       27420 :     fcinfo->args[2].value = arg3;
     848       27420 :     fcinfo->args[2].isnull = false;
     849             : 
     850       27420 :     result = (*func) (fcinfo);
     851             : 
     852             :     /* Check for null result, since caller is clearly not expecting one */
     853       27414 :     if (fcinfo->isnull)
     854           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     855             : 
     856       27414 :     return result;
     857             : }
     858             : 
     859             : Datum
     860         682 : DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     861             :                         Datum arg3, Datum arg4)
     862             : {
     863         682 :     LOCAL_FCINFO(fcinfo, 4);
     864             :     Datum       result;
     865             : 
     866         682 :     InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL);
     867             : 
     868         682 :     fcinfo->args[0].value = arg1;
     869         682 :     fcinfo->args[0].isnull = false;
     870         682 :     fcinfo->args[1].value = arg2;
     871         682 :     fcinfo->args[1].isnull = false;
     872         682 :     fcinfo->args[2].value = arg3;
     873         682 :     fcinfo->args[2].isnull = false;
     874         682 :     fcinfo->args[3].value = arg4;
     875         682 :     fcinfo->args[3].isnull = false;
     876             : 
     877         682 :     result = (*func) (fcinfo);
     878             : 
     879             :     /* Check for null result, since caller is clearly not expecting one */
     880         682 :     if (fcinfo->isnull)
     881           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     882             : 
     883         682 :     return result;
     884             : }
     885             : 
     886             : Datum
     887        2588 : DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     888             :                         Datum arg3, Datum arg4, Datum arg5)
     889             : {
     890        2588 :     LOCAL_FCINFO(fcinfo, 5);
     891             :     Datum       result;
     892             : 
     893        2588 :     InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL);
     894             : 
     895        2588 :     fcinfo->args[0].value = arg1;
     896        2588 :     fcinfo->args[0].isnull = false;
     897        2588 :     fcinfo->args[1].value = arg2;
     898        2588 :     fcinfo->args[1].isnull = false;
     899        2588 :     fcinfo->args[2].value = arg3;
     900        2588 :     fcinfo->args[2].isnull = false;
     901        2588 :     fcinfo->args[3].value = arg4;
     902        2588 :     fcinfo->args[3].isnull = false;
     903        2588 :     fcinfo->args[4].value = arg5;
     904        2588 :     fcinfo->args[4].isnull = false;
     905             : 
     906        2588 :     result = (*func) (fcinfo);
     907             : 
     908             :     /* Check for null result, since caller is clearly not expecting one */
     909        2584 :     if (fcinfo->isnull)
     910           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     911             : 
     912        2584 :     return result;
     913             : }
     914             : 
     915             : Datum
     916           0 : DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     917             :                         Datum arg3, Datum arg4, Datum arg5,
     918             :                         Datum arg6)
     919             : {
     920           0 :     LOCAL_FCINFO(fcinfo, 6);
     921             :     Datum       result;
     922             : 
     923           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL);
     924             : 
     925           0 :     fcinfo->args[0].value = arg1;
     926           0 :     fcinfo->args[0].isnull = false;
     927           0 :     fcinfo->args[1].value = arg2;
     928           0 :     fcinfo->args[1].isnull = false;
     929           0 :     fcinfo->args[2].value = arg3;
     930           0 :     fcinfo->args[2].isnull = false;
     931           0 :     fcinfo->args[3].value = arg4;
     932           0 :     fcinfo->args[3].isnull = false;
     933           0 :     fcinfo->args[4].value = arg5;
     934           0 :     fcinfo->args[4].isnull = false;
     935           0 :     fcinfo->args[5].value = arg6;
     936           0 :     fcinfo->args[5].isnull = false;
     937             : 
     938           0 :     result = (*func) (fcinfo);
     939             : 
     940             :     /* Check for null result, since caller is clearly not expecting one */
     941           0 :     if (fcinfo->isnull)
     942           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     943             : 
     944           0 :     return result;
     945             : }
     946             : 
     947             : Datum
     948           0 : DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     949             :                         Datum arg3, Datum arg4, Datum arg5,
     950             :                         Datum arg6, Datum arg7)
     951             : {
     952           0 :     LOCAL_FCINFO(fcinfo, 7);
     953             :     Datum       result;
     954             : 
     955           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL);
     956             : 
     957           0 :     fcinfo->args[0].value = arg1;
     958           0 :     fcinfo->args[0].isnull = false;
     959           0 :     fcinfo->args[1].value = arg2;
     960           0 :     fcinfo->args[1].isnull = false;
     961           0 :     fcinfo->args[2].value = arg3;
     962           0 :     fcinfo->args[2].isnull = false;
     963           0 :     fcinfo->args[3].value = arg4;
     964           0 :     fcinfo->args[3].isnull = false;
     965           0 :     fcinfo->args[4].value = arg5;
     966           0 :     fcinfo->args[4].isnull = false;
     967           0 :     fcinfo->args[5].value = arg6;
     968           0 :     fcinfo->args[5].isnull = false;
     969           0 :     fcinfo->args[6].value = arg7;
     970           0 :     fcinfo->args[6].isnull = false;
     971             : 
     972           0 :     result = (*func) (fcinfo);
     973             : 
     974             :     /* Check for null result, since caller is clearly not expecting one */
     975           0 :     if (fcinfo->isnull)
     976           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
     977             : 
     978           0 :     return result;
     979             : }
     980             : 
     981             : Datum
     982           0 : DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
     983             :                         Datum arg3, Datum arg4, Datum arg5,
     984             :                         Datum arg6, Datum arg7, Datum arg8)
     985             : {
     986           0 :     LOCAL_FCINFO(fcinfo, 8);
     987             :     Datum       result;
     988             : 
     989           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL);
     990             : 
     991           0 :     fcinfo->args[0].value = arg1;
     992           0 :     fcinfo->args[0].isnull = false;
     993           0 :     fcinfo->args[1].value = arg2;
     994           0 :     fcinfo->args[1].isnull = false;
     995           0 :     fcinfo->args[2].value = arg3;
     996           0 :     fcinfo->args[2].isnull = false;
     997           0 :     fcinfo->args[3].value = arg4;
     998           0 :     fcinfo->args[3].isnull = false;
     999           0 :     fcinfo->args[4].value = arg5;
    1000           0 :     fcinfo->args[4].isnull = false;
    1001           0 :     fcinfo->args[5].value = arg6;
    1002           0 :     fcinfo->args[5].isnull = false;
    1003           0 :     fcinfo->args[6].value = arg7;
    1004           0 :     fcinfo->args[6].isnull = false;
    1005           0 :     fcinfo->args[7].value = arg8;
    1006           0 :     fcinfo->args[7].isnull = false;
    1007             : 
    1008           0 :     result = (*func) (fcinfo);
    1009             : 
    1010             :     /* Check for null result, since caller is clearly not expecting one */
    1011           0 :     if (fcinfo->isnull)
    1012           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
    1013             : 
    1014           0 :     return result;
    1015             : }
    1016             : 
    1017             : Datum
    1018           0 : DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
    1019             :                         Datum arg3, Datum arg4, Datum arg5,
    1020             :                         Datum arg6, Datum arg7, Datum arg8,
    1021             :                         Datum arg9)
    1022             : {
    1023           0 :     LOCAL_FCINFO(fcinfo, 9);
    1024             :     Datum       result;
    1025             : 
    1026           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL);
    1027             : 
    1028           0 :     fcinfo->args[0].value = arg1;
    1029           0 :     fcinfo->args[0].isnull = false;
    1030           0 :     fcinfo->args[1].value = arg2;
    1031           0 :     fcinfo->args[1].isnull = false;
    1032           0 :     fcinfo->args[2].value = arg3;
    1033           0 :     fcinfo->args[2].isnull = false;
    1034           0 :     fcinfo->args[3].value = arg4;
    1035           0 :     fcinfo->args[3].isnull = false;
    1036           0 :     fcinfo->args[4].value = arg5;
    1037           0 :     fcinfo->args[4].isnull = false;
    1038           0 :     fcinfo->args[5].value = arg6;
    1039           0 :     fcinfo->args[5].isnull = false;
    1040           0 :     fcinfo->args[6].value = arg7;
    1041           0 :     fcinfo->args[6].isnull = false;
    1042           0 :     fcinfo->args[7].value = arg8;
    1043           0 :     fcinfo->args[7].isnull = false;
    1044           0 :     fcinfo->args[8].value = arg9;
    1045           0 :     fcinfo->args[8].isnull = false;
    1046             : 
    1047           0 :     result = (*func) (fcinfo);
    1048             : 
    1049             :     /* Check for null result, since caller is clearly not expecting one */
    1050           0 :     if (fcinfo->isnull)
    1051           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
    1052             : 
    1053           0 :     return result;
    1054             : }
    1055             : 
    1056             : /*
    1057             :  * These functions work like the DirectFunctionCall functions except that
    1058             :  * they use the flinfo parameter to initialise the fcinfo for the call.
    1059             :  * It's recommended that the callee only use the fn_extra and fn_mcxt
    1060             :  * fields, as other fields will typically describe the calling function
    1061             :  * not the callee.  Conversely, the calling function should not have
    1062             :  * used fn_extra, unless its use is known to be compatible with the callee's.
    1063             :  */
    1064             : 
    1065             : Datum
    1066           0 : CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
    1067             : {
    1068           0 :     LOCAL_FCINFO(fcinfo, 1);
    1069             :     Datum       result;
    1070             : 
    1071           0 :     InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
    1072             : 
    1073           0 :     fcinfo->args[0].value = arg1;
    1074           0 :     fcinfo->args[0].isnull = false;
    1075             : 
    1076           0 :     result = (*func) (fcinfo);
    1077             : 
    1078             :     /* Check for null result, since caller is clearly not expecting one */
    1079           0 :     if (fcinfo->isnull)
    1080           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
    1081             : 
    1082           0 :     return result;
    1083             : }
    1084             : 
    1085             : Datum
    1086      410042 : CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
    1087             : {
    1088      410042 :     LOCAL_FCINFO(fcinfo, 2);
    1089             :     Datum       result;
    1090             : 
    1091      410042 :     InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
    1092             : 
    1093      410042 :     fcinfo->args[0].value = arg1;
    1094      410042 :     fcinfo->args[0].isnull = false;
    1095      410042 :     fcinfo->args[1].value = arg2;
    1096      410042 :     fcinfo->args[1].isnull = false;
    1097             : 
    1098      410042 :     result = (*func) (fcinfo);
    1099             : 
    1100             :     /* Check for null result, since caller is clearly not expecting one */
    1101      410042 :     if (fcinfo->isnull)
    1102           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
    1103             : 
    1104      410042 :     return result;
    1105             : }
    1106             : 
    1107             : /*
    1108             :  * These are for invocation of a previously-looked-up function with a
    1109             :  * directly-computed parameter list.  Note that neither arguments nor result
    1110             :  * are allowed to be NULL.
    1111             :  */
    1112             : Datum
    1113     1779044 : FunctionCall0Coll(FmgrInfo *flinfo, Oid collation)
    1114             : {
    1115     1779044 :     LOCAL_FCINFO(fcinfo, 0);
    1116             :     Datum       result;
    1117             : 
    1118     1779044 :     InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL);
    1119             : 
    1120     1779044 :     result = FunctionCallInvoke(fcinfo);
    1121             : 
    1122             :     /* Check for null result, since caller is clearly not expecting one */
    1123     1779044 :     if (fcinfo->isnull)
    1124           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1125             : 
    1126     1779044 :     return result;
    1127             : }
    1128             : 
    1129             : Datum
    1130    46222188 : FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
    1131             : {
    1132    46222188 :     LOCAL_FCINFO(fcinfo, 1);
    1133             :     Datum       result;
    1134             : 
    1135    46222188 :     InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
    1136             : 
    1137    46222188 :     fcinfo->args[0].value = arg1;
    1138    46222188 :     fcinfo->args[0].isnull = false;
    1139             : 
    1140    46222188 :     result = FunctionCallInvoke(fcinfo);
    1141             : 
    1142             :     /* Check for null result, since caller is clearly not expecting one */
    1143    46221766 :     if (fcinfo->isnull)
    1144           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1145             : 
    1146    46221766 :     return result;
    1147             : }
    1148             : 
    1149             : Datum
    1150   664042384 : FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
    1151             : {
    1152   664042384 :     LOCAL_FCINFO(fcinfo, 2);
    1153             :     Datum       result;
    1154             : 
    1155   664042384 :     InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
    1156             : 
    1157   664042384 :     fcinfo->args[0].value = arg1;
    1158   664042384 :     fcinfo->args[0].isnull = false;
    1159   664042384 :     fcinfo->args[1].value = arg2;
    1160   664042384 :     fcinfo->args[1].isnull = false;
    1161             : 
    1162   664042384 :     result = FunctionCallInvoke(fcinfo);
    1163             : 
    1164             :     /* Check for null result, since caller is clearly not expecting one */
    1165   664042302 :     if (fcinfo->isnull)
    1166           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1167             : 
    1168   664042302 :     return result;
    1169             : }
    1170             : 
    1171             : Datum
    1172    30730990 : FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1173             :                   Datum arg3)
    1174             : {
    1175    30730990 :     LOCAL_FCINFO(fcinfo, 3);
    1176             :     Datum       result;
    1177             : 
    1178    30730990 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
    1179             : 
    1180    30730990 :     fcinfo->args[0].value = arg1;
    1181    30730990 :     fcinfo->args[0].isnull = false;
    1182    30730990 :     fcinfo->args[1].value = arg2;
    1183    30730990 :     fcinfo->args[1].isnull = false;
    1184    30730990 :     fcinfo->args[2].value = arg3;
    1185    30730990 :     fcinfo->args[2].isnull = false;
    1186             : 
    1187    30730990 :     result = FunctionCallInvoke(fcinfo);
    1188             : 
    1189             :     /* Check for null result, since caller is clearly not expecting one */
    1190    30730990 :     if (fcinfo->isnull)
    1191           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1192             : 
    1193    30730990 :     return result;
    1194             : }
    1195             : 
    1196             : Datum
    1197      682064 : FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1198             :                   Datum arg3, Datum arg4)
    1199             : {
    1200      682064 :     LOCAL_FCINFO(fcinfo, 4);
    1201             :     Datum       result;
    1202             : 
    1203      682064 :     InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL);
    1204             : 
    1205      682064 :     fcinfo->args[0].value = arg1;
    1206      682064 :     fcinfo->args[0].isnull = false;
    1207      682064 :     fcinfo->args[1].value = arg2;
    1208      682064 :     fcinfo->args[1].isnull = false;
    1209      682064 :     fcinfo->args[2].value = arg3;
    1210      682064 :     fcinfo->args[2].isnull = false;
    1211      682064 :     fcinfo->args[3].value = arg4;
    1212      682064 :     fcinfo->args[3].isnull = false;
    1213             : 
    1214      682064 :     result = FunctionCallInvoke(fcinfo);
    1215             : 
    1216             :     /* Check for null result, since caller is clearly not expecting one */
    1217      682064 :     if (fcinfo->isnull)
    1218           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1219             : 
    1220      682064 :     return result;
    1221             : }
    1222             : 
    1223             : Datum
    1224      908704 : FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1225             :                   Datum arg3, Datum arg4, Datum arg5)
    1226             : {
    1227      908704 :     LOCAL_FCINFO(fcinfo, 5);
    1228             :     Datum       result;
    1229             : 
    1230      908704 :     InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL);
    1231             : 
    1232      908704 :     fcinfo->args[0].value = arg1;
    1233      908704 :     fcinfo->args[0].isnull = false;
    1234      908704 :     fcinfo->args[1].value = arg2;
    1235      908704 :     fcinfo->args[1].isnull = false;
    1236      908704 :     fcinfo->args[2].value = arg3;
    1237      908704 :     fcinfo->args[2].isnull = false;
    1238      908704 :     fcinfo->args[3].value = arg4;
    1239      908704 :     fcinfo->args[3].isnull = false;
    1240      908704 :     fcinfo->args[4].value = arg5;
    1241      908704 :     fcinfo->args[4].isnull = false;
    1242             : 
    1243      908704 :     result = FunctionCallInvoke(fcinfo);
    1244             : 
    1245             :     /* Check for null result, since caller is clearly not expecting one */
    1246      908680 :     if (fcinfo->isnull)
    1247           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1248             : 
    1249      908680 :     return result;
    1250             : }
    1251             : 
    1252             : Datum
    1253           0 : FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1254             :                   Datum arg3, Datum arg4, Datum arg5,
    1255             :                   Datum arg6)
    1256             : {
    1257           0 :     LOCAL_FCINFO(fcinfo, 6);
    1258             :     Datum       result;
    1259             : 
    1260           0 :     InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL);
    1261             : 
    1262           0 :     fcinfo->args[0].value = arg1;
    1263           0 :     fcinfo->args[0].isnull = false;
    1264           0 :     fcinfo->args[1].value = arg2;
    1265           0 :     fcinfo->args[1].isnull = false;
    1266           0 :     fcinfo->args[2].value = arg3;
    1267           0 :     fcinfo->args[2].isnull = false;
    1268           0 :     fcinfo->args[3].value = arg4;
    1269           0 :     fcinfo->args[3].isnull = false;
    1270           0 :     fcinfo->args[4].value = arg5;
    1271           0 :     fcinfo->args[4].isnull = false;
    1272           0 :     fcinfo->args[5].value = arg6;
    1273           0 :     fcinfo->args[5].isnull = false;
    1274             : 
    1275           0 :     result = FunctionCallInvoke(fcinfo);
    1276             : 
    1277             :     /* Check for null result, since caller is clearly not expecting one */
    1278           0 :     if (fcinfo->isnull)
    1279           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1280             : 
    1281           0 :     return result;
    1282             : }
    1283             : 
    1284             : Datum
    1285      445696 : FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1286             :                   Datum arg3, Datum arg4, Datum arg5,
    1287             :                   Datum arg6, Datum arg7)
    1288             : {
    1289      445696 :     LOCAL_FCINFO(fcinfo, 7);
    1290             :     Datum       result;
    1291             : 
    1292      445696 :     InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL);
    1293             : 
    1294      445696 :     fcinfo->args[0].value = arg1;
    1295      445696 :     fcinfo->args[0].isnull = false;
    1296      445696 :     fcinfo->args[1].value = arg2;
    1297      445696 :     fcinfo->args[1].isnull = false;
    1298      445696 :     fcinfo->args[2].value = arg3;
    1299      445696 :     fcinfo->args[2].isnull = false;
    1300      445696 :     fcinfo->args[3].value = arg4;
    1301      445696 :     fcinfo->args[3].isnull = false;
    1302      445696 :     fcinfo->args[4].value = arg5;
    1303      445696 :     fcinfo->args[4].isnull = false;
    1304      445696 :     fcinfo->args[5].value = arg6;
    1305      445696 :     fcinfo->args[5].isnull = false;
    1306      445696 :     fcinfo->args[6].value = arg7;
    1307      445696 :     fcinfo->args[6].isnull = false;
    1308             : 
    1309      445696 :     result = FunctionCallInvoke(fcinfo);
    1310             : 
    1311             :     /* Check for null result, since caller is clearly not expecting one */
    1312      445696 :     if (fcinfo->isnull)
    1313           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1314             : 
    1315      445696 :     return result;
    1316             : }
    1317             : 
    1318             : Datum
    1319       36590 : FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1320             :                   Datum arg3, Datum arg4, Datum arg5,
    1321             :                   Datum arg6, Datum arg7, Datum arg8)
    1322             : {
    1323       36590 :     LOCAL_FCINFO(fcinfo, 8);
    1324             :     Datum       result;
    1325             : 
    1326       36590 :     InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL);
    1327             : 
    1328       36590 :     fcinfo->args[0].value = arg1;
    1329       36590 :     fcinfo->args[0].isnull = false;
    1330       36590 :     fcinfo->args[1].value = arg2;
    1331       36590 :     fcinfo->args[1].isnull = false;
    1332       36590 :     fcinfo->args[2].value = arg3;
    1333       36590 :     fcinfo->args[2].isnull = false;
    1334       36590 :     fcinfo->args[3].value = arg4;
    1335       36590 :     fcinfo->args[3].isnull = false;
    1336       36590 :     fcinfo->args[4].value = arg5;
    1337       36590 :     fcinfo->args[4].isnull = false;
    1338       36590 :     fcinfo->args[5].value = arg6;
    1339       36590 :     fcinfo->args[5].isnull = false;
    1340       36590 :     fcinfo->args[6].value = arg7;
    1341       36590 :     fcinfo->args[6].isnull = false;
    1342       36590 :     fcinfo->args[7].value = arg8;
    1343       36590 :     fcinfo->args[7].isnull = false;
    1344             : 
    1345       36590 :     result = FunctionCallInvoke(fcinfo);
    1346             : 
    1347             :     /* Check for null result, since caller is clearly not expecting one */
    1348       36590 :     if (fcinfo->isnull)
    1349           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1350             : 
    1351       36590 :     return result;
    1352             : }
    1353             : 
    1354             : Datum
    1355           0 : FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
    1356             :                   Datum arg3, Datum arg4, Datum arg5,
    1357             :                   Datum arg6, Datum arg7, Datum arg8,
    1358             :                   Datum arg9)
    1359             : {
    1360           0 :     LOCAL_FCINFO(fcinfo, 9);
    1361             :     Datum       result;
    1362             : 
    1363           0 :     InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL);
    1364             : 
    1365           0 :     fcinfo->args[0].value = arg1;
    1366           0 :     fcinfo->args[0].isnull = false;
    1367           0 :     fcinfo->args[1].value = arg2;
    1368           0 :     fcinfo->args[1].isnull = false;
    1369           0 :     fcinfo->args[2].value = arg3;
    1370           0 :     fcinfo->args[2].isnull = false;
    1371           0 :     fcinfo->args[3].value = arg4;
    1372           0 :     fcinfo->args[3].isnull = false;
    1373           0 :     fcinfo->args[4].value = arg5;
    1374           0 :     fcinfo->args[4].isnull = false;
    1375           0 :     fcinfo->args[5].value = arg6;
    1376           0 :     fcinfo->args[5].isnull = false;
    1377           0 :     fcinfo->args[6].value = arg7;
    1378           0 :     fcinfo->args[6].isnull = false;
    1379           0 :     fcinfo->args[7].value = arg8;
    1380           0 :     fcinfo->args[7].isnull = false;
    1381           0 :     fcinfo->args[8].value = arg9;
    1382           0 :     fcinfo->args[8].isnull = false;
    1383             : 
    1384           0 :     result = FunctionCallInvoke(fcinfo);
    1385             : 
    1386             :     /* Check for null result, since caller is clearly not expecting one */
    1387           0 :     if (fcinfo->isnull)
    1388           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
    1389             : 
    1390           0 :     return result;
    1391             : }
    1392             : 
    1393             : 
    1394             : /*
    1395             :  * These are for invocation of a function identified by OID with a
    1396             :  * directly-computed parameter list.  Note that neither arguments nor result
    1397             :  * are allowed to be NULL.  These are essentially fmgr_info() followed
    1398             :  * by FunctionCallN().  If the same function is to be invoked repeatedly,
    1399             :  * do the fmgr_info() once and then use FunctionCallN().
    1400             :  */
    1401             : Datum
    1402     1779044 : OidFunctionCall0Coll(Oid functionId, Oid collation)
    1403             : {
    1404             :     FmgrInfo    flinfo;
    1405             : 
    1406     1779044 :     fmgr_info(functionId, &flinfo);
    1407             : 
    1408     1779044 :     return FunctionCall0Coll(&flinfo, collation);
    1409             : }
    1410             : 
    1411             : Datum
    1412     1648366 : OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
    1413             : {
    1414             :     FmgrInfo    flinfo;
    1415             : 
    1416     1648366 :     fmgr_info(functionId, &flinfo);
    1417             : 
    1418     1648366 :     return FunctionCall1Coll(&flinfo, collation, arg1);
    1419             : }
    1420             : 
    1421             : Datum
    1422         576 : OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
    1423             : {
    1424             :     FmgrInfo    flinfo;
    1425             : 
    1426         576 :     fmgr_info(functionId, &flinfo);
    1427             : 
    1428         576 :     return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
    1429             : }
    1430             : 
    1431             : Datum
    1432           4 : OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1433             :                      Datum arg3)
    1434             : {
    1435             :     FmgrInfo    flinfo;
    1436             : 
    1437           4 :     fmgr_info(functionId, &flinfo);
    1438             : 
    1439           4 :     return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
    1440             : }
    1441             : 
    1442             : Datum
    1443      322170 : OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1444             :                      Datum arg3, Datum arg4)
    1445             : {
    1446             :     FmgrInfo    flinfo;
    1447             : 
    1448      322170 :     fmgr_info(functionId, &flinfo);
    1449             : 
    1450      322170 :     return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
    1451             : }
    1452             : 
    1453             : Datum
    1454      115716 : OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1455             :                      Datum arg3, Datum arg4, Datum arg5)
    1456             : {
    1457             :     FmgrInfo    flinfo;
    1458             : 
    1459      115716 :     fmgr_info(functionId, &flinfo);
    1460             : 
    1461      115716 :     return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
    1462             : }
    1463             : 
    1464             : Datum
    1465           0 : OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1466             :                      Datum arg3, Datum arg4, Datum arg5,
    1467             :                      Datum arg6)
    1468             : {
    1469             :     FmgrInfo    flinfo;
    1470             : 
    1471           0 :     fmgr_info(functionId, &flinfo);
    1472             : 
    1473           0 :     return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
    1474             :                              arg6);
    1475             : }
    1476             : 
    1477             : Datum
    1478        1122 : OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1479             :                      Datum arg3, Datum arg4, Datum arg5,
    1480             :                      Datum arg6, Datum arg7)
    1481             : {
    1482             :     FmgrInfo    flinfo;
    1483             : 
    1484        1122 :     fmgr_info(functionId, &flinfo);
    1485             : 
    1486        1122 :     return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
    1487             :                              arg6, arg7);
    1488             : }
    1489             : 
    1490             : Datum
    1491           0 : OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1492             :                      Datum arg3, Datum arg4, Datum arg5,
    1493             :                      Datum arg6, Datum arg7, Datum arg8)
    1494             : {
    1495             :     FmgrInfo    flinfo;
    1496             : 
    1497           0 :     fmgr_info(functionId, &flinfo);
    1498             : 
    1499           0 :     return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
    1500             :                              arg6, arg7, arg8);
    1501             : }
    1502             : 
    1503             : Datum
    1504           0 : OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
    1505             :                      Datum arg3, Datum arg4, Datum arg5,
    1506             :                      Datum arg6, Datum arg7, Datum arg8,
    1507             :                      Datum arg9)
    1508             : {
    1509             :     FmgrInfo    flinfo;
    1510             : 
    1511           0 :     fmgr_info(functionId, &flinfo);
    1512             : 
    1513           0 :     return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
    1514             :                              arg6, arg7, arg8, arg9);
    1515             : }
    1516             : 
    1517             : 
    1518             : /*
    1519             :  * Special cases for convenient invocation of datatype I/O functions.
    1520             :  */
    1521             : 
    1522             : /*
    1523             :  * Call a previously-looked-up datatype input function.
    1524             :  *
    1525             :  * "str" may be NULL to indicate we are reading a NULL.  In this case
    1526             :  * the caller should assume the result is NULL, but we'll call the input
    1527             :  * function anyway if it's not strict.  So this is almost but not quite
    1528             :  * the same as FunctionCall3.
    1529             :  */
    1530             : Datum
    1531    43888156 : InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
    1532             : {
    1533    43888156 :     LOCAL_FCINFO(fcinfo, 3);
    1534             :     Datum       result;
    1535             : 
    1536    43888156 :     if (str == NULL && flinfo->fn_strict)
    1537      177092 :         return (Datum) 0;       /* just return null result */
    1538             : 
    1539    43711064 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
    1540             : 
    1541    43711064 :     fcinfo->args[0].value = CStringGetDatum(str);
    1542    43711064 :     fcinfo->args[0].isnull = false;
    1543    43711064 :     fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
    1544    43711064 :     fcinfo->args[1].isnull = false;
    1545    43711064 :     fcinfo->args[2].value = Int32GetDatum(typmod);
    1546    43711064 :     fcinfo->args[2].isnull = false;
    1547             : 
    1548    43711064 :     result = FunctionCallInvoke(fcinfo);
    1549             : 
    1550             :     /* Should get null result if and only if str is NULL */
    1551    43709112 :     if (str == NULL)
    1552             :     {
    1553          24 :         if (!fcinfo->isnull)
    1554           0 :             elog(ERROR, "input function %u returned non-NULL",
    1555             :                  flinfo->fn_oid);
    1556             :     }
    1557             :     else
    1558             :     {
    1559    43709088 :         if (fcinfo->isnull)
    1560           0 :             elog(ERROR, "input function %u returned NULL",
    1561             :                  flinfo->fn_oid);
    1562             :     }
    1563             : 
    1564    43709112 :     return result;
    1565             : }
    1566             : 
    1567             : /*
    1568             :  * Call a previously-looked-up datatype output function.
    1569             :  *
    1570             :  * Do not call this on NULL datums.
    1571             :  *
    1572             :  * This is currently little more than window dressing for FunctionCall1.
    1573             :  */
    1574             : char *
    1575    13631354 : OutputFunctionCall(FmgrInfo *flinfo, Datum val)
    1576             : {
    1577    13631354 :     return DatumGetCString(FunctionCall1(flinfo, val));
    1578             : }
    1579             : 
    1580             : /*
    1581             :  * Call a previously-looked-up datatype binary-input function.
    1582             :  *
    1583             :  * "buf" may be NULL to indicate we are reading a NULL.  In this case
    1584             :  * the caller should assume the result is NULL, but we'll call the receive
    1585             :  * function anyway if it's not strict.  So this is almost but not quite
    1586             :  * the same as FunctionCall3.
    1587             :  */
    1588             : Datum
    1589        2498 : ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
    1590             :                     Oid typioparam, int32 typmod)
    1591             : {
    1592        2498 :     LOCAL_FCINFO(fcinfo, 3);
    1593             :     Datum       result;
    1594             : 
    1595        2498 :     if (buf == NULL && flinfo->fn_strict)
    1596          20 :         return (Datum) 0;       /* just return null result */
    1597             : 
    1598        2478 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
    1599             : 
    1600        2478 :     fcinfo->args[0].value = PointerGetDatum(buf);
    1601        2478 :     fcinfo->args[0].isnull = false;
    1602        2478 :     fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
    1603        2478 :     fcinfo->args[1].isnull = false;
    1604        2478 :     fcinfo->args[2].value = Int32GetDatum(typmod);
    1605        2478 :     fcinfo->args[2].isnull = false;
    1606             : 
    1607        2478 :     result = FunctionCallInvoke(fcinfo);
    1608             : 
    1609             :     /* Should get null result if and only if buf is NULL */
    1610        2478 :     if (buf == NULL)
    1611             :     {
    1612           0 :         if (!fcinfo->isnull)
    1613           0 :             elog(ERROR, "receive function %u returned non-NULL",
    1614             :                  flinfo->fn_oid);
    1615             :     }
    1616             :     else
    1617             :     {
    1618        2478 :         if (fcinfo->isnull)
    1619           0 :             elog(ERROR, "receive function %u returned NULL",
    1620             :                  flinfo->fn_oid);
    1621             :     }
    1622             : 
    1623        2478 :     return result;
    1624             : }
    1625             : 
    1626             : /*
    1627             :  * Call a previously-looked-up datatype binary-output function.
    1628             :  *
    1629             :  * Do not call this on NULL datums.
    1630             :  *
    1631             :  * This is little more than window dressing for FunctionCall1, but it does
    1632             :  * guarantee a non-toasted result, which strictly speaking the underlying
    1633             :  * function doesn't.
    1634             :  */
    1635             : bytea *
    1636       10846 : SendFunctionCall(FmgrInfo *flinfo, Datum val)
    1637             : {
    1638       10846 :     return DatumGetByteaP(FunctionCall1(flinfo, val));
    1639             : }
    1640             : 
    1641             : /*
    1642             :  * As above, for I/O functions identified by OID.  These are only to be used
    1643             :  * in seldom-executed code paths.  They are not only slow but leak memory.
    1644             :  */
    1645             : Datum
    1646    32373198 : OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
    1647             : {
    1648             :     FmgrInfo    flinfo;
    1649             : 
    1650    32373198 :     fmgr_info(functionId, &flinfo);
    1651    32373198 :     return InputFunctionCall(&flinfo, str, typioparam, typmod);
    1652             : }
    1653             : 
    1654             : char *
    1655      493238 : OidOutputFunctionCall(Oid functionId, Datum val)
    1656             : {
    1657             :     FmgrInfo    flinfo;
    1658             : 
    1659      493238 :     fmgr_info(functionId, &flinfo);
    1660      493238 :     return OutputFunctionCall(&flinfo, val);
    1661             : }
    1662             : 
    1663             : Datum
    1664        2414 : OidReceiveFunctionCall(Oid functionId, StringInfo buf,
    1665             :                        Oid typioparam, int32 typmod)
    1666             : {
    1667             :     FmgrInfo    flinfo;
    1668             : 
    1669        2414 :     fmgr_info(functionId, &flinfo);
    1670        2414 :     return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
    1671             : }
    1672             : 
    1673             : bytea *
    1674        1228 : OidSendFunctionCall(Oid functionId, Datum val)
    1675             : {
    1676             :     FmgrInfo    flinfo;
    1677             : 
    1678        1228 :     fmgr_info(functionId, &flinfo);
    1679        1228 :     return SendFunctionCall(&flinfo, val);
    1680             : }
    1681             : 
    1682             : 
    1683             : /*-------------------------------------------------------------------------
    1684             :  *      Support routines for standard maybe-pass-by-reference datatypes
    1685             :  *
    1686             :  * int8, float4, and float8 can be passed by value if Datum is wide enough.
    1687             :  * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
    1688             :  * at compile time even if pass-by-val is possible.)
    1689             :  *
    1690             :  * Note: there is only one switch controlling the pass-by-value option for
    1691             :  * both int8 and float8; this is to avoid making things unduly complicated
    1692             :  * for the timestamp types, which might have either representation.
    1693             :  *-------------------------------------------------------------------------
    1694             :  */
    1695             : 
    1696             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    1697             : 
    1698             : Datum
    1699             : Int64GetDatum(int64 X)
    1700             : {
    1701             :     int64      *retval = (int64 *) palloc(sizeof(int64));
    1702             : 
    1703             :     *retval = X;
    1704             :     return PointerGetDatum(retval);
    1705             : }
    1706             : #endif                          /* USE_FLOAT8_BYVAL */
    1707             : 
    1708             : #ifndef USE_FLOAT4_BYVAL
    1709             : 
    1710             : Datum
    1711             : Float4GetDatum(float4 X)
    1712             : {
    1713             :     float4     *retval = (float4 *) palloc(sizeof(float4));
    1714             : 
    1715             :     *retval = X;
    1716             :     return PointerGetDatum(retval);
    1717             : }
    1718             : #endif
    1719             : 
    1720             : #ifndef USE_FLOAT8_BYVAL
    1721             : 
    1722             : Datum
    1723             : Float8GetDatum(float8 X)
    1724             : {
    1725             :     float8     *retval = (float8 *) palloc(sizeof(float8));
    1726             : 
    1727             :     *retval = X;
    1728             :     return PointerGetDatum(retval);
    1729             : }
    1730             : #endif
    1731             : 
    1732             : 
    1733             : /*-------------------------------------------------------------------------
    1734             :  *      Support routines for toastable datatypes
    1735             :  *-------------------------------------------------------------------------
    1736             :  */
    1737             : 
    1738             : struct varlena *
    1739    53377172 : pg_detoast_datum(struct varlena *datum)
    1740             : {
    1741    53377172 :     if (VARATT_IS_EXTENDED(datum))
    1742    16443538 :         return detoast_attr(datum);
    1743             :     else
    1744    36933634 :         return datum;
    1745             : }
    1746             : 
    1747             : struct varlena *
    1748     3634298 : pg_detoast_datum_copy(struct varlena *datum)
    1749             : {
    1750     3634298 :     if (VARATT_IS_EXTENDED(datum))
    1751     1837812 :         return detoast_attr(datum);
    1752             :     else
    1753             :     {
    1754             :         /* Make a modifiable copy of the varlena object */
    1755     1796486 :         Size        len = VARSIZE(datum);
    1756     1796486 :         struct varlena *result = (struct varlena *) palloc(len);
    1757             : 
    1758     1796486 :         memcpy(result, datum, len);
    1759     1796486 :         return result;
    1760             :     }
    1761             : }
    1762             : 
    1763             : struct varlena *
    1764         152 : pg_detoast_datum_slice(struct varlena *datum, int32 first, int32 count)
    1765             : {
    1766             :     /* Only get the specified portion from the toast rel */
    1767         152 :     return detoast_attr_slice(datum, first, count);
    1768             : }
    1769             : 
    1770             : struct varlena *
    1771   201737792 : pg_detoast_datum_packed(struct varlena *datum)
    1772             : {
    1773   201737792 :     if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
    1774       65746 :         return detoast_attr(datum);
    1775             :     else
    1776   201672046 :         return datum;
    1777             : }
    1778             : 
    1779             : /*-------------------------------------------------------------------------
    1780             :  *      Support routines for extracting info from fn_expr parse tree
    1781             :  *
    1782             :  * These are needed by polymorphic functions, which accept multiple possible
    1783             :  * input types and need help from the parser to know what they've got.
    1784             :  * Also, some functions might be interested in whether a parameter is constant.
    1785             :  * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
    1786             :  *-------------------------------------------------------------------------
    1787             :  */
    1788             : 
    1789             : /*
    1790             :  * Get the actual type OID of the function return type
    1791             :  *
    1792             :  * Returns InvalidOid if information is not available
    1793             :  */
    1794             : Oid
    1795       42938 : get_fn_expr_rettype(FmgrInfo *flinfo)
    1796             : {
    1797             :     Node       *expr;
    1798             : 
    1799             :     /*
    1800             :      * can't return anything useful if we have no FmgrInfo or if its fn_expr
    1801             :      * node has not been initialized
    1802             :      */
    1803       42938 :     if (!flinfo || !flinfo->fn_expr)
    1804           0 :         return InvalidOid;
    1805             : 
    1806       42938 :     expr = flinfo->fn_expr;
    1807             : 
    1808       42938 :     return exprType(expr);
    1809             : }
    1810             : 
    1811             : /*
    1812             :  * Get the actual type OID of a specific function argument (counting from 0)
    1813             :  *
    1814             :  * Returns InvalidOid if information is not available
    1815             :  */
    1816             : Oid
    1817      950236 : get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
    1818             : {
    1819             :     /*
    1820             :      * can't return anything useful if we have no FmgrInfo or if its fn_expr
    1821             :      * node has not been initialized
    1822             :      */
    1823      950236 :     if (!flinfo || !flinfo->fn_expr)
    1824           0 :         return InvalidOid;
    1825             : 
    1826      950236 :     return get_call_expr_argtype(flinfo->fn_expr, argnum);
    1827             : }
    1828             : 
    1829             : /*
    1830             :  * Get the actual type OID of a specific function argument (counting from 0),
    1831             :  * but working from the calling expression tree instead of FmgrInfo
    1832             :  *
    1833             :  * Returns InvalidOid if information is not available
    1834             :  */
    1835             : Oid
    1836      958302 : get_call_expr_argtype(Node *expr, int argnum)
    1837             : {
    1838             :     List       *args;
    1839             :     Oid         argtype;
    1840             : 
    1841      958302 :     if (expr == NULL)
    1842           0 :         return InvalidOid;
    1843             : 
    1844      958302 :     if (IsA(expr, FuncExpr))
    1845      958272 :         args = ((FuncExpr *) expr)->args;
    1846          30 :     else if (IsA(expr, OpExpr))
    1847          30 :         args = ((OpExpr *) expr)->args;
    1848           0 :     else if (IsA(expr, DistinctExpr))
    1849           0 :         args = ((DistinctExpr *) expr)->args;
    1850           0 :     else if (IsA(expr, ScalarArrayOpExpr))
    1851           0 :         args = ((ScalarArrayOpExpr *) expr)->args;
    1852           0 :     else if (IsA(expr, NullIfExpr))
    1853           0 :         args = ((NullIfExpr *) expr)->args;
    1854           0 :     else if (IsA(expr, WindowFunc))
    1855           0 :         args = ((WindowFunc *) expr)->args;
    1856             :     else
    1857           0 :         return InvalidOid;
    1858             : 
    1859      958302 :     if (argnum < 0 || argnum >= list_length(args))
    1860           0 :         return InvalidOid;
    1861             : 
    1862      958302 :     argtype = exprType((Node *) list_nth(args, argnum));
    1863             : 
    1864             :     /*
    1865             :      * special hack for ScalarArrayOpExpr: what the underlying function will
    1866             :      * actually get passed is the element type of the array.
    1867             :      */
    1868      958302 :     if (IsA(expr, ScalarArrayOpExpr) &&
    1869             :         argnum == 1)
    1870           0 :         argtype = get_base_element_type(argtype);
    1871             : 
    1872      958302 :     return argtype;
    1873             : }
    1874             : 
    1875             : /*
    1876             :  * Find out whether a specific function argument is constant for the
    1877             :  * duration of a query
    1878             :  *
    1879             :  * Returns false if information is not available
    1880             :  */
    1881             : bool
    1882         856 : get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
    1883             : {
    1884             :     /*
    1885             :      * can't return anything useful if we have no FmgrInfo or if its fn_expr
    1886             :      * node has not been initialized
    1887             :      */
    1888         856 :     if (!flinfo || !flinfo->fn_expr)
    1889           0 :         return false;
    1890             : 
    1891         856 :     return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
    1892             : }
    1893             : 
    1894             : /*
    1895             :  * Find out whether a specific function argument is constant for the
    1896             :  * duration of a query, but working from the calling expression tree
    1897             :  *
    1898             :  * Returns false if information is not available
    1899             :  */
    1900             : bool
    1901         856 : get_call_expr_arg_stable(Node *expr, int argnum)
    1902             : {
    1903             :     List       *args;
    1904             :     Node       *arg;
    1905             : 
    1906         856 :     if (expr == NULL)
    1907           0 :         return false;
    1908             : 
    1909         856 :     if (IsA(expr, FuncExpr))
    1910         332 :         args = ((FuncExpr *) expr)->args;
    1911         524 :     else if (IsA(expr, OpExpr))
    1912           0 :         args = ((OpExpr *) expr)->args;
    1913         524 :     else if (IsA(expr, DistinctExpr))
    1914           0 :         args = ((DistinctExpr *) expr)->args;
    1915         524 :     else if (IsA(expr, ScalarArrayOpExpr))
    1916           0 :         args = ((ScalarArrayOpExpr *) expr)->args;
    1917         524 :     else if (IsA(expr, NullIfExpr))
    1918           0 :         args = ((NullIfExpr *) expr)->args;
    1919         524 :     else if (IsA(expr, WindowFunc))
    1920         524 :         args = ((WindowFunc *) expr)->args;
    1921             :     else
    1922           0 :         return false;
    1923             : 
    1924         856 :     if (argnum < 0 || argnum >= list_length(args))
    1925           0 :         return false;
    1926             : 
    1927         856 :     arg = (Node *) list_nth(args, argnum);
    1928             : 
    1929             :     /*
    1930             :      * Either a true Const or an external Param will have a value that doesn't
    1931             :      * change during the execution of the query.  In future we might want to
    1932             :      * consider other cases too, e.g. now().
    1933             :      */
    1934         856 :     if (IsA(arg, Const))
    1935         696 :         return true;
    1936         160 :     if (IsA(arg, Param) &&
    1937           0 :         ((Param *) arg)->paramkind == PARAM_EXTERN)
    1938           0 :         return true;
    1939             : 
    1940         160 :     return false;
    1941             : }
    1942             : 
    1943             : /*
    1944             :  * Get the VARIADIC flag from the function invocation
    1945             :  *
    1946             :  * Returns false (the default assumption) if information is not available
    1947             :  *
    1948             :  * Note this is generally only of interest to VARIADIC ANY functions
    1949             :  */
    1950             : bool
    1951        8674 : get_fn_expr_variadic(FmgrInfo *flinfo)
    1952             : {
    1953             :     Node       *expr;
    1954             : 
    1955             :     /*
    1956             :      * can't return anything useful if we have no FmgrInfo or if its fn_expr
    1957             :      * node has not been initialized
    1958             :      */
    1959        8674 :     if (!flinfo || !flinfo->fn_expr)
    1960           0 :         return false;
    1961             : 
    1962        8674 :     expr = flinfo->fn_expr;
    1963             : 
    1964        8674 :     if (IsA(expr, FuncExpr))
    1965        8674 :         return ((FuncExpr *) expr)->funcvariadic;
    1966             :     else
    1967           0 :         return false;
    1968             : }
    1969             : 
    1970             : /*-------------------------------------------------------------------------
    1971             :  *      Support routines for procedural language implementations
    1972             :  *-------------------------------------------------------------------------
    1973             :  */
    1974             : 
    1975             : /*
    1976             :  * Verify that a validator is actually associated with the language of a
    1977             :  * particular function and that the user has access to both the language and
    1978             :  * the function.  All validators should call this before doing anything
    1979             :  * substantial.  Doing so ensures a user cannot achieve anything with explicit
    1980             :  * calls to validators that he could not achieve with CREATE FUNCTION or by
    1981             :  * simply calling an existing function.
    1982             :  *
    1983             :  * When this function returns false, callers should skip all validation work
    1984             :  * and call PG_RETURN_VOID().  This never happens at present; it is reserved
    1985             :  * for future expansion.
    1986             :  *
    1987             :  * In particular, checking that the validator corresponds to the function's
    1988             :  * language allows untrusted language validators to assume they process only
    1989             :  * superuser-chosen source code.  (Untrusted language call handlers, by
    1990             :  * definition, do assume that.)  A user lacking the USAGE language privilege
    1991             :  * would be unable to reach the validator through CREATE FUNCTION, so we check
    1992             :  * that to block explicit calls as well.  Checking the EXECUTE privilege on
    1993             :  * the function is often superfluous, because most users can clone the
    1994             :  * function to get an executable copy.  It is meaningful against users with no
    1995             :  * database TEMP right and no permanent schema CREATE right, thereby unable to
    1996             :  * create any function.  Also, if the function tracks persistent state by
    1997             :  * function OID or name, validating the original function might permit more
    1998             :  * mischief than creating and validating a clone thereof.
    1999             :  */
    2000             : bool
    2001       22062 : CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
    2002             : {
    2003             :     HeapTuple   procTup;
    2004             :     HeapTuple   langTup;
    2005             :     Form_pg_proc procStruct;
    2006             :     Form_pg_language langStruct;
    2007             :     AclResult   aclresult;
    2008             : 
    2009             :     /*
    2010             :      * Get the function's pg_proc entry.  Throw a user-facing error for bad
    2011             :      * OID, because validators can be called with user-specified OIDs.
    2012             :      */
    2013       22062 :     procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionOid));
    2014       22062 :     if (!HeapTupleIsValid(procTup))
    2015           0 :         ereport(ERROR,
    2016             :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
    2017             :                  errmsg("function with OID %u does not exist", functionOid)));
    2018       22062 :     procStruct = (Form_pg_proc) GETSTRUCT(procTup);
    2019             : 
    2020             :     /*
    2021             :      * Fetch pg_language entry to know if this is the correct validation
    2022             :      * function for that pg_proc entry.
    2023             :      */
    2024       22062 :     langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(procStruct->prolang));
    2025       22062 :     if (!HeapTupleIsValid(langTup))
    2026           0 :         elog(ERROR, "cache lookup failed for language %u", procStruct->prolang);
    2027       22062 :     langStruct = (Form_pg_language) GETSTRUCT(langTup);
    2028             : 
    2029       22062 :     if (langStruct->lanvalidator != validatorOid)
    2030           0 :         ereport(ERROR,
    2031             :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
    2032             :                  errmsg("language validation function %u called for language %u instead of %u",
    2033             :                         validatorOid, procStruct->prolang,
    2034             :                         langStruct->lanvalidator)));
    2035             : 
    2036             :     /* first validate that we have permissions to use the language */
    2037       22062 :     aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
    2038             :                                      ACL_USAGE);
    2039       22062 :     if (aclresult != ACLCHECK_OK)
    2040           0 :         aclcheck_error(aclresult, OBJECT_LANGUAGE,
    2041           0 :                        NameStr(langStruct->lanname));
    2042             : 
    2043             :     /*
    2044             :      * Check whether we are allowed to execute the function itself. If we can
    2045             :      * execute it, there should be no possible side-effect of
    2046             :      * compiling/validation that execution can't have.
    2047             :      */
    2048       22062 :     aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
    2049       22062 :     if (aclresult != ACLCHECK_OK)
    2050           0 :         aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
    2051             : 
    2052       22062 :     ReleaseSysCache(procTup);
    2053       22062 :     ReleaseSysCache(langTup);
    2054             : 
    2055       22062 :     return true;
    2056             : }

Generated by: LCOV version 1.13