LCOV - differential code coverage report
Current view: top level - src/backend/utils/fmgr - fmgr.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 74.2 % 814 604 6 24 113 67 30 318 41 215 113 351 14
Current Date: 2023-04-08 15:15:32 Functions: 87.0 % 69 60 9 58 2 9 60
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a