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 17:13:01 Functions: 87.0 % 69 60 9 58 2 9 60
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 6 6 6
Legend: Lines: hit not hit (60,120] days: 83.3 % 18 15 3 15
(120,180] days: 87.0 % 23 20 3 20
(240..) days: 73.4 % 767 563 24 113 67 30 318 215 106 336
Function coverage date bins:
(60,120] days: 100.0 % 1 1 1
(120,180] days: 100.0 % 1 1 1
(240..) days: 43.0 % 135 58 9 58 9 59

 Age         Owner                  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 *
 8351 tgl                        76 GIC    52675772 : fmgr_isbuiltin(Oid id)
 9215 webmaster                  77 ECB             : {
                                 78                 :     uint16      index;
                                 79                 : 
                                 80                 :     /* fast lookup only possible if original oid still assigned */
 1551 tgl                        81 GIC    52675772 :     if (id > fmgr_last_builtin_oid)
 2013 andres                     82 CBC       62603 :         return NULL;
 9215 webmaster                  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                 :      */
 2013 andres                     88 GIC    52613169 :     index = fmgr_builtin_oid_index[id];
 2013 andres                     89 CBC    52613169 :     if (index == InvalidOidBuiltinMapping)
                                 90            4559 :         return NULL;
 9215 webmaster                  91 ECB             : 
 2013 andres                     92 GIC    52608610 :     return &fmgr_builtins[index];
 8351 tgl                        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 *
 8053 bruce                     101 GIC       12272 : fmgr_lookupByName(const char *name)
 8351 tgl                       102 ECB             : {
                                103                 :     int         i;
                                104                 : 
 8351 tgl                       105 GIC    23793255 :     for (i = 0; i < fmgr_nbuiltins; i++)
 9173 bruce                     106 ECB             :     {
 8351 tgl                       107 GIC    23793252 :         if (strcmp(name, fmgr_builtins[i].funcName) == 0)
 8351 tgl                       108 CBC       12269 :             return fmgr_builtins + i;
 8053 bruce                     109 ECB             :     }
 7032 neilc                     110 GIC           3 :     return NULL;
 8351 tgl                       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
 8351 tgl                       127 GIC    51460356 : fmgr_info(Oid functionId, FmgrInfo *finfo)
 7855 tgl                       128 ECB             : {
 3966 tgl                       129 GIC    51460356 :     fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
 7855 tgl                       130 CBC    51460356 : }
 7855 tgl                       131 ECB             : 
                                132                 : /*
                                133                 :  * Fill a FmgrInfo struct, specifying a memory context in which its
                                134                 :  * subsidiary data should go.
                                135                 :  */
                                136                 : void
 7855 tgl                       137 GIC     1200750 : fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
 7631 peter_e                   138 ECB             : {
 7631 peter_e                   139 GIC     1200750 :     fmgr_info_cxt_security(functionId, finfo, mcxt, false);
 7631 peter_e                   140 CBC     1200750 : }
 7631 peter_e                   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
 7631 peter_e                   147 GIC    52675772 : fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
 7631 peter_e                   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                 :      */
 7995 peter_e                   161 CBC    52675772 :     finfo->fn_oid = InvalidOid;
 8351 tgl                       162        52675772 :     finfo->fn_extra = NULL;
 7855                           163        52675772 :     finfo->fn_mcxt = mcxt;
 7306                           164        52675772 :     finfo->fn_expr = NULL;       /* caller may set this later */
                                165                 : 
 8351                           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;
 8175                           173        52608610 :         finfo->fn_retset = fbp->retset;
 2118                           174        52608610 :         finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
 8175                           175        52608610 :         finfo->fn_addr = fbp->func;
 7995 peter_e                   176        52608610 :         finfo->fn_oid = functionId;
 8351 tgl                       177        52608610 :         return;
                                178                 :     }
                                179                 : 
                                180                 :     /* Otherwise we need the pg_proc entry */
 4802 rhaas                     181           67162 :     procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
 8351 tgl                       182           67162 :     if (!HeapTupleIsValid(procedureTuple))
 7198 tgl                       183 UBC           0 :         elog(ERROR, "cache lookup failed for function %u", functionId);
 8351 tgl                       184 CBC       67162 :     procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
                                185                 : 
                                186           67162 :     finfo->fn_nargs = procedureStruct->pronargs;
                                187           67162 :     finfo->fn_strict = procedureStruct->proisstrict;
 8263                           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                 :      */
 5697                           204           67162 :     if (!ignore_security &&
                                205           52496 :         (procedureStruct->prosecdef ||
 1838 andrew                    206           52488 :          !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
 4500 rhaas                     207           52466 :          FmgrHookIsNeeded(functionId)))
                                208                 :     {
 7631 peter_e                   209              30 :         finfo->fn_addr = fmgr_security_definer;
 2118 tgl                       210              30 :         finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
 7995 peter_e                   211              30 :         finfo->fn_oid = functionId;
 8179 tgl                       212              30 :         ReleaseSysCache(procedureTuple);
 8351                           213              30 :         return;
                                214                 :     }
                                215                 : 
 8175                           216           67132 :     switch (procedureStruct->prolang)
                                217                 :     {
 8351                           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                 :              */
   15 dgustafsson               229 GNC        1267 :             prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                230                 :                                                  Anum_pg_proc_prosrc);
 5493 tgl                       231 CBC        1267 :             prosrc = TextDatumGetCString(prosrcdatum);
 8351 tgl                       232 GBC        1267 :             fbp = fmgr_lookupByName(prosrc);
 8351 tgl                       233 GIC        1267 :             if (fbp == NULL)
 7198 tgl                       234 UIC           0 :                 ereport(ERROR,
                                235                 :                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
 6796 bruce                     236 ECB             :                          errmsg("internal function \"%s\" is not in internal lookup table",
                                237                 :                                 prosrc)));
 8351 tgl                       238 CBC        1267 :             pfree(prosrc);
                                239                 :             /* Should we check that nargs, strict, retset match the table? */
 8175                           240            1267 :             finfo->fn_addr = fbp->func;
 5442 tgl                       241 ECB             :             /* note this policy is also assumed in fast path above */
 5442 tgl                       242 GIC        1267 :             finfo->fn_stats = TRACK_FUNC_ALL;    /* ie, never track */
 8351 tgl                       243 CBC        1267 :             break;
 8720 bruce                     244 ECB             : 
 8351 tgl                       245 CBC       42877 :         case ClanguageId:
 7995 peter_e                   246           42877 :             fmgr_info_C_lang(functionId, finfo, procedureTuple);
 5442 tgl                       247 GIC       42877 :             finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */
 8351 tgl                       248 CBC       42877 :             break;
 8351 tgl                       249 ECB             : 
 8351 tgl                       250 CBC        8352 :         case SQLlanguageId:
                                251            8352 :             finfo->fn_addr = fmgr_sql;
 5442 tgl                       252 GIC        8352 :             finfo->fn_stats = TRACK_FUNC_PL; /* ie, track if ALL */
 8351 tgl                       253 CBC        8352 :             break;
 8351 tgl                       254 ECB             : 
 8351 tgl                       255 CBC       14636 :         default:
 7995 peter_e                   256           14636 :             fmgr_info_other_lang(functionId, finfo, procedureTuple);
 5442 tgl                       257 GIC       14636 :             finfo->fn_stats = TRACK_FUNC_OFF;    /* ie, track if not OFF */
 8175                           258           14636 :             break;
 8175 tgl                       259 ECB             :     }
                                260                 : 
 7995 peter_e                   261 GIC       67132 :     finfo->fn_oid = functionId;
 8175 tgl                       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.
 1846 andres                    279 ECB             :  */
                                280                 : void
 1846 andres                    281 GIC        2800 : fmgr_symbol(Oid functionId, char **mod, char **fn)
                                282                 : {
                                283                 :     HeapTuple   procedureTuple;
                                284                 :     Form_pg_proc procedureStruct;
 1846 andres                    285 ECB             :     Datum       prosrcattr;
                                286                 :     Datum       probinattr;
 1846 andres                    287 EUB             : 
 1846 andres                    288 CBC        2800 :     procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
 1846 andres                    289 GIC        2800 :     if (!HeapTupleIsValid(procedureTuple))
 1846 andres                    290 LBC           0 :         elog(ERROR, "cache lookup failed for function %u", functionId);
 1846 andres                    291 CBC        2800 :     procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
 1846 andres                    292 ECB             : 
 1846 andres                    293 GIC        2800 :     if (procedureStruct->prosecdef ||
 1838 andrew                    294 GBC        2800 :         !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) ||
 1846 andres                    295            2800 :         FmgrHookIsNeeded(functionId))
 1846 andres                    296 EUB             :     {
 1809 tgl                       297 UBC           0 :         *mod = NULL;            /* core binary */
 1846 andres                    298 UIC           0 :         *fn = pstrdup("fmgr_security_definer");
                                299               0 :         ReleaseSysCache(procedureTuple);
                                300               0 :         return;
 1846 andres                    301 ECB             :     }
                                302                 : 
                                303                 :     /* see fmgr_info_cxt_security for the individual cases */
 1846 andres                    304 CBC        2800 :     switch (procedureStruct->prolang)
                                305                 :     {
 1846 andres                    306 GIC        2758 :         case INTERNALlanguageId:
   15 dgustafsson               307 GNC        2758 :             prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                308                 :                                                 Anum_pg_proc_prosrc);
 1846 andres                    309 ECB             : 
 1809 tgl                       310 CBC        2758 :             *mod = NULL;        /* core binary */
 1846 andres                    311 GIC        2758 :             *fn = TextDatumGetCString(prosrcattr);
                                312            2758 :             break;
 1846 andres                    313 ECB             : 
 1846 andres                    314 GIC          18 :         case ClanguageId:
   15 dgustafsson               315 GNC          18 :             prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                316                 :                                                 Anum_pg_proc_prosrc);
                                317                 : 
                                318              18 :             probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                319                 :                                                 Anum_pg_proc_probin);
 1846 andres                    320 ECB             : 
                                321                 :             /*
                                322                 :              * No need to check symbol presence / API version here, already
                                323                 :              * checked in fmgr_info_cxt_security.
                                324                 :              */
 1846 andres                    325 CBC          18 :             *mod = TextDatumGetCString(probinattr);
                                326              18 :             *fn = TextDatumGetCString(prosrcattr);
                                327              18 :             break;
 1846 andres                    328 ECB             : 
 1846 andres                    329 GIC          12 :         case SQLlanguageId:
 1809 tgl                       330              12 :             *mod = NULL;        /* core binary */
 1846 andres                    331 CBC          12 :             *fn = pstrdup("fmgr_sql");
 1846 andres                    332 GIC          12 :             break;
                                333                 : 
                                334              12 :         default:
                                335              12 :             *mod = NULL;
 1809 tgl                       336              12 :             *fn = NULL;         /* unknown, pass pointer */
 1846 andres                    337              12 :             break;
                                338                 :     }
                                339                 : 
 1846 andres                    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
 7995 peter_e                   349           42877 : fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
 8175 tgl                       350 ECB             : {
                                351                 :     CFuncHashTabEntry *hashentry;
                                352                 :     PGFunction  user_fn;
 6158                           353                 :     const Pg_finfo_record *inforec;
                                354                 : 
                                355                 :     /*
                                356                 :      * See if we have the function address cached already
                                357                 :      */
 7020 tgl                       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,
 7020 tgl                       367 ECB             :                     probinattr;
                                368                 :         char       *prosrcstring,
                                369                 :                    *probinstring;
                                370                 :         void       *libraryhandle;
                                371                 : 
                                372                 :         /*
 5380                           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.
 6796 bruce                     376                 :          */
   15 dgustafsson               377 GNC        2824 :         prosrcattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                378                 :                                             Anum_pg_proc_prosrc);
 5493 tgl                       379 GIC        2824 :         prosrcstring = TextDatumGetCString(prosrcattr);
                                380                 : 
   15 dgustafsson               381 GNC        2824 :         probinattr = SysCacheGetAttrNotNull(PROCOID, procedureTuple,
                                382                 :                                             Anum_pg_proc_probin);
 5493 tgl                       383 GIC        2824 :         probinstring = TextDatumGetCString(probinattr);
                                384                 : 
 7020 tgl                       385 ECB             :         /* Look up the function itself */
 7020 tgl                       386 GIC        2824 :         user_fn = load_external_function(probinstring, prosrcstring, true,
 7020 tgl                       387 ECB             :                                          &libraryhandle);
                                388                 : 
                                389                 :         /* Get the function information record (real or default) */
 7020 tgl                       390 CBC        2824 :         inforec = fetch_finfo_record(libraryhandle, prosrcstring);
 7020 tgl                       391 EUB             : 
                                392                 :         /* Cache the addresses for later calls */
 7020 tgl                       393 GBC        2824 :         record_C_func(procedureTuple, user_fn, inforec);
                                394                 : 
 7020 tgl                       395 GIC        2824 :         pfree(prosrcstring);
                                396            2824 :         pfree(probinstring);
 7020 tgl                       397 ECB             :     }
                                398                 : 
 8175 tgl                       399 GIC       42877 :     switch (inforec->api_version)
                                400                 :     {
                                401           42877 :         case 1:
                                402                 :             /* New style: call directly */
                                403           42877 :             finfo->fn_addr = user_fn;
 8175 tgl                       404 CBC       42877 :             break;
 8175 tgl                       405 UIC           0 :         default:
 8175 tgl                       406 ECB             :             /* Shouldn't get here if fetch_finfo_record did its job */
 7198 tgl                       407 LBC           0 :             elog(ERROR, "unrecognized function API version: %d",
                                408                 :                  inforec->api_version);
                                409                 :             break;
                                410                 :     }
 8772 tgl                       411 GIC       42877 : }
 8772 tgl                       412 ECB             : 
 8175                           413                 : /*
 7995 peter_e                   414 EUB             :  * Special fmgr_info processing for other-language functions.  Note
 7995 peter_e                   415 ECB             :  * that finfo->fn_oid is not valid yet.
                                416                 :  */
                                417                 : static void
 7995 peter_e                   418 GIC       14636 : fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
                                419                 : {
 8175 tgl                       420           14636 :     Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
                                421           14636 :     Oid         language = procedureStruct->prolang;
 8175 tgl                       422 ECB             :     HeapTuple   languageTuple;
                                423                 :     Form_pg_language languageStruct;
 7544 peter_e                   424                 :     FmgrInfo    plfinfo;
                                425                 : 
 4802 rhaas                     426 CBC       14636 :     languageTuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(language));
 8175 tgl                       427           14636 :     if (!HeapTupleIsValid(languageTuple))
 7198 tgl                       428 UIC           0 :         elog(ERROR, "cache lookup failed for language %u", language);
 8175 tgl                       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                 :      */
 3966                           436           14636 :     fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
                                437                 :                            CurrentMemoryContext, true);
 7544 peter_e                   438           14636 :     finfo->fn_addr = plfinfo.fn_addr;
                                439                 : 
 8175 tgl                       440           14636 :     ReleaseSysCache(languageTuple);
 8175 tgl                       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.
 8175 tgl                       447 ECB             :  *
                                448                 :  * If no info function exists for the given name an error is raised.
                                449                 :  *
 6583                           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
 8175                           452                 :  * pg_proc.
                                453                 :  */
 6158 tgl                       454 EUB             : const Pg_finfo_record *
 2186 tgl                       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                 : 
 3465 peter_e                   461            6308 :     infofuncname = psprintf("pg_finfo_%s", funcname);
                                462                 : 
 8175 tgl                       463 ECB             :     /* Try to look up the info function */
 7855 tgl                       464 GIC        6308 :     infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
                                465                 :                                                           infofuncname);
 7032 neilc                     466 CBC        6308 :     if (infofunc == NULL)
 8175 tgl                       467 EUB             :     {
 2202 andres                    468 LBC           0 :         ereport(ERROR,
                                469                 :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
 2118 tgl                       470 ECB             :                  errmsg("could not find function information for function \"%s\"",
                                471                 :                         funcname),
 2202 andres                    472                 :                  errhint("SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname).")));
 2153 bruce                     473 EUB             :         return NULL;            /* silence compiler */
 8175 tgl                       474                 :     }
                                475                 : 
                                476                 :     /* Found, so call it */
 8053 bruce                     477 GIC        6308 :     inforec = (*infofunc) ();
                                478                 : 
                                479                 :     /* Validate result as best we can */
 8175 tgl                       480            6308 :     if (inforec == NULL)
 7198 tgl                       481 LBC           0 :         elog(ERROR, "null result from info function \"%s\"", infofuncname);
 8175 tgl                       482 CBC        6308 :     switch (inforec->api_version)
                                483                 :     {
 8175 tgl                       484 GIC        6308 :         case 1:
                                485                 :             /* OK, no additional fields to validate */
                                486            6308 :             break;
 8175 tgl                       487 UIC           0 :         default:
 7198                           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                 : 
 8175 tgl                       495 GIC        6308 :     pfree(infofuncname);
                                496            6308 :     return inforec;
                                497                 : }
                                498                 : 
                                499                 : 
                                500                 : /*-------------------------------------------------------------------------
 7020 tgl                       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 *
 7020 tgl                       515 CBC       42877 : lookup_C_func(HeapTuple procedureTuple)
 7020 tgl                       516 ECB             : {
 1601 andres                    517 CBC       42877 :     Oid         fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
 7020 tgl                       518 ECB             :     CFuncHashTabEntry *entry;
                                519                 : 
 7020 tgl                       520 GIC       42877 :     if (CFuncHash == NULL)
                                521            1160 :         return NULL;            /* no table yet */
                                522                 :     entry = (CFuncHashTabEntry *)
                                523           41717 :         hash_search(CFuncHash,
                                524                 :                     &fn_oid,
 7020 tgl                       525 ECB             :                     HASH_FIND,
                                526                 :                     NULL);
 7020 tgl                       527 GIC       41717 :     if (entry == NULL)
 7020 tgl                       528 CBC        1661 :         return NULL;            /* no such entry */
 3395 rhaas                     529 GIC       80109 :     if (entry->fn_xmin == HeapTupleHeaderGetRawXmin(procedureTuple->t_data) &&
 5903 tgl                       530           40053 :         ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
 7020                           531           40053 :         return entry;           /* OK */
                                532               3 :     return NULL;                /* entry is out of date */
 7020 tgl                       533 ECB             : }
                                534                 : 
                                535                 : /*
                                536                 :  * record_C_func: enter (or update) info about a C function in the hash table
                                537                 :  */
                                538                 : static void
 7020 tgl                       539 CBC        2824 : record_C_func(HeapTuple procedureTuple,
                                540                 :               PGFunction user_fn, const Pg_finfo_record *inforec)
                                541                 : {
 1418 tgl                       542 GIC        2824 :     Oid         fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
                                543                 :     CFuncHashTabEntry *entry;
                                544                 :     bool        found;
                                545                 : 
 7020 tgl                       546 ECB             :     /* Create the hash table if it doesn't exist yet */
 7020 tgl                       547 GIC        2824 :     if (CFuncHash == NULL)
                                548                 :     {
                                549                 :         HASHCTL     hash_ctl;
                                550                 : 
 7020 tgl                       551 CBC        1160 :         hash_ctl.keysize = sizeof(Oid);
                                552            1160 :         hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
                                553            1160 :         CFuncHash = hash_create("CFuncHash",
 7020 tgl                       554 ECB             :                                 100,
                                555                 :                                 &hash_ctl,
                                556                 :                                 HASH_ELEM | HASH_BLOBS);
                                557                 :     }
                                558                 : 
                                559                 :     entry = (CFuncHashTabEntry *)
 7020 tgl                       560 GIC        2824 :         hash_search(CFuncHash,
                                561                 :                     &fn_oid,
                                562                 :                     HASH_ENTER,
                                563                 :                     &found);
                                564                 :     /* OID is already filled in */
 3395 rhaas                     565            2824 :     entry->fn_xmin = HeapTupleHeaderGetRawXmin(procedureTuple->t_data);
 5903 tgl                       566 CBC        2824 :     entry->fn_tid = procedureTuple->t_self;
 7020 tgl                       567 GIC        2824 :     entry->user_fn = user_fn;
                                568            2824 :     entry->inforec = inforec;
 7020 tgl                       569 CBC        2824 : }
 7020 tgl                       570 ECB             : 
                                571                 : 
 7855                           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
 7855 tgl                       580 GIC    34338341 : fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
 7855 tgl                       581 ECB             :                MemoryContext destcxt)
                                582                 : {
 7855 tgl                       583 CBC    34338341 :     memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
 7855 tgl                       584 GIC    34338341 :     dstinfo->fn_mcxt = destcxt;
 2202 andres                    585 CBC    34338341 :     dstinfo->fn_extra = NULL;
 7855 tgl                       586        34338341 : }
 7855 tgl                       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
 8175 tgl                       595 GIC       11005 : fmgr_internal_function(const char *proname)
                                596                 : {
 8351                           597           11005 :     const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
                                598                 : 
                                599           11005 :     if (fbp == NULL)
                                600               3 :         return InvalidOid;
 8175                           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 */
 4486 tgl                       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
 3260 bruce                     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
 7631 peter_e                   630 GIC          30 : fmgr_security_definer(PG_FUNCTION_ARGS)
                                631                 : {
                                632                 :     Datum       result;
                                633                 :     struct fmgr_security_definer_cache *volatile fcache;
 5697 tgl                       634 ECB             :     FmgrInfo   *save_flinfo;
                                635                 :     Oid         save_userid;
                                636                 :     int         save_sec_context;
                                637                 :     volatile int save_nestlevel;
 5442                           638                 :     PgStat_FunctionCallUsage fcusage;
 7631 peter_e                   639                 : 
 7631 peter_e                   640 GIC          30 :     if (!fcinfo->flinfo->fn_extra)
 7631 peter_e                   641 ECB             :     {
 5697 tgl                       642                 :         HeapTuple   tuple;
                                643                 :         Form_pg_proc procedureStruct;
 5697 tgl                       644 EUB             :         Datum       datum;
                                645                 :         bool        isnull;
 5697 tgl                       646 ECB             :         MemoryContext oldcxt;
                                647                 : 
 6585 tgl                       648 CBC          30 :         fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
 6585 tgl                       649 ECB             :                                         sizeof(*fcache));
                                650                 : 
 7631 peter_e                   651 CBC          30 :         fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
 7631 peter_e                   652 GIC          30 :                                fcinfo->flinfo->fn_mcxt, true);
 5731 tgl                       653 CBC          30 :         fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
                                654                 : 
 4802 rhaas                     655              30 :         tuple = SearchSysCache1(PROCOID,
                                656              30 :                                 ObjectIdGetDatum(fcinfo->flinfo->fn_oid));
 7631 peter_e                   657              30 :         if (!HeapTupleIsValid(tuple))
 7198 tgl                       658 UIC           0 :             elog(ERROR, "cache lookup failed for function %u",
                                659                 :                  fcinfo->flinfo->fn_oid);
 5697 tgl                       660 CBC          30 :         procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
                                661                 : 
                                662              30 :         if (procedureStruct->prosecdef)
 5697 tgl                       663 GIC           8 :             fcache->userid = procedureStruct->proowner;
                                664                 : 
 5697 tgl                       665 GBC          30 :         datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
                                666                 :                                 &isnull);
 5697 tgl                       667 GIC          30 :         if (!isnull)
 5697 tgl                       668 ECB             :         {
 5697 tgl                       669 CBC          22 :             oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
                                670              22 :             fcache->proconfig = DatumGetArrayTypePCopy(datum);
 5697 tgl                       671 GIC          22 :             MemoryContextSwitchTo(oldcxt);
 5697 tgl                       672 ECB             :         }
                                673                 : 
 7631 peter_e                   674 CBC          30 :         ReleaseSysCache(tuple);
 7631 peter_e                   675 ECB             : 
 7631 peter_e                   676 GIC          30 :         fcinfo->flinfo->fn_extra = fcache;
                                677                 :     }
 7631 peter_e                   678 ECB             :     else
 7631 peter_e                   679 UIC           0 :         fcache = fcinfo->flinfo->fn_extra;
 7631 peter_e                   680 ECB             : 
                                681                 :     /* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
 4869 tgl                       682 CBC          30 :     GetUserIdAndSecContext(&save_userid, &save_sec_context);
 5697 tgl                       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                 : 
 5575 tgl                       688 CBC          30 :     if (OidIsValid(fcache->userid))
 4869 tgl                       689 GBC           8 :         SetUserIdAndSecContext(fcache->userid,
                                690                 :                                save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
                                691                 : 
 5575 tgl                       692 GIC          30 :     if (fcache->proconfig)
                                693                 :     {
                                694              22 :         ProcessGUCArray(fcache->proconfig,
                                695                 :                         NULL,
                                696              22 :                         (superuser() ? PGC_SUSET : PGC_USERSET),
 5575 tgl                       697 ECB             :                         PGC_S_SESSION,
                                698                 :                         GUC_ACTION_SAVE);
                                699                 :     }
                                700                 : 
 4500 rhaas                     701                 :     /* function manager hook */
 4500 rhaas                     702 GIC          27 :     if (fmgr_hook)
 4382 bruce                     703 UIC           0 :         (*fmgr_hook) (FHET_START, &fcache->flinfo, &fcache->arg);
 4500 rhaas                     704 ECB             : 
                                705                 :     /*
 5575 tgl                       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                 :      */
 5575 tgl                       710 GIC          27 :     save_flinfo = fcinfo->flinfo;
                                711                 : 
 5575 tgl                       712 CBC          27 :     PG_TRY();
 5575 tgl                       713 ECB             :     {
 5575 tgl                       714 CBC          27 :         fcinfo->flinfo = &fcache->flinfo;
 6764 tgl                       715 EUB             : 
                                716                 :         /* See notes in fmgr_info_cxt_security */
 5442 tgl                       717 CBC          27 :         pgstat_init_function_usage(fcinfo, &fcusage);
                                718                 : 
 6764                           719              27 :         result = FunctionCallInvoke(fcinfo);
 5442 tgl                       720 ECB             : 
 5442 tgl                       721 EUB             :         /*
 5442 tgl                       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                 :          */
 5442 tgl                       725 GIC          22 :         pgstat_end_function_usage(&fcusage,
 5442 tgl                       726 CBC          22 :                                   (fcinfo->resultinfo == NULL ||
 5442 tgl                       727 GIC          22 :                                    !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
 5442 tgl                       728 LBC           0 :                                    ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
 6764 tgl                       729 ECB             :     }
 6764 tgl                       730 CBC           5 :     PG_CATCH();
 6764 tgl                       731 ECB             :     {
 6764 tgl                       732 CBC           5 :         fcinfo->flinfo = save_flinfo;
 4500 rhaas                     733 GBC           5 :         if (fmgr_hook)
 4382 bruce                     734 UIC           0 :             (*fmgr_hook) (FHET_ABORT, &fcache->flinfo, &fcache->arg);
 6764 tgl                       735 CBC           5 :         PG_RE_THROW();
                                736                 :     }
 6764 tgl                       737 GIC          22 :     PG_END_TRY();
                                738                 : 
 7631 peter_e                   739              22 :     fcinfo->flinfo = save_flinfo;
                                740                 : 
 5697 tgl                       741              22 :     if (fcache->proconfig)
                                742              15 :         AtEOXact_GUC(true, save_nestlevel);
                                743              22 :     if (OidIsValid(fcache->userid))
 4869                           744               7 :         SetUserIdAndSecContext(save_userid, save_sec_context);
 4500 rhaas                     745              22 :     if (fmgr_hook)
 4382 bruce                     746 UIC           0 :         (*fmgr_hook) (FHET_END, &fcache->flinfo, &fcache->arg);
                                747                 : 
 7631 peter_e                   748 GIC          22 :     return result;
                                749                 : }
                                750                 : 
 8351 tgl                       751 ECB             : 
                                752                 : /*-------------------------------------------------------------------------
                                753                 :  *      Support routines for callers of fmgr-compatible functions
                                754                 :  *-------------------------------------------------------------------------
                                755                 :  */
 8772                           756                 : 
                                757                 : /*
 6640                           758                 :  * These are for invocation of a specifically named function with a
 8351                           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
 4380 tgl                       764 CBC     1680855 : DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
 9770 scrappy                   765 EUB             : {
 1534 andres                    766 GIC     1680855 :     LOCAL_FCINFO(fcinfo, 1);
 8053 bruce                     767 ECB             :     Datum       result;
                                768                 : 
 1534 andres                    769 GIC     1680855 :     InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
                                770                 : 
 1534 andres                    771 CBC     1680855 :     fcinfo->args[0].value = arg1;
 1534 andres                    772 GIC     1680855 :     fcinfo->args[0].isnull = false;
 9345 bruce                     773 ECB             : 
 1534 andres                    774 GIC     1680855 :     result = (*func) (fcinfo);
                                775                 : 
 8351 tgl                       776 ECB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                    777 GIC     1680843 :     if (fcinfo->isnull)
 7198 tgl                       778 LBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 8351 tgl                       779 ECB             : 
 8351 tgl                       780 CBC     1680843 :     return result;
 9770 scrappy                   781 ECB             : }
                                782                 : 
 8351 tgl                       783                 : Datum
 4380 tgl                       784 GIC    19901161 : DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
                                785                 : {
 1534 andres                    786 CBC    19901161 :     LOCAL_FCINFO(fcinfo, 2);
 8053 bruce                     787 EUB             :     Datum       result;
                                788                 : 
 1534 andres                    789 CBC    19901161 :     InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
                                790                 : 
 1534 andres                    791 GIC    19901161 :     fcinfo->args[0].value = arg1;
                                792        19901161 :     fcinfo->args[0].isnull = false;
 1534 andres                    793 CBC    19901161 :     fcinfo->args[1].value = arg2;
 1534 andres                    794 GIC    19901161 :     fcinfo->args[1].isnull = false;
                                795                 : 
 1534 andres                    796 CBC    19901161 :     result = (*func) (fcinfo);
                                797                 : 
                                798                 :     /* Check for null result, since caller is clearly not expecting one */
                                799        19901143 :     if (fcinfo->isnull)
 7198 tgl                       800 UIC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 8351 tgl                       801 ECB             : 
 8351 tgl                       802 CBC    19901143 :     return result;
 8351 tgl                       803 ECB             : }
                                804                 : 
                                805                 : Datum
 4380 tgl                       806 CBC       38783 : DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
                                807                 :                         Datum arg3)
 8351 tgl                       808 ECB             : {
 1534 andres                    809 GIC       38783 :     LOCAL_FCINFO(fcinfo, 3);
                                810                 :     Datum       result;
 8351 tgl                       811 ECB             : 
 1534 andres                    812 GBC       38783 :     InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL);
                                813                 : 
 1534 andres                    814 CBC       38783 :     fcinfo->args[0].value = arg1;
 1534 andres                    815 GIC       38783 :     fcinfo->args[0].isnull = false;
                                816           38783 :     fcinfo->args[1].value = arg2;
                                817           38783 :     fcinfo->args[1].isnull = false;
 1534 andres                    818 CBC       38783 :     fcinfo->args[2].value = arg3;
 1534 andres                    819 GIC       38783 :     fcinfo->args[2].isnull = false;
                                820                 : 
 1534 andres                    821 CBC       38783 :     result = (*func) (fcinfo);
                                822                 : 
                                823                 :     /* Check for null result, since caller is clearly not expecting one */
                                824           38776 :     if (fcinfo->isnull)
 7198 tgl                       825 UIC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 8351 tgl                       826 ECB             : 
 8351 tgl                       827 CBC       38776 :     return result;
 8351 tgl                       828 ECB             : }
                                829                 : 
                                830                 : Datum
 4380 tgl                       831 CBC         674 : DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     832 ECB             :                         Datum arg3, Datum arg4)
 8351 tgl                       833                 : {
 1534 andres                    834 GIC         674 :     LOCAL_FCINFO(fcinfo, 4);
 8053 bruce                     835 ECB             :     Datum       result;
                                836                 : 
 1534 andres                    837 GIC         674 :     InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL);
 6640 tgl                       838 ECB             : 
 1534 andres                    839 GBC         674 :     fcinfo->args[0].value = arg1;
 1534 andres                    840 GIC         674 :     fcinfo->args[0].isnull = false;
 1534 andres                    841 CBC         674 :     fcinfo->args[1].value = arg2;
 1534 andres                    842 GIC         674 :     fcinfo->args[1].isnull = false;
                                843             674 :     fcinfo->args[2].value = arg3;
                                844             674 :     fcinfo->args[2].isnull = false;
 1534 andres                    845 CBC         674 :     fcinfo->args[3].value = arg4;
 1534 andres                    846 GIC         674 :     fcinfo->args[3].isnull = false;
                                847                 : 
 1534 andres                    848 CBC         674 :     result = (*func) (fcinfo);
                                849                 : 
                                850                 :     /* Check for null result, since caller is clearly not expecting one */
                                851             674 :     if (fcinfo->isnull)
 7198 tgl                       852 UIC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 8351 tgl                       853 ECB             : 
 8351 tgl                       854 CBC         674 :     return result;
 8351 tgl                       855 ECB             : }
                                856                 : 
                                857                 : Datum
 4380 tgl                       858 CBC        2100 : DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     859 ECB             :                         Datum arg3, Datum arg4, Datum arg5)
 8351 tgl                       860                 : {
 1534 andres                    861 CBC        2100 :     LOCAL_FCINFO(fcinfo, 5);
 8053 bruce                     862 ECB             :     Datum       result;
                                863                 : 
 1534 andres                    864 CBC        2100 :     InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL);
                                865                 : 
 1534 andres                    866 GIC        2100 :     fcinfo->args[0].value = arg1;
 1534 andres                    867 CBC        2100 :     fcinfo->args[0].isnull = false;
 1534 andres                    868 GBC        2100 :     fcinfo->args[1].value = arg2;
 1534 andres                    869 GIC        2100 :     fcinfo->args[1].isnull = false;
 1534 andres                    870 CBC        2100 :     fcinfo->args[2].value = arg3;
 1534 andres                    871 GIC        2100 :     fcinfo->args[2].isnull = false;
                                872            2100 :     fcinfo->args[3].value = arg4;
                                873            2100 :     fcinfo->args[3].isnull = false;
 1534 andres                    874 GBC        2100 :     fcinfo->args[4].value = arg5;
 1534 andres                    875 GIC        2100 :     fcinfo->args[4].isnull = false;
                                876                 : 
                                877            2100 :     result = (*func) (fcinfo);
 8351 tgl                       878 EUB             : 
                                879                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                    880 GIC        2097 :     if (fcinfo->isnull)
 7198 tgl                       881 UBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
                                882                 : 
 8351 tgl                       883 GBC        2097 :     return result;
 8351 tgl                       884 EUB             : }
                                885                 : 
                                886                 : Datum
 4380 tgl                       887 UBC           0 : DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     888 EUB             :                         Datum arg3, Datum arg4, Datum arg5,
                                889                 :                         Datum arg6)
 8351 tgl                       890                 : {
 1534 andres                    891 UBC           0 :     LOCAL_FCINFO(fcinfo, 6);
 8053 bruce                     892 EUB             :     Datum       result;
 8351 tgl                       893                 : 
 1534 andres                    894 UBC           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL);
                                895                 : 
                                896               0 :     fcinfo->args[0].value = arg1;
 1534 andres                    897 UIC           0 :     fcinfo->args[0].isnull = false;
                                898               0 :     fcinfo->args[1].value = arg2;
 1534 andres                    899 UBC           0 :     fcinfo->args[1].isnull = false;
                                900               0 :     fcinfo->args[2].value = arg3;
 1534 andres                    901 UIC           0 :     fcinfo->args[2].isnull = false;
 1534 andres                    902 UBC           0 :     fcinfo->args[3].value = arg4;
 1534 andres                    903 UIC           0 :     fcinfo->args[3].isnull = false;
                                904               0 :     fcinfo->args[4].value = arg5;
                                905               0 :     fcinfo->args[4].isnull = false;
 1534 andres                    906 UBC           0 :     fcinfo->args[5].value = arg6;
 1534 andres                    907 UIC           0 :     fcinfo->args[5].isnull = false;
                                908                 : 
                                909               0 :     result = (*func) (fcinfo);
 8351 tgl                       910 EUB             : 
                                911                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                    912 UIC           0 :     if (fcinfo->isnull)
 7198 tgl                       913 UBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
                                914                 : 
 8351                           915               0 :     return result;
 8351 tgl                       916 EUB             : }
                                917                 : 
                                918                 : Datum
 4380 tgl                       919 UBC           0 : DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     920 EUB             :                         Datum arg3, Datum arg4, Datum arg5,
                                921                 :                         Datum arg6, Datum arg7)
 8351 tgl                       922                 : {
 1534 andres                    923 UBC           0 :     LOCAL_FCINFO(fcinfo, 7);
 8053 bruce                     924 EUB             :     Datum       result;
 8351 tgl                       925                 : 
 1534 andres                    926 UBC           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL);
 1534 andres                    927 EUB             : 
 1534 andres                    928 UBC           0 :     fcinfo->args[0].value = arg1;
 1534 andres                    929 UIC           0 :     fcinfo->args[0].isnull = false;
 1534 andres                    930 UBC           0 :     fcinfo->args[1].value = arg2;
 1534 andres                    931 UIC           0 :     fcinfo->args[1].isnull = false;
                                932               0 :     fcinfo->args[2].value = arg3;
 1534 andres                    933 UBC           0 :     fcinfo->args[2].isnull = false;
                                934               0 :     fcinfo->args[3].value = arg4;
 1534 andres                    935 UIC           0 :     fcinfo->args[3].isnull = false;
 1534 andres                    936 UBC           0 :     fcinfo->args[4].value = arg5;
 1534 andres                    937 UIC           0 :     fcinfo->args[4].isnull = false;
                                938               0 :     fcinfo->args[5].value = arg6;
                                939               0 :     fcinfo->args[5].isnull = false;
 1534 andres                    940 UBC           0 :     fcinfo->args[6].value = arg7;
 1534 andres                    941 UIC           0 :     fcinfo->args[6].isnull = false;
                                942                 : 
                                943               0 :     result = (*func) (fcinfo);
 8351 tgl                       944 EUB             : 
                                945                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                    946 UIC           0 :     if (fcinfo->isnull)
 7198 tgl                       947 UBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
                                948                 : 
 8351                           949               0 :     return result;
 8351 tgl                       950 EUB             : }
                                951                 : 
                                952                 : Datum
 4380 tgl                       953 UBC           0 : DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     954 EUB             :                         Datum arg3, Datum arg4, Datum arg5,
                                955                 :                         Datum arg6, Datum arg7, Datum arg8)
 8351 tgl                       956                 : {
 1534 andres                    957 UBC           0 :     LOCAL_FCINFO(fcinfo, 8);
 8053 bruce                     958 EUB             :     Datum       result;
 8351 tgl                       959                 : 
 1534 andres                    960 UBC           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL);
 1534 andres                    961 EUB             : 
 1534 andres                    962 UBC           0 :     fcinfo->args[0].value = arg1;
                                963               0 :     fcinfo->args[0].isnull = false;
                                964               0 :     fcinfo->args[1].value = arg2;
 1534 andres                    965 UIC           0 :     fcinfo->args[1].isnull = false;
 1534 andres                    966 UBC           0 :     fcinfo->args[2].value = arg3;
 1534 andres                    967 UIC           0 :     fcinfo->args[2].isnull = false;
                                968               0 :     fcinfo->args[3].value = arg4;
 1534 andres                    969 UBC           0 :     fcinfo->args[3].isnull = false;
                                970               0 :     fcinfo->args[4].value = arg5;
 1534 andres                    971 UIC           0 :     fcinfo->args[4].isnull = false;
 1534 andres                    972 UBC           0 :     fcinfo->args[5].value = arg6;
 1534 andres                    973 UIC           0 :     fcinfo->args[5].isnull = false;
                                974               0 :     fcinfo->args[6].value = arg7;
                                975               0 :     fcinfo->args[6].isnull = false;
 1534 andres                    976 UBC           0 :     fcinfo->args[7].value = arg8;
 1534 andres                    977 UIC           0 :     fcinfo->args[7].isnull = false;
                                978                 : 
                                979               0 :     result = (*func) (fcinfo);
                                980                 : 
 8351 tgl                       981 EUB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                    982 UIC           0 :     if (fcinfo->isnull)
 7198 tgl                       983               0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 8351 tgl                       984 EUB             : 
 8351 tgl                       985 UIC           0 :     return result;
 8351 tgl                       986 EUB             : }
                                987                 : 
                                988                 : Datum
 4380 tgl                       989 UBC           0 : DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                     990 EUB             :                         Datum arg3, Datum arg4, Datum arg5,
                                991                 :                         Datum arg6, Datum arg7, Datum arg8,
                                992                 :                         Datum arg9)
 8351 tgl                       993                 : {
 1534 andres                    994 UBC           0 :     LOCAL_FCINFO(fcinfo, 9);
 8053 bruce                     995 EUB             :     Datum       result;
 8351 tgl                       996                 : 
 1534 andres                    997 UBC           0 :     InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL);
 1534 andres                    998 EUB             : 
 1534 andres                    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;
 1534 andres                   1004 UIC           0 :     fcinfo->args[2].isnull = false;
 1534 andres                   1005 UBC           0 :     fcinfo->args[3].value = arg4;
 1534 andres                   1006 UIC           0 :     fcinfo->args[3].isnull = false;
                               1007               0 :     fcinfo->args[4].value = arg5;
 1534 andres                   1008 UBC           0 :     fcinfo->args[4].isnull = false;
                               1009               0 :     fcinfo->args[5].value = arg6;
 1534 andres                   1010 UIC           0 :     fcinfo->args[5].isnull = false;
 1534 andres                   1011 UBC           0 :     fcinfo->args[6].value = arg7;
 1534 andres                   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)
 7198 tgl                      1022               0 :         elog(ERROR, "function %p returned NULL", (void *) func);
                               1023                 : 
 8351 tgl                      1024 UBC           0 :     return result;
                               1025                 : }
 8351 tgl                      1026 EUB             : 
                               1027                 : /*
                               1028                 :  * These functions work like the DirectFunctionCall functions except that
 2210 andrew                   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
 2210 andrew                   1037 UBC           0 : CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
 2210 andrew                   1038 EUB             : {
 1534 andres                   1039 UIC           0 :     LOCAL_FCINFO(fcinfo, 1);
 2210 andrew                   1040 EUB             :     Datum       result;
                               1041                 : 
 1534 andres                   1042 UIC           0 :     InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
                               1043                 : 
 1534 andres                   1044 LBC           0 :     fcinfo->args[0].value = arg1;
 1534 andres                   1045 UIC           0 :     fcinfo->args[0].isnull = false;
 2210 andrew                   1046 ECB             : 
 1534 andres                   1047 UIC           0 :     result = (*func) (fcinfo);
                               1048                 : 
 2210 andrew                   1049 ECB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1050 UIC           0 :     if (fcinfo->isnull)
 2210 andrew                   1051 LBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
 2210 andrew                   1052 ECB             : 
 2210 andrew                   1053 LBC           0 :     return result;
 2210 andrew                   1054 ECB             : }
                               1055                 : 
                               1056                 : Datum
 2210 andrew                   1057 GIC      205030 : CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
                               1058                 : {
 1534 andres                   1059 CBC      205030 :     LOCAL_FCINFO(fcinfo, 2);
 2210 andrew                   1060 EUB             :     Datum       result;
                               1061                 : 
 1534 andres                   1062 CBC      205030 :     InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
                               1063                 : 
 1534 andres                   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                 : 
 2210 andrew                   1071 ECB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1072 GIC      205030 :     if (fcinfo->isnull)
 2210 andrew                   1073 LBC           0 :         elog(ERROR, "function %p returned NULL", (void *) func);
                               1074                 : 
 2210 andrew                   1075 GIC      205030 :     return result;
 2210 andrew                   1076 ECB             : }
                               1077                 : 
 6640 tgl                      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
 8351                          1081                 :  * are allowed to be NULL.
 9770 scrappy                  1082 EUB             :  */
                               1083                 : Datum
 1534 andres                   1084 CBC     2085528 : FunctionCall0Coll(FmgrInfo *flinfo, Oid collation)
                               1085                 : {
 1534 andres                   1086 GIC     2085528 :     LOCAL_FCINFO(fcinfo, 0);
                               1087                 :     Datum       result;
 1534 andres                   1088 ECB             : 
 1534 andres                   1089 GIC     2085528 :     InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL);
 1534 andres                   1090 ECB             : 
 1534 andres                   1091 GIC     2085528 :     result = FunctionCallInvoke(fcinfo);
                               1092                 : 
 1534 andres                   1093 ECB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1094 GIC     2085528 :     if (fcinfo->isnull)
 1534 andres                   1095 LBC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 1534 andres                   1096 ECB             : 
 1534 andres                   1097 GIC     2085528 :     return result;
 1534 andres                   1098 ECB             : }
                               1099                 : 
                               1100                 : Datum
 4380 tgl                      1101 CBC    47264307 : FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
 8351 tgl                      1102 EUB             : {
 1534 andres                   1103 GIC    47264307 :     LOCAL_FCINFO(fcinfo, 1);
 8053 bruce                    1104 ECB             :     Datum       result;
                               1105                 : 
 1534 andres                   1106 GIC    47264307 :     InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
                               1107                 : 
 1534 andres                   1108 CBC    47264307 :     fcinfo->args[0].value = arg1;
 1534 andres                   1109 GIC    47264307 :     fcinfo->args[0].isnull = false;
 8351 tgl                      1110 ECB             : 
 1534 andres                   1111 GIC    47264307 :     result = FunctionCallInvoke(fcinfo);
                               1112                 : 
 8351 tgl                      1113 ECB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1114 GIC    47263998 :     if (fcinfo->isnull)
 1534 andres                   1115 LBC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 8351 tgl                      1116 ECB             : 
 8351 tgl                      1117 CBC    47263998 :     return result;
 8351 tgl                      1118 ECB             : }
                               1119                 : 
                               1120                 : Datum
 4380 tgl                      1121 GIC   539069089 : FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
                               1122                 : {
 1534 andres                   1123 CBC   539069089 :     LOCAL_FCINFO(fcinfo, 2);
 8053 bruce                    1124 EUB             :     Datum       result;
                               1125                 : 
 1534 andres                   1126 CBC   539069089 :     InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
                               1127                 : 
 1534 andres                   1128 GIC   539069089 :     fcinfo->args[0].value = arg1;
                               1129       539069089 :     fcinfo->args[0].isnull = false;
 1534 andres                   1130 CBC   539069089 :     fcinfo->args[1].value = arg2;
 1534 andres                   1131 GIC   539069089 :     fcinfo->args[1].isnull = false;
                               1132                 : 
 1534 andres                   1133 CBC   539069089 :     result = FunctionCallInvoke(fcinfo);
                               1134                 : 
                               1135                 :     /* Check for null result, since caller is clearly not expecting one */
                               1136       539069030 :     if (fcinfo->isnull)
 1534 andres                   1137 UIC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 8351 tgl                      1138 ECB             : 
 8351 tgl                      1139 CBC   539069030 :     return result;
 8351 tgl                      1140 ECB             : }
                               1141                 : 
                               1142                 : Datum
 4380 tgl                      1143 CBC    23954770 : FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
                               1144                 :                   Datum arg3)
 8351 tgl                      1145 ECB             : {
 1534 andres                   1146 GIC    23954770 :     LOCAL_FCINFO(fcinfo, 3);
                               1147                 :     Datum       result;
 8351 tgl                      1148 ECB             : 
 1534 andres                   1149 GBC    23954770 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
                               1150                 : 
 1534 andres                   1151 CBC    23954770 :     fcinfo->args[0].value = arg1;
 1534 andres                   1152 GIC    23954770 :     fcinfo->args[0].isnull = false;
                               1153        23954770 :     fcinfo->args[1].value = arg2;
                               1154        23954770 :     fcinfo->args[1].isnull = false;
 1534 andres                   1155 CBC    23954770 :     fcinfo->args[2].value = arg3;
 1534 andres                   1156 GIC    23954770 :     fcinfo->args[2].isnull = false;
                               1157                 : 
 1534 andres                   1158 CBC    23954770 :     result = FunctionCallInvoke(fcinfo);
                               1159                 : 
                               1160                 :     /* Check for null result, since caller is clearly not expecting one */
                               1161        23954770 :     if (fcinfo->isnull)
 1534 andres                   1162 UIC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 8351 tgl                      1163 ECB             : 
 8351 tgl                      1164 CBC    23954770 :     return result;
 8351 tgl                      1165 ECB             : }
                               1166                 : 
                               1167                 : Datum
 4380 tgl                      1168 CBC      722548 : FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1169 ECB             :                   Datum arg3, Datum arg4)
 8351 tgl                      1170                 : {
 1534 andres                   1171 GIC      722548 :     LOCAL_FCINFO(fcinfo, 4);
 8053 bruce                    1172 ECB             :     Datum       result;
                               1173                 : 
 1534 andres                   1174 GIC      722548 :     InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL);
 6640 tgl                      1175 ECB             : 
 1534 andres                   1176 GBC      722548 :     fcinfo->args[0].value = arg1;
 1534 andres                   1177 GIC      722548 :     fcinfo->args[0].isnull = false;
 1534 andres                   1178 CBC      722548 :     fcinfo->args[1].value = arg2;
 1534 andres                   1179 GIC      722548 :     fcinfo->args[1].isnull = false;
                               1180          722548 :     fcinfo->args[2].value = arg3;
                               1181          722548 :     fcinfo->args[2].isnull = false;
 1534 andres                   1182 CBC      722548 :     fcinfo->args[3].value = arg4;
 1534 andres                   1183 GIC      722548 :     fcinfo->args[3].isnull = false;
                               1184                 : 
 1534 andres                   1185 CBC      722548 :     result = FunctionCallInvoke(fcinfo);
                               1186                 : 
                               1187                 :     /* Check for null result, since caller is clearly not expecting one */
                               1188          722536 :     if (fcinfo->isnull)
 1534 andres                   1189 UIC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 8351 tgl                      1190 ECB             : 
 8351 tgl                      1191 CBC      722536 :     return result;
 8351 tgl                      1192 ECB             : }
                               1193                 : 
                               1194                 : Datum
 4380 tgl                      1195 CBC     1060814 : FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1196 ECB             :                   Datum arg3, Datum arg4, Datum arg5)
 8351 tgl                      1197                 : {
 1534 andres                   1198 CBC     1060814 :     LOCAL_FCINFO(fcinfo, 5);
 8053 bruce                    1199 ECB             :     Datum       result;
                               1200                 : 
 1534 andres                   1201 CBC     1060814 :     InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL);
                               1202                 : 
 1534 andres                   1203 GIC     1060814 :     fcinfo->args[0].value = arg1;
 1534 andres                   1204 CBC     1060814 :     fcinfo->args[0].isnull = false;
 1534 andres                   1205 GBC     1060814 :     fcinfo->args[1].value = arg2;
 1534 andres                   1206 GIC     1060814 :     fcinfo->args[1].isnull = false;
 1534 andres                   1207 CBC     1060814 :     fcinfo->args[2].value = arg3;
 1534 andres                   1208 GIC     1060814 :     fcinfo->args[2].isnull = false;
                               1209         1060814 :     fcinfo->args[3].value = arg4;
                               1210         1060814 :     fcinfo->args[3].isnull = false;
 1534 andres                   1211 CBC     1060814 :     fcinfo->args[4].value = arg5;
 1534 andres                   1212 GIC     1060814 :     fcinfo->args[4].isnull = false;
                               1213                 : 
                               1214         1060814 :     result = FunctionCallInvoke(fcinfo);
 8351 tgl                      1215 ECB             : 
                               1216                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1217 GIC     1060796 :     if (fcinfo->isnull)
 1534 andres                   1218 LBC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
                               1219                 : 
 8351 tgl                      1220 CBC     1060796 :     return result;
 8351 tgl                      1221 ECB             : }
                               1222                 : 
                               1223                 : Datum
 4380 tgl                      1224 CBC        3545 : FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1225 ECB             :                   Datum arg3, Datum arg4, Datum arg5,
                               1226                 :                   Datum arg6)
 8351 tgl                      1227                 : {
 1534 andres                   1228 CBC        3545 :     LOCAL_FCINFO(fcinfo, 6);
 8053 bruce                    1229 ECB             :     Datum       result;
 8351 tgl                      1230                 : 
 1534 andres                   1231 CBC        3545 :     InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL);
                               1232                 : 
                               1233            3545 :     fcinfo->args[0].value = arg1;
 1534 andres                   1234 GIC        3545 :     fcinfo->args[0].isnull = false;
                               1235            3545 :     fcinfo->args[1].value = arg2;
 1534 andres                   1236 CBC        3545 :     fcinfo->args[1].isnull = false;
 1534 andres                   1237 GBC        3545 :     fcinfo->args[2].value = arg3;
 1534 andres                   1238 GIC        3545 :     fcinfo->args[2].isnull = false;
 1534 andres                   1239 CBC        3545 :     fcinfo->args[3].value = arg4;
 1534 andres                   1240 GIC        3545 :     fcinfo->args[3].isnull = false;
                               1241            3545 :     fcinfo->args[4].value = arg5;
                               1242            3545 :     fcinfo->args[4].isnull = false;
 1534 andres                   1243 CBC        3545 :     fcinfo->args[5].value = arg6;
 1534 andres                   1244 GIC        3545 :     fcinfo->args[5].isnull = false;
                               1245                 : 
                               1246            3545 :     result = FunctionCallInvoke(fcinfo);
 8351 tgl                      1247 ECB             : 
                               1248                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1249 GIC        2375 :     if (fcinfo->isnull)
 1534 andres                   1250 LBC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
                               1251                 : 
 8351 tgl                      1252 CBC        2375 :     return result;
 8351 tgl                      1253 ECB             : }
                               1254                 : 
                               1255                 : Datum
 4380 tgl                      1256 CBC      484834 : FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1257 ECB             :                   Datum arg3, Datum arg4, Datum arg5,
                               1258                 :                   Datum arg6, Datum arg7)
 9770 scrappy                  1259                 : {
 1534 andres                   1260 CBC      484834 :     LOCAL_FCINFO(fcinfo, 7);
 8053 bruce                    1261 ECB             :     Datum       result;
 8351 tgl                      1262                 : 
 1534 andres                   1263 CBC      484834 :     InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL);
 1534 andres                   1264 ECB             : 
 1534 andres                   1265 CBC      484834 :     fcinfo->args[0].value = arg1;
 1534 andres                   1266 GIC      484834 :     fcinfo->args[0].isnull = false;
 1534 andres                   1267 CBC      484834 :     fcinfo->args[1].value = arg2;
 1534 andres                   1268 GIC      484834 :     fcinfo->args[1].isnull = false;
                               1269          484834 :     fcinfo->args[2].value = arg3;
 1534 andres                   1270 CBC      484834 :     fcinfo->args[2].isnull = false;
 1534 andres                   1271 GBC      484834 :     fcinfo->args[3].value = arg4;
 1534 andres                   1272 GIC      484834 :     fcinfo->args[3].isnull = false;
 1534 andres                   1273 CBC      484834 :     fcinfo->args[4].value = arg5;
 1534 andres                   1274 GIC      484834 :     fcinfo->args[4].isnull = false;
                               1275          484834 :     fcinfo->args[5].value = arg6;
                               1276          484834 :     fcinfo->args[5].isnull = false;
 1534 andres                   1277 CBC      484834 :     fcinfo->args[6].value = arg7;
 1534 andres                   1278 GIC      484834 :     fcinfo->args[6].isnull = false;
                               1279                 : 
                               1280          484834 :     result = FunctionCallInvoke(fcinfo);
 8351 tgl                      1281 ECB             : 
                               1282                 :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1283 GIC      484834 :     if (fcinfo->isnull)
 1534 andres                   1284 LBC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
                               1285                 : 
 8351 tgl                      1286 CBC      484834 :     return result;
 8351 tgl                      1287 ECB             : }
                               1288                 : 
                               1289                 : Datum
 4380 tgl                      1290 CBC       18721 : FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1291 ECB             :                   Datum arg3, Datum arg4, Datum arg5,
                               1292                 :                   Datum arg6, Datum arg7, Datum arg8)
 8351 tgl                      1293                 : {
 1534 andres                   1294 CBC       18721 :     LOCAL_FCINFO(fcinfo, 8);
 8053 bruce                    1295 ECB             :     Datum       result;
 8351 tgl                      1296                 : 
 1534 andres                   1297 CBC       18721 :     InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL);
 1534 andres                   1298 ECB             : 
 1534 andres                   1299 CBC       18721 :     fcinfo->args[0].value = arg1;
                               1300           18721 :     fcinfo->args[0].isnull = false;
                               1301           18721 :     fcinfo->args[1].value = arg2;
 1534 andres                   1302 GIC       18721 :     fcinfo->args[1].isnull = false;
 1534 andres                   1303 CBC       18721 :     fcinfo->args[2].value = arg3;
 1534 andres                   1304 GIC       18721 :     fcinfo->args[2].isnull = false;
                               1305           18721 :     fcinfo->args[3].value = arg4;
 1534 andres                   1306 CBC       18721 :     fcinfo->args[3].isnull = false;
 1534 andres                   1307 GBC       18721 :     fcinfo->args[4].value = arg5;
 1534 andres                   1308 GIC       18721 :     fcinfo->args[4].isnull = false;
 1534 andres                   1309 CBC       18721 :     fcinfo->args[5].value = arg6;
 1534 andres                   1310 GIC       18721 :     fcinfo->args[5].isnull = false;
                               1311           18721 :     fcinfo->args[6].value = arg7;
                               1312           18721 :     fcinfo->args[6].isnull = false;
 1534 andres                   1313 GBC       18721 :     fcinfo->args[7].value = arg8;
 1534 andres                   1314 GIC       18721 :     fcinfo->args[7].isnull = false;
                               1315                 : 
                               1316           18721 :     result = FunctionCallInvoke(fcinfo);
                               1317                 : 
 8351 tgl                      1318 EUB             :     /* Check for null result, since caller is clearly not expecting one */
 1534 andres                   1319 GIC       18721 :     if (fcinfo->isnull)
 1534 andres                   1320 UIC           0 :         elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
 8351 tgl                      1321 EUB             : 
 8351 tgl                      1322 GIC       18721 :     return result;
 8351 tgl                      1323 EUB             : }
                               1324                 : 
                               1325                 : Datum
 4380 tgl                      1326 UBC           0 : FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
 4322 bruce                    1327 EUB             :                   Datum arg3, Datum arg4, Datum arg5,
                               1328                 :                   Datum arg6, Datum arg7, Datum arg8,
                               1329                 :                   Datum arg9)
 8351 tgl                      1330                 : {
 1534 andres                   1331 UBC           0 :     LOCAL_FCINFO(fcinfo, 9);
 8053 bruce                    1332 EUB             :     Datum       result;
 8351 tgl                      1333                 : 
 1534 andres                   1334 UBC           0 :     InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL);
 1534 andres                   1335 EUB             : 
 1534 andres                   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;
 1534 andres                   1341 UIC           0 :     fcinfo->args[2].isnull = false;
 1534 andres                   1342 UBC           0 :     fcinfo->args[3].value = arg4;
 1534 andres                   1343 UIC           0 :     fcinfo->args[3].isnull = false;
                               1344               0 :     fcinfo->args[4].value = arg5;
 1534 andres                   1345 UBC           0 :     fcinfo->args[4].isnull = false;
                               1346               0 :     fcinfo->args[5].value = arg6;
 1534 andres                   1347 UIC           0 :     fcinfo->args[5].isnull = false;
 1534 andres                   1348 UBC           0 :     fcinfo->args[6].value = arg7;
 1534 andres                   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);
 9345 bruce                    1360 ECB             : 
 8351 tgl                      1361 UIC           0 :     return result;
                               1362                 : }
                               1363                 : 
 8351 tgl                      1364 ECB             : 
                               1365                 : /*
 6640                          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,
 8351                          1370                 :  * do the fmgr_info() once and then use FunctionCallN().
                               1371                 :  */
                               1372                 : Datum
 4380 tgl                      1373 GIC     2085528 : OidFunctionCall0Coll(Oid functionId, Oid collation)
 4431 tgl                      1374 ECB             : {
                               1375                 :     FmgrInfo    flinfo;
                               1376                 : 
 4431 tgl                      1377 GIC     2085528 :     fmgr_info(functionId, &flinfo);
                               1378                 : 
 1534 andres                   1379         2085528 :     return FunctionCall0Coll(&flinfo, collation);
 4431 tgl                      1380 ECB             : }
                               1381                 : 
                               1382                 : Datum
 4380 tgl                      1383 GIC      615971 : OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
 8351 tgl                      1384 ECB             : {
                               1385                 :     FmgrInfo    flinfo;
                               1386                 : 
 8351 tgl                      1387 GIC      615971 :     fmgr_info(functionId, &flinfo);
                               1388                 : 
 1534 andres                   1389          615971 :     return FunctionCall1Coll(&flinfo, collation, arg1);
 8351 tgl                      1390 ECB             : }
                               1391                 : 
                               1392                 : Datum
 4380 tgl                      1393 GIC         475 : OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
                               1394                 : {
 8053 bruce                    1395 ECB             :     FmgrInfo    flinfo;
                               1396                 : 
 8351 tgl                      1397 CBC         475 :     fmgr_info(functionId, &flinfo);
                               1398                 : 
 1534 andres                   1399 GIC         475 :     return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
                               1400                 : }
 8351 tgl                      1401 ECB             : 
                               1402                 : Datum
 4380 tgl                      1403 GIC           2 : OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                               1404                 :                      Datum arg3)
                               1405                 : {
 8053 bruce                    1406 ECB             :     FmgrInfo    flinfo;
                               1407                 : 
 8351 tgl                      1408 CBC           2 :     fmgr_info(functionId, &flinfo);
                               1409                 : 
 1534 andres                   1410 GIC           2 :     return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
                               1411                 : }
 8351 tgl                      1412 ECB             : 
                               1413                 : Datum
 4380 tgl                      1414 GIC      252276 : OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                               1415                 :                      Datum arg3, Datum arg4)
                               1416                 : {
 8053 bruce                    1417 ECB             :     FmgrInfo    flinfo;
                               1418                 : 
 8351 tgl                      1419 CBC      252276 :     fmgr_info(functionId, &flinfo);
                               1420                 : 
 1534 andres                   1421 GIC      252276 :     return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
                               1422                 : }
 8351 tgl                      1423 ECB             : 
                               1424                 : Datum
 4380 tgl                      1425 GIC       83895 : OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
                               1426                 :                      Datum arg3, Datum arg4, Datum arg5)
                               1427                 : {
                               1428                 :     FmgrInfo    flinfo;
 8351 tgl                      1429 ECB             : 
 8351 tgl                      1430 GIC       83895 :     fmgr_info(functionId, &flinfo);
 8351 tgl                      1431 ECB             : 
 1534 andres                   1432 GIC       83895 :     return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
                               1433                 : }
                               1434                 : 
                               1435                 : Datum
 4380 tgl                      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                 : 
 8351                          1442            3383 :     fmgr_info(functionId, &flinfo);
                               1443                 : 
 1534 andres                   1444            3383 :     return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
                               1445                 :                              arg6);
                               1446                 : }
                               1447                 : 
                               1448                 : Datum
 4380 tgl                      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                 : 
 8351                          1455               0 :     fmgr_info(functionId, &flinfo);
                               1456                 : 
 1534 andres                   1457               0 :     return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
                               1458                 :                              arg6, arg7);
                               1459                 : }
                               1460                 : 
                               1461                 : Datum
 4380 tgl                      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                 : 
 8351 tgl                      1468 UIC           0 :     fmgr_info(functionId, &flinfo);
 8351 tgl                      1469 EUB             : 
 1534 andres                   1470 UIC           0 :     return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
 1534 andres                   1471 EUB             :                              arg6, arg7, arg8);
                               1472                 : }
                               1473                 : 
                               1474                 : Datum
 4380 tgl                      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                 : 
 8351                          1482               0 :     fmgr_info(functionId, &flinfo);
                               1483                 : 
 1534 andres                   1484               0 :     return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
                               1485                 :                              arg6, arg7, arg8, arg9);
                               1486                 : }
                               1487                 : 
                               1488                 : 
 6214 tgl                      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
 6214 tgl                      1502 CBC    49761250 : InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
 6214 tgl                      1503 ECB             : {
 1534 andres                   1504 CBC    49761250 :     LOCAL_FCINFO(fcinfo, 3);
                               1505                 :     Datum       result;
 6214 tgl                      1506 ECB             : 
 6214 tgl                      1507 GIC    49761250 :     if (str == NULL && flinfo->fn_strict)
                               1508         2314348 :         return (Datum) 0;       /* just return null result */
 6214 tgl                      1509 ECB             : 
 1534 andres                   1510 GIC    47446902 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
 6214 tgl                      1511 ECB             : 
 1534 andres                   1512 GBC    47446902 :     fcinfo->args[0].value = CStringGetDatum(str);
 1534 andres                   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);
 1534 andres                   1517 CBC    47446902 :     fcinfo->args[2].isnull = false;
 6214 tgl                      1518 EUB             : 
 1534 andres                   1519 GIC    47446902 :     result = FunctionCallInvoke(fcinfo);
                               1520                 : 
                               1521                 :     /* Should get null result if and only if str is NULL */
 6214 tgl                      1522 CBC    47444711 :     if (str == NULL)
                               1523                 :     {
 1534 andres                   1524 GIC          18 :         if (!fcinfo->isnull)
 6214 tgl                      1525 UIC           0 :             elog(ERROR, "input function %u returned non-NULL",
                               1526                 :                  flinfo->fn_oid);
                               1527                 :     }
                               1528                 :     else
                               1529                 :     {
 1534 andres                   1530 GIC    47444693 :         if (fcinfo->isnull)
 6214 tgl                      1531 UIC           0 :             elog(ERROR, "input function %u returned NULL",
                               1532                 :                  flinfo->fn_oid);
                               1533                 :     }
                               1534                 : 
 6214 tgl                      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
  121 tgl                      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                 :     {
  121 tgl                      1588 UNC           0 :         if (!fcinfo->isnull)
                               1589               0 :             elog(ERROR, "input function %u returned non-NULL",
                               1590                 :                  flinfo->fn_oid);
                               1591                 :     }
                               1592                 :     else
                               1593                 :     {
  121 tgl                      1594 GNC     2265754 :         if (fcinfo->isnull)
  121 tgl                      1595 UNC           0 :             elog(ERROR, "input function %u returned NULL",
                               1596                 :                  flinfo->fn_oid);
                               1597                 :     }
                               1598                 : 
  121 tgl                      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
  119                          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                 :     {
  119 tgl                      1621 UNC           0 :         *result = (Datum) 0;    /* just return null result */
                               1622               0 :         return true;
                               1623                 :     }
                               1624                 : 
  119 tgl                      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)
  119 tgl                      1642 UNC           0 :         elog(ERROR, "input function %p returned NULL", (void *) func);
                               1643                 : 
  119 tgl                      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.
 6214 tgl                      1653 ECB             :  */
                               1654                 : char *
 6214 tgl                      1655 GIC    19516625 : OutputFunctionCall(FmgrInfo *flinfo, Datum val)
                               1656                 : {
 2343                          1657        19516625 :     return DatumGetCString(FunctionCall1(flinfo, val));
 6214 tgl                      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
 2343                          1666                 :  * the same as FunctionCall3.
                               1667                 :  */
 6214                          1668                 : Datum
 6214 tgl                      1669 CBC      155538 : ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
 6214 tgl                      1670 ECB             :                     Oid typioparam, int32 typmod)
                               1671                 : {
 1534 andres                   1672 CBC      155538 :     LOCAL_FCINFO(fcinfo, 3);
 6214 tgl                      1673 ECB             :     Datum       result;
                               1674                 : 
 6214 tgl                      1675 CBC      155538 :     if (buf == NULL && flinfo->fn_strict)
 6214 tgl                      1676 GIC          15 :         return (Datum) 0;       /* just return null result */
                               1677                 : 
 1534 andres                   1678 CBC      155523 :     InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
 6214 tgl                      1679 ECB             : 
 1534 andres                   1680 GIC      155523 :     fcinfo->args[0].value = PointerGetDatum(buf);
                               1681          155523 :     fcinfo->args[0].isnull = false;
 1534 andres                   1682 CBC      155523 :     fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
 1534 andres                   1683 GIC      155523 :     fcinfo->args[1].isnull = false;
 1534 andres                   1684 GBC      155523 :     fcinfo->args[2].value = Int32GetDatum(typmod);
                               1685          155523 :     fcinfo->args[2].isnull = false;
                               1686                 : 
 1534 andres                   1687 GIC      155523 :     result = FunctionCallInvoke(fcinfo);
                               1688                 : 
                               1689                 :     /* Should get null result if and only if buf is NULL */
 6214 tgl                      1690 CBC      155523 :     if (buf == NULL)
 6214 tgl                      1691 EUB             :     {
 1534 andres                   1692 UIC           0 :         if (!fcinfo->isnull)
 6214 tgl                      1693               0 :             elog(ERROR, "receive function %u returned non-NULL",
                               1694                 :                  flinfo->fn_oid);
 6214 tgl                      1695 ECB             :     }
                               1696                 :     else
                               1697                 :     {
 1534 andres                   1698 GIC      155523 :         if (fcinfo->isnull)
 6214 tgl                      1699 UIC           0 :             elog(ERROR, "receive function %u returned NULL",
                               1700                 :                  flinfo->fn_oid);
                               1701                 :     }
                               1702                 : 
 6214 tgl                      1703 GIC      155523 :     return result;
                               1704                 : }
                               1705                 : 
                               1706                 : /*
                               1707                 :  * Call a previously-looked-up datatype binary-output function.
 6214 tgl                      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
 2343                          1713                 :  * function doesn't.
                               1714                 :  */
 6214                          1715                 : bytea *
 6214 tgl                      1716 GIC      123526 : SendFunctionCall(FmgrInfo *flinfo, Datum val)
 6214 tgl                      1717 EUB             : {
 2343 tgl                      1718 GBC      123526 :     return DatumGetByteaP(FunctionCall1(flinfo, val));
                               1719                 : }
                               1720                 : 
 6214 tgl                      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
 6214 tgl                      1726 CBC    39208096 : OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
 6214 tgl                      1727 ECB             : {
                               1728                 :     FmgrInfo    flinfo;
                               1729                 : 
 6214 tgl                      1730 CBC    39208096 :     fmgr_info(functionId, &flinfo);
 6214 tgl                      1731 GIC    39208096 :     return InputFunctionCall(&flinfo, str, typioparam, typmod);
                               1732                 : }
 6214 tgl                      1733 ECB             : 
                               1734                 : char *
 6214 tgl                      1735 GIC      510939 : OidOutputFunctionCall(Oid functionId, Datum val)
                               1736                 : {
 6214 tgl                      1737 ECB             :     FmgrInfo    flinfo;
 6214 tgl                      1738 EUB             : 
 6214 tgl                      1739 GIC      510939 :     fmgr_info(functionId, &flinfo);
 6214 tgl                      1740 CBC      510939 :     return OutputFunctionCall(&flinfo, val);
                               1741                 : }
                               1742                 : 
                               1743                 : Datum
 6214 tgl                      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);
 6214 tgl                      1751 ECB             : }
                               1752                 : 
                               1753                 : bytea *
 6214 tgl                      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
 8351 tgl                      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
 2412 heikki.linnakangas       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
 5466 tgl                      1771                 :  * both int8 and float8; this is to avoid making things unduly complicated
                               1772                 :  * for the timestamp types, which might have either representation.
                               1773                 :  *-------------------------------------------------------------------------
 8351                          1774                 :  */
                               1775                 : 
 5466                          1776                 : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
                               1777                 : 
 8351                          1778                 : Datum
                               1779                 : Int64GetDatum(int64 X)
                               1780                 : {
                               1781                 :     int64      *retval = (int64 *) palloc(sizeof(int64));
                               1782                 : 
                               1783                 :     *retval = X;
                               1784                 :     return PointerGetDatum(retval);
                               1785                 : }
 5466                          1786                 : 
                               1787                 : Datum
 8351 tgl                      1788 EUB             : Float8GetDatum(float8 X)
                               1789                 : {
                               1790                 :     float8     *retval = (float8 *) palloc(sizeof(float8));
                               1791                 : 
                               1792                 :     *retval = X;
                               1793                 :     return PointerGetDatum(retval);
 9770 scrappy                  1794 ECB             : }
 1235 peter                    1795 EUB             : #endif                          /* USE_FLOAT8_BYVAL */
                               1796                 : 
                               1797                 : 
                               1798                 : /*-------------------------------------------------------------------------
 8312 tgl                      1799 ECB             :  *      Support routines for toastable datatypes
                               1800                 :  *-------------------------------------------------------------------------
                               1801                 :  */
                               1802                 : 
                               1803                 : struct varlena *
 2118 tgl                      1804 GIC    54499802 : pg_detoast_datum(struct varlena *datum)
                               1805                 : {
 8312                          1806        54499802 :     if (VARATT_IS_EXTENDED(datum))
 1283 rhaas                    1807        16436975 :         return detoast_attr(datum);
                               1808                 :     else
 8312 tgl                      1809        38062827 :         return datum;
                               1810                 : }
                               1811                 : 
 8312 tgl                      1812 ECB             : struct varlena *
 2118 tgl                      1813 GIC     2462638 : pg_detoast_datum_copy(struct varlena *datum)
 8312 tgl                      1814 ECB             : {
 8312 tgl                      1815 GIC     2462638 :     if (VARATT_IS_EXTENDED(datum))
 1283 rhaas                    1816         1249274 :         return detoast_attr(datum);
                               1817                 :     else
                               1818                 :     {
                               1819                 :         /* Make a modifiable copy of the varlena object */
 8053 bruce                    1820         1213364 :         Size        len = VARSIZE(datum);
 8312 tgl                      1821         1213364 :         struct varlena *result = (struct varlena *) palloc(len);
 8312 tgl                      1822 ECB             : 
 8312 tgl                      1823 GIC     1213364 :         memcpy(result, datum, len);
                               1824         1213364 :         return result;
                               1825                 :     }
 8312 tgl                      1826 ECB             : }
 7705 bruce                    1827                 : 
                               1828                 : struct varlena *
 2118 tgl                      1829 GIC        2173 : pg_detoast_datum_slice(struct varlena *datum, int32 first, int32 count)
                               1830                 : {
 7705 bruce                    1831 ECB             :     /* Only get the specified portion from the toast rel */
 1283 rhaas                    1832 GIC        2173 :     return detoast_attr_slice(datum, first, count);
                               1833                 : }
                               1834                 : 
 5847 tgl                      1835 ECB             : struct varlena *
 2118 tgl                      1836 CBC   203513620 : pg_detoast_datum_packed(struct varlena *datum)
                               1837                 : {
 5847 tgl                      1838 GIC   203513620 :     if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
 1283 rhaas                    1839           68926 :         return detoast_attr(datum);
 5847 tgl                      1840 ECB             :     else
 5847 tgl                      1841 GIC   203444694 :         return datum;
                               1842                 : }
                               1843                 : 
                               1844                 : /*-------------------------------------------------------------------------
 7306 tgl                      1845 ECB             :  *      Support routines for extracting info from fn_expr parse tree
 7222                          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.
 3730                          1850                 :  * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
                               1851                 :  *-------------------------------------------------------------------------
                               1852                 :  */
                               1853                 : 
 7306                          1854                 : /*
 7222                          1855                 :  * Get the actual type OID of the function return type
                               1856                 :  *
                               1857                 :  * Returns InvalidOid if information is not available
                               1858                 :  */
                               1859                 : Oid
 7222 tgl                      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)
 7306 tgl                      1869 UIC           0 :         return InvalidOid;
                               1870                 : 
 7222 tgl                      1871 GIC       67383 :     expr = flinfo->fn_expr;
                               1872                 : 
 7306                          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
 7222                          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)
 7306 tgl                      1889 UIC           0 :         return InvalidOid;
                               1890                 : 
 6583 tgl                      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                 :  */
 6583 tgl                      1900 ECB             : Oid
 6583 tgl                      1901 GIC      934133 : get_call_expr_argtype(Node *expr, int argnum)
 6583 tgl                      1902 ECB             : {
                               1903                 :     List       *args;
                               1904                 :     Oid         argtype;
                               1905                 : 
 6583 tgl                      1906 GIC      934133 :     if (expr == NULL)
 6583 tgl                      1907 UIC           0 :         return InvalidOid;
                               1908                 : 
 7306 tgl                      1909 CBC      934133 :     if (IsA(expr, FuncExpr))
 7306 tgl                      1910 GIC      934112 :         args = ((FuncExpr *) expr)->args;
 7306 tgl                      1911 CBC          21 :     else if (IsA(expr, OpExpr))
                               1912              21 :         args = ((OpExpr *) expr)->args;
 7224 tgl                      1913 UIC           0 :     else if (IsA(expr, DistinctExpr))
                               1914               0 :         args = ((DistinctExpr *) expr)->args;
                               1915               0 :     else if (IsA(expr, ScalarArrayOpExpr))
 7224 tgl                      1916 LBC           0 :         args = ((ScalarArrayOpExpr *) expr)->args;
                               1917               0 :     else if (IsA(expr, NullIfExpr))
 7224 tgl                      1918 UIC           0 :         args = ((NullIfExpr *) expr)->args;
 5215 tgl                      1919 LBC           0 :     else if (IsA(expr, WindowFunc))
                               1920               0 :         args = ((WindowFunc *) expr)->args;
                               1921                 :     else
 7306 tgl                      1922 UIC           0 :         return InvalidOid;
                               1923                 : 
 6888 neilc                    1924 GIC      934133 :     if (argnum < 0 || argnum >= list_length(args))
 7306 tgl                      1925 LBC           0 :         return InvalidOid;
                               1926                 : 
 6888 neilc                    1927 GIC      934133 :     argtype = exprType((Node *) list_nth(args, argnum));
 7224 tgl                      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                 :      */
 7224 tgl                      1933 GIC      934133 :     if (IsA(expr, ScalarArrayOpExpr) &&
 7224 tgl                      1934 ECB             :         argnum == 1)
 4553 tgl                      1935 LBC           0 :         argtype = get_base_element_type(argtype);
                               1936                 : 
 7224 tgl                      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
 5215 tgl                      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)
 5215 tgl                      1954 UIC           0 :         return false;
                               1955                 : 
 5215 tgl                      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
 5215 tgl                      1964 ECB             :  */
 5215 tgl                      1965 EUB             : bool
 5215 tgl                      1966 GIC        1636 : get_call_expr_arg_stable(Node *expr, int argnum)
 5215 tgl                      1967 ECB             : {
                               1968                 :     List       *args;
                               1969                 :     Node       *arg;
                               1970                 : 
 5215 tgl                      1971 GIC        1636 :     if (expr == NULL)
 5215 tgl                      1972 UIC           0 :         return false;
                               1973                 : 
 5215 tgl                      1974 GIC        1636 :     if (IsA(expr, FuncExpr))
                               1975            1123 :         args = ((FuncExpr *) expr)->args;
                               1976             513 :     else if (IsA(expr, OpExpr))
 5215 tgl                      1977 UIC           0 :         args = ((OpExpr *) expr)->args;
 5215 tgl                      1978 CBC         513 :     else if (IsA(expr, DistinctExpr))
 5215 tgl                      1979 UIC           0 :         args = ((DistinctExpr *) expr)->args;
 5215 tgl                      1980 GIC         513 :     else if (IsA(expr, ScalarArrayOpExpr))
 5215 tgl                      1981 UIC           0 :         args = ((ScalarArrayOpExpr *) expr)->args;
 5215 tgl                      1982 GIC         513 :     else if (IsA(expr, NullIfExpr))
 5215 tgl                      1983 UIC           0 :         args = ((NullIfExpr *) expr)->args;
 5215 tgl                      1984 CBC         513 :     else if (IsA(expr, WindowFunc))
 5215 tgl                      1985 GBC         513 :         args = ((WindowFunc *) expr)->args;
                               1986                 :     else
 5215 tgl                      1987 LBC           0 :         return false;
                               1988                 : 
 5215 tgl                      1989 GIC        1636 :     if (argnum < 0 || argnum >= list_length(args))
 5215 tgl                      1990 UIC           0 :         return false;
                               1991                 : 
 5215 tgl                      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
 5050 bruce                    1997 ECB             :      * consider other cases too, e.g. now().
                               1998                 :      */
 5215 tgl                      1999 GIC        1636 :     if (IsA(arg, Const))
                               2000            1482 :         return true;
                               2001             154 :     if (IsA(arg, Param) &&
 5215 tgl                      2002 CBC           2 :         ((Param *) arg)->paramkind == PARAM_EXTERN)
 5215 tgl                      2003 UBC           0 :         return true;
                               2004                 : 
 5215 tgl                      2005 CBC         154 :     return false;
 5215 tgl                      2006 ECB             : }
 3730                          2007                 : 
                               2008                 : /*
 3730 tgl                      2009 EUB             :  * Get the VARIADIC flag from the function invocation
                               2010                 :  *
                               2011                 :  * Returns false (the default assumption) if information is not available
 3293                          2012                 :  *
                               2013                 :  * Note this is generally only of interest to VARIADIC ANY functions
 3730                          2014                 :  */
                               2015                 : bool
 3730 tgl                      2016 GBC       14064 : get_fn_expr_variadic(FmgrInfo *flinfo)
                               2017                 : {
 3730 tgl                      2018 EUB             :     Node       *expr;
                               2019                 : 
 3730 tgl                      2020 ECB             :     /*
 3730 tgl                      2021 EUB             :      * can't return anything useful if we have no FmgrInfo or if its fn_expr
                               2022                 :      * node has not been initialized
 3730 tgl                      2023 ECB             :      */
 3730 tgl                      2024 GIC       14064 :     if (!flinfo || !flinfo->fn_expr)
 3730 tgl                      2025 UIC           0 :         return false;
                               2026                 : 
 3730 tgl                      2027 GIC       14064 :     expr = flinfo->fn_expr;
                               2028                 : 
 3730 tgl                      2029 CBC       14064 :     if (IsA(expr, FuncExpr))
 3730 tgl                      2030 GIC       14064 :         return ((FuncExpr *) expr)->funcvariadic;
 3730 tgl                      2031 EUB             :     else
 3730 tgl                      2032 UIC           0 :         return false;
 3730 tgl                      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
 1105 akorotkov                2042 GIC      517345 : set_fn_opclass_options(FmgrInfo *flinfo, bytea *options)
 1105 akorotkov                2043 ECB             : {
 1105 akorotkov                2044 GIC      517345 :     flinfo->fn_expr = (Node *) makeConst(BYTEAOID, -1, InvalidOid, -1,
                               2045                 :                                          PointerGetDatum(options),
                               2046                 :                                          options == NULL, false);
                               2047          517345 : }
                               2048                 : 
 1105 akorotkov                2049 ECB             : /*
 1105 akorotkov                2050 EUB             :  * Check if options are defined for opclass support function.
                               2051                 :  */
 1105 akorotkov                2052 ECB             : bool
 1105 akorotkov                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                 :     }
 1105 akorotkov                2062 LBC           0 :     return false;
                               2063                 : }
                               2064                 : 
                               2065                 : /*
                               2066                 :  * Get options for opclass support function.
 1105 akorotkov                2067 ECB             :  */
 1105 akorotkov                2068 EUB             : bytea *
 1105 akorotkov                2069 GIC     2490227 : get_fn_opclass_options(FmgrInfo *flinfo)
 1105 akorotkov                2070 ECB             : {
 1105 akorotkov                2071 CBC     2490227 :     if (flinfo && flinfo->fn_expr && IsA(flinfo->fn_expr, Const))
 1105 akorotkov                2072 ECB             :     {
 1105 akorotkov                2073 GBC     2490227 :         Const      *expr = (Const *) flinfo->fn_expr;
 1105 akorotkov                2074 ECB             : 
 1105 akorotkov                2075 GBC     2490227 :         if (expr->consttype == BYTEAOID)
 1105 akorotkov                2076 CBC     2490227 :             return expr->constisnull ? NULL : DatumGetByteaP(expr->constvalue);
 1105 akorotkov                2077 EUB             :     }
 1105 akorotkov                2078 ECB             : 
 1105 akorotkov                2079 UBC           0 :     ereport(ERROR,
 1105 akorotkov                2080 ECB             :             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  937 peter                    2081                 :              errmsg("operator class options info is absent in function call context")));
                               2082                 : 
 1105 akorotkov                2083 EUB             :     return NULL;
                               2084                 : }
 1105 akorotkov                2085 ECB             : 
 3338 noah                     2086 EUB             : /*-------------------------------------------------------------------------
                               2087                 :  *      Support routines for procedural language implementations
 3338 noah                     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                 :  *
 3338 noah                     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
 3338 noah                     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
 3338 noah                     2117 GIC       35534 : CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
                               2118                 : {
                               2119                 :     HeapTuple   procTup;
 3338 noah                     2120 ECB             :     HeapTuple   langTup;
 3338 noah                     2121 EUB             :     Form_pg_proc procStruct;
                               2122                 :     Form_pg_language langStruct;
 3338 noah                     2123 ECB             :     AclResult   aclresult;
                               2124                 : 
 2403 tgl                      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.
 2403 tgl                      2128 EUB             :      */
 3338 noah                     2129 GIC       35534 :     procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionOid));
                               2130           35534 :     if (!HeapTupleIsValid(procTup))
 2403 tgl                      2131 UIC           0 :         ereport(ERROR,
                               2132                 :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
                               2133                 :                  errmsg("function with OID %u does not exist", functionOid)));
 3338 noah                     2134 GIC       35534 :     procStruct = (Form_pg_proc) GETSTRUCT(procTup);
                               2135                 : 
                               2136                 :     /*
                               2137                 :      * Fetch pg_language entry to know if this is the correct validation
 3338 noah                     2138 ECB             :      * function for that pg_proc entry.
                               2139                 :      */
 3338 noah                     2140 CBC       35534 :     langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(procStruct->prolang));
 3338 noah                     2141 GIC       35534 :     if (!HeapTupleIsValid(langTup))
 3338 noah                     2142 UIC           0 :         elog(ERROR, "cache lookup failed for language %u", procStruct->prolang);
 3338 noah                     2143 CBC       35534 :     langStruct = (Form_pg_language) GETSTRUCT(langTup);
                               2144                 : 
 3338 noah                     2145 GIC       35534 :     if (langStruct->lanvalidator != validatorOid)
 3338 noah                     2146 UIC           0 :         ereport(ERROR,
                               2147                 :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                               2148                 :                  errmsg("language validation function %u called for language %u instead of %u",
 3338 noah                     2149 ECB             :                         validatorOid, procStruct->prolang,
                               2150                 :                         langStruct->lanvalidator)));
                               2151                 : 
                               2152                 :     /* first validate that we have permissions to use the language */
  147 peter                    2153 GNC       35534 :     aclresult = object_aclcheck(LanguageRelationId, procStruct->prolang, GetUserId(),
                               2154                 :                                      ACL_USAGE);
 3338 noah                     2155 CBC       35534 :     if (aclresult != ACLCHECK_OK)
 1954 peter_e                  2156 LBC           0 :         aclcheck_error(aclresult, OBJECT_LANGUAGE,
 3338 noah                     2157 UIC           0 :                        NameStr(langStruct->lanname));
 3338 noah                     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                 :      */
  147 peter                    2164 GNC       35534 :     aclresult = object_aclcheck(ProcedureRelationId, functionOid, GetUserId(), ACL_EXECUTE);
 3338 noah                     2165 CBC       35534 :     if (aclresult != ACLCHECK_OK)
 1954 peter_e                  2166 UIC           0 :         aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
 3338 noah                     2167 ECB             : 
 3338 noah                     2168 GIC       35534 :     ReleaseSysCache(procTup);
 3338 noah                     2169 CBC       35534 :     ReleaseSysCache(langTup);
                               2170                 : 
                               2171           35534 :     return true;
 3338 noah                     2172 ECB             : }
        

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