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

Generated by: LCOV version 1.13