Header And Logo

PostgreSQL
| The world's most advanced open source database.

fmgr.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * fmgr.c
00004  *    The Postgres function manager.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/utils/fmgr/fmgr.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #include "postgres.h"
00017 
00018 #include "access/tuptoaster.h"
00019 #include "catalog/pg_language.h"
00020 #include "catalog/pg_proc.h"
00021 #include "executor/functions.h"
00022 #include "executor/spi.h"
00023 #include "lib/stringinfo.h"
00024 #include "miscadmin.h"
00025 #include "nodes/nodeFuncs.h"
00026 #include "pgstat.h"
00027 #include "utils/builtins.h"
00028 #include "utils/fmgrtab.h"
00029 #include "utils/guc.h"
00030 #include "utils/lsyscache.h"
00031 #include "utils/syscache.h"
00032 
00033 /*
00034  * Hooks for function calls
00035  */
00036 PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook = NULL;
00037 PGDLLIMPORT fmgr_hook_type fmgr_hook = NULL;
00038 
00039 /*
00040  * Declaration for old-style function pointer type.  This is now used only
00041  * in fmgr_oldstyle() and is no longer exported.
00042  *
00043  * The m68k SVR4 ABI defines that pointers are returned in %a0 instead of
00044  * %d0. So if a function pointer is declared to return a pointer, the
00045  * compiler may look only into %a0, but if the called function was declared
00046  * to return an integer type, it puts its value only into %d0. So the
00047  * caller doesn't pick up the correct return value. The solution is to
00048  * declare the function pointer to return int, so the compiler picks up the
00049  * return value from %d0. (Functions returning pointers put their value
00050  * *additionally* into %d0 for compatibility.) The price is that there are
00051  * some warnings about int->pointer conversions ... which we can suppress
00052  * with suitably ugly casts in fmgr_oldstyle().
00053  */
00054 #if (defined(__mc68000__) || (defined(__m68k__))) && defined(__ELF__)
00055 typedef int32 (*func_ptr) ();
00056 #else
00057 typedef char *(*func_ptr) ();
00058 #endif
00059 
00060 /*
00061  * For an oldstyle function, fn_extra points to a record like this:
00062  */
00063 typedef struct
00064 {
00065     func_ptr    func;           /* Address of the oldstyle function */
00066     bool        arg_toastable[FUNC_MAX_ARGS];   /* is n'th arg of a toastable
00067                                                  * datatype? */
00068 } Oldstyle_fnextra;
00069 
00070 /*
00071  * Hashtable for fast lookup of external C functions
00072  */
00073 typedef struct
00074 {
00075     /* fn_oid is the hash key and so must be first! */
00076     Oid         fn_oid;         /* OID of an external C function */
00077     TransactionId fn_xmin;      /* for checking up-to-dateness */
00078     ItemPointerData fn_tid;
00079     PGFunction  user_fn;        /* the function's address */
00080     const Pg_finfo_record *inforec;     /* address of its info record */
00081 } CFuncHashTabEntry;
00082 
00083 static HTAB *CFuncHash = NULL;
00084 
00085 
00086 static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
00087                        bool ignore_security);
00088 static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
00089 static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
00090 static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
00091 static void record_C_func(HeapTuple procedureTuple,
00092               PGFunction user_fn, const Pg_finfo_record *inforec);
00093 static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
00094 static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
00095 
00096 
00097 /*
00098  * Lookup routines for builtin-function table.  We can search by either Oid
00099  * or name, but search by Oid is much faster.
00100  */
00101 
00102 static const FmgrBuiltin *
00103 fmgr_isbuiltin(Oid id)
00104 {
00105     int         low = 0;
00106     int         high = fmgr_nbuiltins - 1;
00107 
00108     /*
00109      * Loop invariant: low is the first index that could contain target entry,
00110      * and high is the last index that could contain it.
00111      */
00112     while (low <= high)
00113     {
00114         int         i = (high + low) / 2;
00115         const FmgrBuiltin *ptr = &fmgr_builtins[i];
00116 
00117         if (id == ptr->foid)
00118             return ptr;
00119         else if (id > ptr->foid)
00120             low = i + 1;
00121         else
00122             high = i - 1;
00123     }
00124     return NULL;
00125 }
00126 
00127 /*
00128  * Lookup a builtin by name.  Note there can be more than one entry in
00129  * the array with the same name, but they should all point to the same
00130  * routine.
00131  */
00132 static const FmgrBuiltin *
00133 fmgr_lookupByName(const char *name)
00134 {
00135     int         i;
00136 
00137     for (i = 0; i < fmgr_nbuiltins; i++)
00138     {
00139         if (strcmp(name, fmgr_builtins[i].funcName) == 0)
00140             return fmgr_builtins + i;
00141     }
00142     return NULL;
00143 }
00144 
00145 /*
00146  * This routine fills a FmgrInfo struct, given the OID
00147  * of the function to be called.
00148  *
00149  * The caller's CurrentMemoryContext is used as the fn_mcxt of the info
00150  * struct; this means that any subsidiary data attached to the info struct
00151  * (either by fmgr_info itself, or later on by a function call handler)
00152  * will be allocated in that context.  The caller must ensure that this
00153  * context is at least as long-lived as the info struct itself.  This is
00154  * not a problem in typical cases where the info struct is on the stack or
00155  * in freshly-palloc'd space.  However, if one intends to store an info
00156  * struct in a long-lived table, it's better to use fmgr_info_cxt.
00157  */
00158 void
00159 fmgr_info(Oid functionId, FmgrInfo *finfo)
00160 {
00161     fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
00162 }
00163 
00164 /*
00165  * Fill a FmgrInfo struct, specifying a memory context in which its
00166  * subsidiary data should go.
00167  */
00168 void
00169 fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
00170 {
00171     fmgr_info_cxt_security(functionId, finfo, mcxt, false);
00172 }
00173 
00174 /*
00175  * This one does the actual work.  ignore_security is ordinarily false
00176  * but is set to true when we need to avoid recursion.
00177  */
00178 static void
00179 fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
00180                        bool ignore_security)
00181 {
00182     const FmgrBuiltin *fbp;
00183     HeapTuple   procedureTuple;
00184     Form_pg_proc procedureStruct;
00185     Datum       prosrcdatum;
00186     bool        isnull;
00187     char       *prosrc;
00188 
00189     /*
00190      * fn_oid *must* be filled in last.  Some code assumes that if fn_oid is
00191      * valid, the whole struct is valid.  Some FmgrInfo struct's do survive
00192      * elogs.
00193      */
00194     finfo->fn_oid = InvalidOid;
00195     finfo->fn_extra = NULL;
00196     finfo->fn_mcxt = mcxt;
00197     finfo->fn_expr = NULL;      /* caller may set this later */
00198 
00199     if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
00200     {
00201         /*
00202          * Fast path for builtin functions: don't bother consulting pg_proc
00203          */
00204         finfo->fn_nargs = fbp->nargs;
00205         finfo->fn_strict = fbp->strict;
00206         finfo->fn_retset = fbp->retset;
00207         finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
00208         finfo->fn_addr = fbp->func;
00209         finfo->fn_oid = functionId;
00210         return;
00211     }
00212 
00213     /* Otherwise we need the pg_proc entry */
00214     procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
00215     if (!HeapTupleIsValid(procedureTuple))
00216         elog(ERROR, "cache lookup failed for function %u", functionId);
00217     procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
00218 
00219     finfo->fn_nargs = procedureStruct->pronargs;
00220     finfo->fn_strict = procedureStruct->proisstrict;
00221     finfo->fn_retset = procedureStruct->proretset;
00222 
00223     /*
00224      * If it has prosecdef set, non-null proconfig, or if a plugin wants to
00225      * hook function entry/exit, use fmgr_security_definer call handler ---
00226      * unless we are being called again by fmgr_security_definer or
00227      * fmgr_info_other_lang.
00228      *
00229      * When using fmgr_security_definer, function stats tracking is always
00230      * disabled at the outer level, and instead we set the flag properly in
00231      * fmgr_security_definer's private flinfo and implement the tracking
00232      * inside fmgr_security_definer.  This loses the ability to charge the
00233      * overhead of fmgr_security_definer to the function, but gains the
00234      * ability to set the track_functions GUC as a local GUC parameter of an
00235      * interesting function and have the right things happen.
00236      */
00237     if (!ignore_security &&
00238         (procedureStruct->prosecdef ||
00239          !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig) ||
00240          FmgrHookIsNeeded(functionId)))
00241     {
00242         finfo->fn_addr = fmgr_security_definer;
00243         finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
00244         finfo->fn_oid = functionId;
00245         ReleaseSysCache(procedureTuple);
00246         return;
00247     }
00248 
00249     switch (procedureStruct->prolang)
00250     {
00251         case INTERNALlanguageId:
00252 
00253             /*
00254              * For an ordinary builtin function, we should never get here
00255              * because the isbuiltin() search above will have succeeded.
00256              * However, if the user has done a CREATE FUNCTION to create an
00257              * alias for a builtin function, we can end up here.  In that case
00258              * we have to look up the function by name.  The name of the
00259              * internal function is stored in prosrc (it doesn't have to be
00260              * the same as the name of the alias!)
00261              */
00262             prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
00263                                           Anum_pg_proc_prosrc, &isnull);
00264             if (isnull)
00265                 elog(ERROR, "null prosrc");
00266             prosrc = TextDatumGetCString(prosrcdatum);
00267             fbp = fmgr_lookupByName(prosrc);
00268             if (fbp == NULL)
00269                 ereport(ERROR,
00270                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
00271                          errmsg("internal function \"%s\" is not in internal lookup table",
00272                                 prosrc)));
00273             pfree(prosrc);
00274             /* Should we check that nargs, strict, retset match the table? */
00275             finfo->fn_addr = fbp->func;
00276             /* note this policy is also assumed in fast path above */
00277             finfo->fn_stats = TRACK_FUNC_ALL;   /* ie, never track */
00278             break;
00279 
00280         case ClanguageId:
00281             fmgr_info_C_lang(functionId, finfo, procedureTuple);
00282             finfo->fn_stats = TRACK_FUNC_PL;    /* ie, track if ALL */
00283             break;
00284 
00285         case SQLlanguageId:
00286             finfo->fn_addr = fmgr_sql;
00287             finfo->fn_stats = TRACK_FUNC_PL;    /* ie, track if ALL */
00288             break;
00289 
00290         default:
00291             fmgr_info_other_lang(functionId, finfo, procedureTuple);
00292             finfo->fn_stats = TRACK_FUNC_OFF;   /* ie, track if not OFF */
00293             break;
00294     }
00295 
00296     finfo->fn_oid = functionId;
00297     ReleaseSysCache(procedureTuple);
00298 }
00299 
00300 /*
00301  * Special fmgr_info processing for C-language functions.  Note that
00302  * finfo->fn_oid is not valid yet.
00303  */
00304 static void
00305 fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
00306 {
00307     Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
00308     CFuncHashTabEntry *hashentry;
00309     PGFunction  user_fn;
00310     const Pg_finfo_record *inforec;
00311     Oldstyle_fnextra *fnextra;
00312     bool        isnull;
00313     int         i;
00314 
00315     /*
00316      * See if we have the function address cached already
00317      */
00318     hashentry = lookup_C_func(procedureTuple);
00319     if (hashentry)
00320     {
00321         user_fn = hashentry->user_fn;
00322         inforec = hashentry->inforec;
00323     }
00324     else
00325     {
00326         Datum       prosrcattr,
00327                     probinattr;
00328         char       *prosrcstring,
00329                    *probinstring;
00330         void       *libraryhandle;
00331 
00332         /*
00333          * Get prosrc and probin strings (link symbol and library filename).
00334          * While in general these columns might be null, that's not allowed
00335          * for C-language functions.
00336          */
00337         prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
00338                                      Anum_pg_proc_prosrc, &isnull);
00339         if (isnull)
00340             elog(ERROR, "null prosrc for C function %u", functionId);
00341         prosrcstring = TextDatumGetCString(prosrcattr);
00342 
00343         probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
00344                                      Anum_pg_proc_probin, &isnull);
00345         if (isnull)
00346             elog(ERROR, "null probin for C function %u", functionId);
00347         probinstring = TextDatumGetCString(probinattr);
00348 
00349         /* Look up the function itself */
00350         user_fn = load_external_function(probinstring, prosrcstring, true,
00351                                          &libraryhandle);
00352 
00353         /* Get the function information record (real or default) */
00354         inforec = fetch_finfo_record(libraryhandle, prosrcstring);
00355 
00356         /* Cache the addresses for later calls */
00357         record_C_func(procedureTuple, user_fn, inforec);
00358 
00359         pfree(prosrcstring);
00360         pfree(probinstring);
00361     }
00362 
00363     switch (inforec->api_version)
00364     {
00365         case 0:
00366             /* Old style: need to use a handler */
00367             finfo->fn_addr = fmgr_oldstyle;
00368             fnextra = (Oldstyle_fnextra *)
00369                 MemoryContextAllocZero(finfo->fn_mcxt,
00370                                        sizeof(Oldstyle_fnextra));
00371             finfo->fn_extra = (void *) fnextra;
00372             fnextra->func = (func_ptr) user_fn;
00373             for (i = 0; i < procedureStruct->pronargs; i++)
00374             {
00375                 fnextra->arg_toastable[i] =
00376                     TypeIsToastable(procedureStruct->proargtypes.values[i]);
00377             }
00378             break;
00379         case 1:
00380             /* New style: call directly */
00381             finfo->fn_addr = user_fn;
00382             break;
00383         default:
00384             /* Shouldn't get here if fetch_finfo_record did its job */
00385             elog(ERROR, "unrecognized function API version: %d",
00386                  inforec->api_version);
00387             break;
00388     }
00389 }
00390 
00391 /*
00392  * Special fmgr_info processing for other-language functions.  Note
00393  * that finfo->fn_oid is not valid yet.
00394  */
00395 static void
00396 fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
00397 {
00398     Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
00399     Oid         language = procedureStruct->prolang;
00400     HeapTuple   languageTuple;
00401     Form_pg_language languageStruct;
00402     FmgrInfo    plfinfo;
00403 
00404     languageTuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(language));
00405     if (!HeapTupleIsValid(languageTuple))
00406         elog(ERROR, "cache lookup failed for language %u", language);
00407     languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
00408 
00409     /*
00410      * Look up the language's call handler function, ignoring any attributes
00411      * that would normally cause insertion of fmgr_security_definer.  We need
00412      * to get back a bare pointer to the actual C-language function.
00413      */
00414     fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
00415                            CurrentMemoryContext, true);
00416     finfo->fn_addr = plfinfo.fn_addr;
00417 
00418     /*
00419      * If lookup of the PL handler function produced nonnull fn_extra,
00420      * complain --- it must be an oldstyle function! We no longer support
00421      * oldstyle PL handlers.
00422      */
00423     if (plfinfo.fn_extra != NULL)
00424         elog(ERROR, "language %u has old-style handler", language);
00425 
00426     ReleaseSysCache(languageTuple);
00427 }
00428 
00429 /*
00430  * Fetch and validate the information record for the given external function.
00431  * The function is specified by a handle for the containing library
00432  * (obtained from load_external_function) as well as the function name.
00433  *
00434  * If no info function exists for the given name, it is not an error.
00435  * Instead we return a default info record for a version-0 function.
00436  * We want to raise an error here only if the info function returns
00437  * something bogus.
00438  *
00439  * This function is broken out of fmgr_info_C_lang so that fmgr_c_validator
00440  * can validate the information record for a function not yet entered into
00441  * pg_proc.
00442  */
00443 const Pg_finfo_record *
00444 fetch_finfo_record(void *filehandle, char *funcname)
00445 {
00446     char       *infofuncname;
00447     PGFInfoFunction infofunc;
00448     const Pg_finfo_record *inforec;
00449     static Pg_finfo_record default_inforec = {0};
00450 
00451     /* Compute name of info func */
00452     infofuncname = (char *) palloc(strlen(funcname) + 10);
00453     strcpy(infofuncname, "pg_finfo_");
00454     strcat(infofuncname, funcname);
00455 
00456     /* Try to look up the info function */
00457     infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
00458                                                           infofuncname);
00459     if (infofunc == NULL)
00460     {
00461         /* Not found --- assume version 0 */
00462         pfree(infofuncname);
00463         return &default_inforec;
00464     }
00465 
00466     /* Found, so call it */
00467     inforec = (*infofunc) ();
00468 
00469     /* Validate result as best we can */
00470     if (inforec == NULL)
00471         elog(ERROR, "null result from info function \"%s\"", infofuncname);
00472     switch (inforec->api_version)
00473     {
00474         case 0:
00475         case 1:
00476             /* OK, no additional fields to validate */
00477             break;
00478         default:
00479             ereport(ERROR,
00480                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00481                      errmsg("unrecognized API version %d reported by info function \"%s\"",
00482                             inforec->api_version, infofuncname)));
00483             break;
00484     }
00485 
00486     pfree(infofuncname);
00487     return inforec;
00488 }
00489 
00490 
00491 /*-------------------------------------------------------------------------
00492  *      Routines for caching lookup information for external C functions.
00493  *
00494  * The routines in dfmgr.c are relatively slow, so we try to avoid running
00495  * them more than once per external function per session.  We use a hash table
00496  * with the function OID as the lookup key.
00497  *-------------------------------------------------------------------------
00498  */
00499 
00500 /*
00501  * lookup_C_func: try to find a C function in the hash table
00502  *
00503  * If an entry exists and is up to date, return it; else return NULL
00504  */
00505 static CFuncHashTabEntry *
00506 lookup_C_func(HeapTuple procedureTuple)
00507 {
00508     Oid         fn_oid = HeapTupleGetOid(procedureTuple);
00509     CFuncHashTabEntry *entry;
00510 
00511     if (CFuncHash == NULL)
00512         return NULL;            /* no table yet */
00513     entry = (CFuncHashTabEntry *)
00514         hash_search(CFuncHash,
00515                     &fn_oid,
00516                     HASH_FIND,
00517                     NULL);
00518     if (entry == NULL)
00519         return NULL;            /* no such entry */
00520     if (entry->fn_xmin == HeapTupleHeaderGetXmin(procedureTuple->t_data) &&
00521         ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
00522         return entry;           /* OK */
00523     return NULL;                /* entry is out of date */
00524 }
00525 
00526 /*
00527  * record_C_func: enter (or update) info about a C function in the hash table
00528  */
00529 static void
00530 record_C_func(HeapTuple procedureTuple,
00531               PGFunction user_fn, const Pg_finfo_record *inforec)
00532 {
00533     Oid         fn_oid = HeapTupleGetOid(procedureTuple);
00534     CFuncHashTabEntry *entry;
00535     bool        found;
00536 
00537     /* Create the hash table if it doesn't exist yet */
00538     if (CFuncHash == NULL)
00539     {
00540         HASHCTL     hash_ctl;
00541 
00542         MemSet(&hash_ctl, 0, sizeof(hash_ctl));
00543         hash_ctl.keysize = sizeof(Oid);
00544         hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
00545         hash_ctl.hash = oid_hash;
00546         CFuncHash = hash_create("CFuncHash",
00547                                 100,
00548                                 &hash_ctl,
00549                                 HASH_ELEM | HASH_FUNCTION);
00550     }
00551 
00552     entry = (CFuncHashTabEntry *)
00553         hash_search(CFuncHash,
00554                     &fn_oid,
00555                     HASH_ENTER,
00556                     &found);
00557     /* OID is already filled in */
00558     entry->fn_xmin = HeapTupleHeaderGetXmin(procedureTuple->t_data);
00559     entry->fn_tid = procedureTuple->t_self;
00560     entry->user_fn = user_fn;
00561     entry->inforec = inforec;
00562 }
00563 
00564 /*
00565  * clear_external_function_hash: remove entries for a library being closed
00566  *
00567  * Presently we just zap the entire hash table, but later it might be worth
00568  * the effort to remove only the entries associated with the given handle.
00569  */
00570 void
00571 clear_external_function_hash(void *filehandle)
00572 {
00573     if (CFuncHash)
00574         hash_destroy(CFuncHash);
00575     CFuncHash = NULL;
00576 }
00577 
00578 
00579 /*
00580  * Copy an FmgrInfo struct
00581  *
00582  * This is inherently somewhat bogus since we can't reliably duplicate
00583  * language-dependent subsidiary info.  We cheat by zeroing fn_extra,
00584  * instead, meaning that subsidiary info will have to be recomputed.
00585  */
00586 void
00587 fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
00588                MemoryContext destcxt)
00589 {
00590     memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
00591     dstinfo->fn_mcxt = destcxt;
00592     if (dstinfo->fn_addr == fmgr_oldstyle)
00593     {
00594         /* For oldstyle functions we must copy fn_extra */
00595         Oldstyle_fnextra *fnextra;
00596 
00597         fnextra = (Oldstyle_fnextra *)
00598             MemoryContextAlloc(destcxt, sizeof(Oldstyle_fnextra));
00599         memcpy(fnextra, srcinfo->fn_extra, sizeof(Oldstyle_fnextra));
00600         dstinfo->fn_extra = (void *) fnextra;
00601     }
00602     else
00603         dstinfo->fn_extra = NULL;
00604 }
00605 
00606 
00607 /*
00608  * Specialized lookup routine for fmgr_internal_validator: given the alleged
00609  * name of an internal function, return the OID of the function.
00610  * If the name is not recognized, return InvalidOid.
00611  */
00612 Oid
00613 fmgr_internal_function(const char *proname)
00614 {
00615     const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
00616 
00617     if (fbp == NULL)
00618         return InvalidOid;
00619     return fbp->foid;
00620 }
00621 
00622 
00623 /*
00624  * Handler for old-style "C" language functions
00625  */
00626 static Datum
00627 fmgr_oldstyle(PG_FUNCTION_ARGS)
00628 {
00629     Oldstyle_fnextra *fnextra;
00630     int         n_arguments = fcinfo->nargs;
00631     int         i;
00632     bool        isnull;
00633     func_ptr    user_fn;
00634     char       *returnValue;
00635 
00636     if (fcinfo->flinfo == NULL || fcinfo->flinfo->fn_extra == NULL)
00637         elog(ERROR, "fmgr_oldstyle received NULL pointer");
00638     fnextra = (Oldstyle_fnextra *) fcinfo->flinfo->fn_extra;
00639 
00640     /*
00641      * Result is NULL if any argument is NULL, but we still call the function
00642      * (peculiar, but that's the way it worked before, and after all this is a
00643      * backwards-compatibility wrapper).  Note, however, that we'll never get
00644      * here with NULL arguments if the function is marked strict.
00645      *
00646      * We also need to detoast any TOAST-ed inputs, since it's unlikely that
00647      * an old-style function knows about TOASTing.
00648      */
00649     isnull = false;
00650     for (i = 0; i < n_arguments; i++)
00651     {
00652         if (PG_ARGISNULL(i))
00653             isnull = true;
00654         else if (fnextra->arg_toastable[i])
00655             fcinfo->arg[i] = PointerGetDatum(PG_DETOAST_DATUM(fcinfo->arg[i]));
00656     }
00657     fcinfo->isnull = isnull;
00658 
00659     user_fn = fnextra->func;
00660 
00661     switch (n_arguments)
00662     {
00663         case 0:
00664             returnValue = (char *) (*user_fn) ();
00665             break;
00666         case 1:
00667 
00668             /*
00669              * nullvalue() used to use isNull to check if arg is NULL; perhaps
00670              * there are other functions still out there that also rely on
00671              * this undocumented hack?
00672              */
00673             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00674                                                &fcinfo->isnull);
00675             break;
00676         case 2:
00677             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00678                                                fcinfo->arg[1]);
00679             break;
00680         case 3:
00681             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00682                                                fcinfo->arg[1],
00683                                                fcinfo->arg[2]);
00684             break;
00685         case 4:
00686             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00687                                                fcinfo->arg[1],
00688                                                fcinfo->arg[2],
00689                                                fcinfo->arg[3]);
00690             break;
00691         case 5:
00692             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00693                                                fcinfo->arg[1],
00694                                                fcinfo->arg[2],
00695                                                fcinfo->arg[3],
00696                                                fcinfo->arg[4]);
00697             break;
00698         case 6:
00699             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00700                                                fcinfo->arg[1],
00701                                                fcinfo->arg[2],
00702                                                fcinfo->arg[3],
00703                                                fcinfo->arg[4],
00704                                                fcinfo->arg[5]);
00705             break;
00706         case 7:
00707             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00708                                                fcinfo->arg[1],
00709                                                fcinfo->arg[2],
00710                                                fcinfo->arg[3],
00711                                                fcinfo->arg[4],
00712                                                fcinfo->arg[5],
00713                                                fcinfo->arg[6]);
00714             break;
00715         case 8:
00716             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00717                                                fcinfo->arg[1],
00718                                                fcinfo->arg[2],
00719                                                fcinfo->arg[3],
00720                                                fcinfo->arg[4],
00721                                                fcinfo->arg[5],
00722                                                fcinfo->arg[6],
00723                                                fcinfo->arg[7]);
00724             break;
00725         case 9:
00726             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00727                                                fcinfo->arg[1],
00728                                                fcinfo->arg[2],
00729                                                fcinfo->arg[3],
00730                                                fcinfo->arg[4],
00731                                                fcinfo->arg[5],
00732                                                fcinfo->arg[6],
00733                                                fcinfo->arg[7],
00734                                                fcinfo->arg[8]);
00735             break;
00736         case 10:
00737             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00738                                                fcinfo->arg[1],
00739                                                fcinfo->arg[2],
00740                                                fcinfo->arg[3],
00741                                                fcinfo->arg[4],
00742                                                fcinfo->arg[5],
00743                                                fcinfo->arg[6],
00744                                                fcinfo->arg[7],
00745                                                fcinfo->arg[8],
00746                                                fcinfo->arg[9]);
00747             break;
00748         case 11:
00749             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00750                                                fcinfo->arg[1],
00751                                                fcinfo->arg[2],
00752                                                fcinfo->arg[3],
00753                                                fcinfo->arg[4],
00754                                                fcinfo->arg[5],
00755                                                fcinfo->arg[6],
00756                                                fcinfo->arg[7],
00757                                                fcinfo->arg[8],
00758                                                fcinfo->arg[9],
00759                                                fcinfo->arg[10]);
00760             break;
00761         case 12:
00762             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00763                                                fcinfo->arg[1],
00764                                                fcinfo->arg[2],
00765                                                fcinfo->arg[3],
00766                                                fcinfo->arg[4],
00767                                                fcinfo->arg[5],
00768                                                fcinfo->arg[6],
00769                                                fcinfo->arg[7],
00770                                                fcinfo->arg[8],
00771                                                fcinfo->arg[9],
00772                                                fcinfo->arg[10],
00773                                                fcinfo->arg[11]);
00774             break;
00775         case 13:
00776             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00777                                                fcinfo->arg[1],
00778                                                fcinfo->arg[2],
00779                                                fcinfo->arg[3],
00780                                                fcinfo->arg[4],
00781                                                fcinfo->arg[5],
00782                                                fcinfo->arg[6],
00783                                                fcinfo->arg[7],
00784                                                fcinfo->arg[8],
00785                                                fcinfo->arg[9],
00786                                                fcinfo->arg[10],
00787                                                fcinfo->arg[11],
00788                                                fcinfo->arg[12]);
00789             break;
00790         case 14:
00791             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00792                                                fcinfo->arg[1],
00793                                                fcinfo->arg[2],
00794                                                fcinfo->arg[3],
00795                                                fcinfo->arg[4],
00796                                                fcinfo->arg[5],
00797                                                fcinfo->arg[6],
00798                                                fcinfo->arg[7],
00799                                                fcinfo->arg[8],
00800                                                fcinfo->arg[9],
00801                                                fcinfo->arg[10],
00802                                                fcinfo->arg[11],
00803                                                fcinfo->arg[12],
00804                                                fcinfo->arg[13]);
00805             break;
00806         case 15:
00807             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00808                                                fcinfo->arg[1],
00809                                                fcinfo->arg[2],
00810                                                fcinfo->arg[3],
00811                                                fcinfo->arg[4],
00812                                                fcinfo->arg[5],
00813                                                fcinfo->arg[6],
00814                                                fcinfo->arg[7],
00815                                                fcinfo->arg[8],
00816                                                fcinfo->arg[9],
00817                                                fcinfo->arg[10],
00818                                                fcinfo->arg[11],
00819                                                fcinfo->arg[12],
00820                                                fcinfo->arg[13],
00821                                                fcinfo->arg[14]);
00822             break;
00823         case 16:
00824             returnValue = (char *) (*user_fn) (fcinfo->arg[0],
00825                                                fcinfo->arg[1],
00826                                                fcinfo->arg[2],
00827                                                fcinfo->arg[3],
00828                                                fcinfo->arg[4],
00829                                                fcinfo->arg[5],
00830                                                fcinfo->arg[6],
00831                                                fcinfo->arg[7],
00832                                                fcinfo->arg[8],
00833                                                fcinfo->arg[9],
00834                                                fcinfo->arg[10],
00835                                                fcinfo->arg[11],
00836                                                fcinfo->arg[12],
00837                                                fcinfo->arg[13],
00838                                                fcinfo->arg[14],
00839                                                fcinfo->arg[15]);
00840             break;
00841         default:
00842 
00843             /*
00844              * Increasing FUNC_MAX_ARGS doesn't automatically add cases to the
00845              * above code, so mention the actual value in this error not
00846              * FUNC_MAX_ARGS.  You could add cases to the above if you needed
00847              * to support old-style functions with many arguments, but making
00848              * 'em be new-style is probably a better idea.
00849              */
00850             ereport(ERROR,
00851                     (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
00852              errmsg("function %u has too many arguments (%d, maximum is %d)",
00853                     fcinfo->flinfo->fn_oid, n_arguments, 16)));
00854             returnValue = NULL; /* keep compiler quiet */
00855             break;
00856     }
00857 
00858     return PointerGetDatum(returnValue);
00859 }
00860 
00861 
00862 /*
00863  * Support for security-definer and proconfig-using functions.  We support
00864  * both of these features using the same call handler, because they are
00865  * often used together and it would be inefficient (as well as notationally
00866  * messy) to have two levels of call handler involved.
00867  */
00868 struct fmgr_security_definer_cache
00869 {
00870     FmgrInfo    flinfo;         /* lookup info for target function */
00871     Oid         userid;         /* userid to set, or InvalidOid */
00872     ArrayType  *proconfig;      /* GUC values to set, or NULL */
00873     Datum       arg;            /* passthrough argument for plugin modules */
00874 };
00875 
00876 /*
00877  * Function handler for security-definer/proconfig/plugin-hooked functions.
00878  * We extract the OID of the actual function and do a fmgr lookup again.
00879  * Then we fetch the pg_proc row and copy the owner ID and proconfig fields.
00880  * (All this info is cached for the duration of the current query.)
00881  * To execute a call, we temporarily replace the flinfo with the cached
00882  * and looked-up one, while keeping the outer fcinfo (which contains all
00883  * the actual arguments, etc.) intact.  This is not re-entrant, but then
00884  * the fcinfo itself can't be used re-entrantly anyway.
00885  */
00886 static Datum
00887 fmgr_security_definer(PG_FUNCTION_ARGS)
00888 {
00889     Datum       result;
00890     struct fmgr_security_definer_cache *volatile fcache;
00891     FmgrInfo   *save_flinfo;
00892     Oid         save_userid;
00893     int         save_sec_context;
00894     volatile int save_nestlevel;
00895     PgStat_FunctionCallUsage fcusage;
00896 
00897     if (!fcinfo->flinfo->fn_extra)
00898     {
00899         HeapTuple   tuple;
00900         Form_pg_proc procedureStruct;
00901         Datum       datum;
00902         bool        isnull;
00903         MemoryContext oldcxt;
00904 
00905         fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
00906                                         sizeof(*fcache));
00907 
00908         fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
00909                                fcinfo->flinfo->fn_mcxt, true);
00910         fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
00911 
00912         tuple = SearchSysCache1(PROCOID,
00913                                 ObjectIdGetDatum(fcinfo->flinfo->fn_oid));
00914         if (!HeapTupleIsValid(tuple))
00915             elog(ERROR, "cache lookup failed for function %u",
00916                  fcinfo->flinfo->fn_oid);
00917         procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
00918 
00919         if (procedureStruct->prosecdef)
00920             fcache->userid = procedureStruct->proowner;
00921 
00922         datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
00923                                 &isnull);
00924         if (!isnull)
00925         {
00926             oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
00927             fcache->proconfig = DatumGetArrayTypePCopy(datum);
00928             MemoryContextSwitchTo(oldcxt);
00929         }
00930 
00931         ReleaseSysCache(tuple);
00932 
00933         fcinfo->flinfo->fn_extra = fcache;
00934     }
00935     else
00936         fcache = fcinfo->flinfo->fn_extra;
00937 
00938     /* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
00939     GetUserIdAndSecContext(&save_userid, &save_sec_context);
00940     if (fcache->proconfig)      /* Need a new GUC nesting level */
00941         save_nestlevel = NewGUCNestLevel();
00942     else
00943         save_nestlevel = 0;     /* keep compiler quiet */
00944 
00945     if (OidIsValid(fcache->userid))
00946         SetUserIdAndSecContext(fcache->userid,
00947                             save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
00948 
00949     if (fcache->proconfig)
00950     {
00951         ProcessGUCArray(fcache->proconfig,
00952                         (superuser() ? PGC_SUSET : PGC_USERSET),
00953                         PGC_S_SESSION,
00954                         GUC_ACTION_SAVE);
00955     }
00956 
00957     /* function manager hook */
00958     if (fmgr_hook)
00959         (*fmgr_hook) (FHET_START, &fcache->flinfo, &fcache->arg);
00960 
00961     /*
00962      * We don't need to restore GUC or userid settings on error, because the
00963      * ensuing xact or subxact abort will do that.  The PG_TRY block is only
00964      * needed to clean up the flinfo link.
00965      */
00966     save_flinfo = fcinfo->flinfo;
00967 
00968     PG_TRY();
00969     {
00970         fcinfo->flinfo = &fcache->flinfo;
00971 
00972         /* See notes in fmgr_info_cxt_security */
00973         pgstat_init_function_usage(fcinfo, &fcusage);
00974 
00975         result = FunctionCallInvoke(fcinfo);
00976 
00977         /*
00978          * We could be calling either a regular or a set-returning function,
00979          * so we have to test to see what finalize flag to use.
00980          */
00981         pgstat_end_function_usage(&fcusage,
00982                                   (fcinfo->resultinfo == NULL ||
00983                                    !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
00984                                    ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
00985     }
00986     PG_CATCH();
00987     {
00988         fcinfo->flinfo = save_flinfo;
00989         if (fmgr_hook)
00990             (*fmgr_hook) (FHET_ABORT, &fcache->flinfo, &fcache->arg);
00991         PG_RE_THROW();
00992     }
00993     PG_END_TRY();
00994 
00995     fcinfo->flinfo = save_flinfo;
00996 
00997     if (fcache->proconfig)
00998         AtEOXact_GUC(true, save_nestlevel);
00999     if (OidIsValid(fcache->userid))
01000         SetUserIdAndSecContext(save_userid, save_sec_context);
01001     if (fmgr_hook)
01002         (*fmgr_hook) (FHET_END, &fcache->flinfo, &fcache->arg);
01003 
01004     return result;
01005 }
01006 
01007 
01008 /*-------------------------------------------------------------------------
01009  *      Support routines for callers of fmgr-compatible functions
01010  *-------------------------------------------------------------------------
01011  */
01012 
01013 /*
01014  * These are for invocation of a specifically named function with a
01015  * directly-computed parameter list.  Note that neither arguments nor result
01016  * are allowed to be NULL.  Also, the function cannot be one that needs to
01017  * look at FmgrInfo, since there won't be any.
01018  */
01019 Datum
01020 DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
01021 {
01022     FunctionCallInfoData fcinfo;
01023     Datum       result;
01024 
01025     InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
01026 
01027     fcinfo.arg[0] = arg1;
01028     fcinfo.argnull[0] = false;
01029 
01030     result = (*func) (&fcinfo);
01031 
01032     /* Check for null result, since caller is clearly not expecting one */
01033     if (fcinfo.isnull)
01034         elog(ERROR, "function %p returned NULL", (void *) func);
01035 
01036     return result;
01037 }
01038 
01039 Datum
01040 DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
01041 {
01042     FunctionCallInfoData fcinfo;
01043     Datum       result;
01044 
01045     InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
01046 
01047     fcinfo.arg[0] = arg1;
01048     fcinfo.arg[1] = arg2;
01049     fcinfo.argnull[0] = false;
01050     fcinfo.argnull[1] = false;
01051 
01052     result = (*func) (&fcinfo);
01053 
01054     /* Check for null result, since caller is clearly not expecting one */
01055     if (fcinfo.isnull)
01056         elog(ERROR, "function %p returned NULL", (void *) func);
01057 
01058     return result;
01059 }
01060 
01061 Datum
01062 DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01063                         Datum arg3)
01064 {
01065     FunctionCallInfoData fcinfo;
01066     Datum       result;
01067 
01068     InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
01069 
01070     fcinfo.arg[0] = arg1;
01071     fcinfo.arg[1] = arg2;
01072     fcinfo.arg[2] = arg3;
01073     fcinfo.argnull[0] = false;
01074     fcinfo.argnull[1] = false;
01075     fcinfo.argnull[2] = false;
01076 
01077     result = (*func) (&fcinfo);
01078 
01079     /* Check for null result, since caller is clearly not expecting one */
01080     if (fcinfo.isnull)
01081         elog(ERROR, "function %p returned NULL", (void *) func);
01082 
01083     return result;
01084 }
01085 
01086 Datum
01087 DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01088                         Datum arg3, Datum arg4)
01089 {
01090     FunctionCallInfoData fcinfo;
01091     Datum       result;
01092 
01093     InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
01094 
01095     fcinfo.arg[0] = arg1;
01096     fcinfo.arg[1] = arg2;
01097     fcinfo.arg[2] = arg3;
01098     fcinfo.arg[3] = arg4;
01099     fcinfo.argnull[0] = false;
01100     fcinfo.argnull[1] = false;
01101     fcinfo.argnull[2] = false;
01102     fcinfo.argnull[3] = false;
01103 
01104     result = (*func) (&fcinfo);
01105 
01106     /* Check for null result, since caller is clearly not expecting one */
01107     if (fcinfo.isnull)
01108         elog(ERROR, "function %p returned NULL", (void *) func);
01109 
01110     return result;
01111 }
01112 
01113 Datum
01114 DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01115                         Datum arg3, Datum arg4, Datum arg5)
01116 {
01117     FunctionCallInfoData fcinfo;
01118     Datum       result;
01119 
01120     InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
01121 
01122     fcinfo.arg[0] = arg1;
01123     fcinfo.arg[1] = arg2;
01124     fcinfo.arg[2] = arg3;
01125     fcinfo.arg[3] = arg4;
01126     fcinfo.arg[4] = arg5;
01127     fcinfo.argnull[0] = false;
01128     fcinfo.argnull[1] = false;
01129     fcinfo.argnull[2] = false;
01130     fcinfo.argnull[3] = false;
01131     fcinfo.argnull[4] = false;
01132 
01133     result = (*func) (&fcinfo);
01134 
01135     /* Check for null result, since caller is clearly not expecting one */
01136     if (fcinfo.isnull)
01137         elog(ERROR, "function %p returned NULL", (void *) func);
01138 
01139     return result;
01140 }
01141 
01142 Datum
01143 DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01144                         Datum arg3, Datum arg4, Datum arg5,
01145                         Datum arg6)
01146 {
01147     FunctionCallInfoData fcinfo;
01148     Datum       result;
01149 
01150     InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
01151 
01152     fcinfo.arg[0] = arg1;
01153     fcinfo.arg[1] = arg2;
01154     fcinfo.arg[2] = arg3;
01155     fcinfo.arg[3] = arg4;
01156     fcinfo.arg[4] = arg5;
01157     fcinfo.arg[5] = arg6;
01158     fcinfo.argnull[0] = false;
01159     fcinfo.argnull[1] = false;
01160     fcinfo.argnull[2] = false;
01161     fcinfo.argnull[3] = false;
01162     fcinfo.argnull[4] = false;
01163     fcinfo.argnull[5] = false;
01164 
01165     result = (*func) (&fcinfo);
01166 
01167     /* Check for null result, since caller is clearly not expecting one */
01168     if (fcinfo.isnull)
01169         elog(ERROR, "function %p returned NULL", (void *) func);
01170 
01171     return result;
01172 }
01173 
01174 Datum
01175 DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01176                         Datum arg3, Datum arg4, Datum arg5,
01177                         Datum arg6, Datum arg7)
01178 {
01179     FunctionCallInfoData fcinfo;
01180     Datum       result;
01181 
01182     InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
01183 
01184     fcinfo.arg[0] = arg1;
01185     fcinfo.arg[1] = arg2;
01186     fcinfo.arg[2] = arg3;
01187     fcinfo.arg[3] = arg4;
01188     fcinfo.arg[4] = arg5;
01189     fcinfo.arg[5] = arg6;
01190     fcinfo.arg[6] = arg7;
01191     fcinfo.argnull[0] = false;
01192     fcinfo.argnull[1] = false;
01193     fcinfo.argnull[2] = false;
01194     fcinfo.argnull[3] = false;
01195     fcinfo.argnull[4] = false;
01196     fcinfo.argnull[5] = false;
01197     fcinfo.argnull[6] = false;
01198 
01199     result = (*func) (&fcinfo);
01200 
01201     /* Check for null result, since caller is clearly not expecting one */
01202     if (fcinfo.isnull)
01203         elog(ERROR, "function %p returned NULL", (void *) func);
01204 
01205     return result;
01206 }
01207 
01208 Datum
01209 DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01210                         Datum arg3, Datum arg4, Datum arg5,
01211                         Datum arg6, Datum arg7, Datum arg8)
01212 {
01213     FunctionCallInfoData fcinfo;
01214     Datum       result;
01215 
01216     InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
01217 
01218     fcinfo.arg[0] = arg1;
01219     fcinfo.arg[1] = arg2;
01220     fcinfo.arg[2] = arg3;
01221     fcinfo.arg[3] = arg4;
01222     fcinfo.arg[4] = arg5;
01223     fcinfo.arg[5] = arg6;
01224     fcinfo.arg[6] = arg7;
01225     fcinfo.arg[7] = arg8;
01226     fcinfo.argnull[0] = false;
01227     fcinfo.argnull[1] = false;
01228     fcinfo.argnull[2] = false;
01229     fcinfo.argnull[3] = false;
01230     fcinfo.argnull[4] = false;
01231     fcinfo.argnull[5] = false;
01232     fcinfo.argnull[6] = false;
01233     fcinfo.argnull[7] = false;
01234 
01235     result = (*func) (&fcinfo);
01236 
01237     /* Check for null result, since caller is clearly not expecting one */
01238     if (fcinfo.isnull)
01239         elog(ERROR, "function %p returned NULL", (void *) func);
01240 
01241     return result;
01242 }
01243 
01244 Datum
01245 DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
01246                         Datum arg3, Datum arg4, Datum arg5,
01247                         Datum arg6, Datum arg7, Datum arg8,
01248                         Datum arg9)
01249 {
01250     FunctionCallInfoData fcinfo;
01251     Datum       result;
01252 
01253     InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
01254 
01255     fcinfo.arg[0] = arg1;
01256     fcinfo.arg[1] = arg2;
01257     fcinfo.arg[2] = arg3;
01258     fcinfo.arg[3] = arg4;
01259     fcinfo.arg[4] = arg5;
01260     fcinfo.arg[5] = arg6;
01261     fcinfo.arg[6] = arg7;
01262     fcinfo.arg[7] = arg8;
01263     fcinfo.arg[8] = arg9;
01264     fcinfo.argnull[0] = false;
01265     fcinfo.argnull[1] = false;
01266     fcinfo.argnull[2] = false;
01267     fcinfo.argnull[3] = false;
01268     fcinfo.argnull[4] = false;
01269     fcinfo.argnull[5] = false;
01270     fcinfo.argnull[6] = false;
01271     fcinfo.argnull[7] = false;
01272     fcinfo.argnull[8] = false;
01273 
01274     result = (*func) (&fcinfo);
01275 
01276     /* Check for null result, since caller is clearly not expecting one */
01277     if (fcinfo.isnull)
01278         elog(ERROR, "function %p returned NULL", (void *) func);
01279 
01280     return result;
01281 }
01282 
01283 
01284 /*
01285  * These are for invocation of a previously-looked-up function with a
01286  * directly-computed parameter list.  Note that neither arguments nor result
01287  * are allowed to be NULL.
01288  */
01289 Datum
01290 FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
01291 {
01292     FunctionCallInfoData fcinfo;
01293     Datum       result;
01294 
01295     InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
01296 
01297     fcinfo.arg[0] = arg1;
01298     fcinfo.argnull[0] = false;
01299 
01300     result = FunctionCallInvoke(&fcinfo);
01301 
01302     /* Check for null result, since caller is clearly not expecting one */
01303     if (fcinfo.isnull)
01304         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01305 
01306     return result;
01307 }
01308 
01309 Datum
01310 FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
01311 {
01312     /*
01313      * XXX if you change this routine, see also the inlined version in
01314      * utils/sort/tuplesort.c!
01315      */
01316     FunctionCallInfoData fcinfo;
01317     Datum       result;
01318 
01319     InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
01320 
01321     fcinfo.arg[0] = arg1;
01322     fcinfo.arg[1] = arg2;
01323     fcinfo.argnull[0] = false;
01324     fcinfo.argnull[1] = false;
01325 
01326     result = FunctionCallInvoke(&fcinfo);
01327 
01328     /* Check for null result, since caller is clearly not expecting one */
01329     if (fcinfo.isnull)
01330         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01331 
01332     return result;
01333 }
01334 
01335 Datum
01336 FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01337                   Datum arg3)
01338 {
01339     FunctionCallInfoData fcinfo;
01340     Datum       result;
01341 
01342     InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
01343 
01344     fcinfo.arg[0] = arg1;
01345     fcinfo.arg[1] = arg2;
01346     fcinfo.arg[2] = arg3;
01347     fcinfo.argnull[0] = false;
01348     fcinfo.argnull[1] = false;
01349     fcinfo.argnull[2] = false;
01350 
01351     result = FunctionCallInvoke(&fcinfo);
01352 
01353     /* Check for null result, since caller is clearly not expecting one */
01354     if (fcinfo.isnull)
01355         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01356 
01357     return result;
01358 }
01359 
01360 Datum
01361 FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01362                   Datum arg3, Datum arg4)
01363 {
01364     FunctionCallInfoData fcinfo;
01365     Datum       result;
01366 
01367     InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
01368 
01369     fcinfo.arg[0] = arg1;
01370     fcinfo.arg[1] = arg2;
01371     fcinfo.arg[2] = arg3;
01372     fcinfo.arg[3] = arg4;
01373     fcinfo.argnull[0] = false;
01374     fcinfo.argnull[1] = false;
01375     fcinfo.argnull[2] = false;
01376     fcinfo.argnull[3] = false;
01377 
01378     result = FunctionCallInvoke(&fcinfo);
01379 
01380     /* Check for null result, since caller is clearly not expecting one */
01381     if (fcinfo.isnull)
01382         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01383 
01384     return result;
01385 }
01386 
01387 Datum
01388 FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01389                   Datum arg3, Datum arg4, Datum arg5)
01390 {
01391     FunctionCallInfoData fcinfo;
01392     Datum       result;
01393 
01394     InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
01395 
01396     fcinfo.arg[0] = arg1;
01397     fcinfo.arg[1] = arg2;
01398     fcinfo.arg[2] = arg3;
01399     fcinfo.arg[3] = arg4;
01400     fcinfo.arg[4] = arg5;
01401     fcinfo.argnull[0] = false;
01402     fcinfo.argnull[1] = false;
01403     fcinfo.argnull[2] = false;
01404     fcinfo.argnull[3] = false;
01405     fcinfo.argnull[4] = false;
01406 
01407     result = FunctionCallInvoke(&fcinfo);
01408 
01409     /* Check for null result, since caller is clearly not expecting one */
01410     if (fcinfo.isnull)
01411         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01412 
01413     return result;
01414 }
01415 
01416 Datum
01417 FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01418                   Datum arg3, Datum arg4, Datum arg5,
01419                   Datum arg6)
01420 {
01421     FunctionCallInfoData fcinfo;
01422     Datum       result;
01423 
01424     InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
01425 
01426     fcinfo.arg[0] = arg1;
01427     fcinfo.arg[1] = arg2;
01428     fcinfo.arg[2] = arg3;
01429     fcinfo.arg[3] = arg4;
01430     fcinfo.arg[4] = arg5;
01431     fcinfo.arg[5] = arg6;
01432     fcinfo.argnull[0] = false;
01433     fcinfo.argnull[1] = false;
01434     fcinfo.argnull[2] = false;
01435     fcinfo.argnull[3] = false;
01436     fcinfo.argnull[4] = false;
01437     fcinfo.argnull[5] = false;
01438 
01439     result = FunctionCallInvoke(&fcinfo);
01440 
01441     /* Check for null result, since caller is clearly not expecting one */
01442     if (fcinfo.isnull)
01443         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01444 
01445     return result;
01446 }
01447 
01448 Datum
01449 FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01450                   Datum arg3, Datum arg4, Datum arg5,
01451                   Datum arg6, Datum arg7)
01452 {
01453     FunctionCallInfoData fcinfo;
01454     Datum       result;
01455 
01456     InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
01457 
01458     fcinfo.arg[0] = arg1;
01459     fcinfo.arg[1] = arg2;
01460     fcinfo.arg[2] = arg3;
01461     fcinfo.arg[3] = arg4;
01462     fcinfo.arg[4] = arg5;
01463     fcinfo.arg[5] = arg6;
01464     fcinfo.arg[6] = arg7;
01465     fcinfo.argnull[0] = false;
01466     fcinfo.argnull[1] = false;
01467     fcinfo.argnull[2] = false;
01468     fcinfo.argnull[3] = false;
01469     fcinfo.argnull[4] = false;
01470     fcinfo.argnull[5] = false;
01471     fcinfo.argnull[6] = false;
01472 
01473     result = FunctionCallInvoke(&fcinfo);
01474 
01475     /* Check for null result, since caller is clearly not expecting one */
01476     if (fcinfo.isnull)
01477         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01478 
01479     return result;
01480 }
01481 
01482 Datum
01483 FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01484                   Datum arg3, Datum arg4, Datum arg5,
01485                   Datum arg6, Datum arg7, Datum arg8)
01486 {
01487     FunctionCallInfoData fcinfo;
01488     Datum       result;
01489 
01490     InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
01491 
01492     fcinfo.arg[0] = arg1;
01493     fcinfo.arg[1] = arg2;
01494     fcinfo.arg[2] = arg3;
01495     fcinfo.arg[3] = arg4;
01496     fcinfo.arg[4] = arg5;
01497     fcinfo.arg[5] = arg6;
01498     fcinfo.arg[6] = arg7;
01499     fcinfo.arg[7] = arg8;
01500     fcinfo.argnull[0] = false;
01501     fcinfo.argnull[1] = false;
01502     fcinfo.argnull[2] = false;
01503     fcinfo.argnull[3] = false;
01504     fcinfo.argnull[4] = false;
01505     fcinfo.argnull[5] = false;
01506     fcinfo.argnull[6] = false;
01507     fcinfo.argnull[7] = false;
01508 
01509     result = FunctionCallInvoke(&fcinfo);
01510 
01511     /* Check for null result, since caller is clearly not expecting one */
01512     if (fcinfo.isnull)
01513         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01514 
01515     return result;
01516 }
01517 
01518 Datum
01519 FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
01520                   Datum arg3, Datum arg4, Datum arg5,
01521                   Datum arg6, Datum arg7, Datum arg8,
01522                   Datum arg9)
01523 {
01524     FunctionCallInfoData fcinfo;
01525     Datum       result;
01526 
01527     InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
01528 
01529     fcinfo.arg[0] = arg1;
01530     fcinfo.arg[1] = arg2;
01531     fcinfo.arg[2] = arg3;
01532     fcinfo.arg[3] = arg4;
01533     fcinfo.arg[4] = arg5;
01534     fcinfo.arg[5] = arg6;
01535     fcinfo.arg[6] = arg7;
01536     fcinfo.arg[7] = arg8;
01537     fcinfo.arg[8] = arg9;
01538     fcinfo.argnull[0] = false;
01539     fcinfo.argnull[1] = false;
01540     fcinfo.argnull[2] = false;
01541     fcinfo.argnull[3] = false;
01542     fcinfo.argnull[4] = false;
01543     fcinfo.argnull[5] = false;
01544     fcinfo.argnull[6] = false;
01545     fcinfo.argnull[7] = false;
01546     fcinfo.argnull[8] = false;
01547 
01548     result = FunctionCallInvoke(&fcinfo);
01549 
01550     /* Check for null result, since caller is clearly not expecting one */
01551     if (fcinfo.isnull)
01552         elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
01553 
01554     return result;
01555 }
01556 
01557 
01558 /*
01559  * These are for invocation of a function identified by OID with a
01560  * directly-computed parameter list.  Note that neither arguments nor result
01561  * are allowed to be NULL.  These are essentially fmgr_info() followed
01562  * by FunctionCallN().  If the same function is to be invoked repeatedly,
01563  * do the fmgr_info() once and then use FunctionCallN().
01564  */
01565 Datum
01566 OidFunctionCall0Coll(Oid functionId, Oid collation)
01567 {
01568     FmgrInfo    flinfo;
01569     FunctionCallInfoData fcinfo;
01570     Datum       result;
01571 
01572     fmgr_info(functionId, &flinfo);
01573 
01574     InitFunctionCallInfoData(fcinfo, &flinfo, 0, collation, NULL, NULL);
01575 
01576     result = FunctionCallInvoke(&fcinfo);
01577 
01578     /* Check for null result, since caller is clearly not expecting one */
01579     if (fcinfo.isnull)
01580         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01581 
01582     return result;
01583 }
01584 
01585 Datum
01586 OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
01587 {
01588     FmgrInfo    flinfo;
01589     FunctionCallInfoData fcinfo;
01590     Datum       result;
01591 
01592     fmgr_info(functionId, &flinfo);
01593 
01594     InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL);
01595 
01596     fcinfo.arg[0] = arg1;
01597     fcinfo.argnull[0] = false;
01598 
01599     result = FunctionCallInvoke(&fcinfo);
01600 
01601     /* Check for null result, since caller is clearly not expecting one */
01602     if (fcinfo.isnull)
01603         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01604 
01605     return result;
01606 }
01607 
01608 Datum
01609 OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
01610 {
01611     FmgrInfo    flinfo;
01612     FunctionCallInfoData fcinfo;
01613     Datum       result;
01614 
01615     fmgr_info(functionId, &flinfo);
01616 
01617     InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL);
01618 
01619     fcinfo.arg[0] = arg1;
01620     fcinfo.arg[1] = arg2;
01621     fcinfo.argnull[0] = false;
01622     fcinfo.argnull[1] = false;
01623 
01624     result = FunctionCallInvoke(&fcinfo);
01625 
01626     /* Check for null result, since caller is clearly not expecting one */
01627     if (fcinfo.isnull)
01628         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01629 
01630     return result;
01631 }
01632 
01633 Datum
01634 OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01635                      Datum arg3)
01636 {
01637     FmgrInfo    flinfo;
01638     FunctionCallInfoData fcinfo;
01639     Datum       result;
01640 
01641     fmgr_info(functionId, &flinfo);
01642 
01643     InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, NULL, NULL);
01644 
01645     fcinfo.arg[0] = arg1;
01646     fcinfo.arg[1] = arg2;
01647     fcinfo.arg[2] = arg3;
01648     fcinfo.argnull[0] = false;
01649     fcinfo.argnull[1] = false;
01650     fcinfo.argnull[2] = false;
01651 
01652     result = FunctionCallInvoke(&fcinfo);
01653 
01654     /* Check for null result, since caller is clearly not expecting one */
01655     if (fcinfo.isnull)
01656         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01657 
01658     return result;
01659 }
01660 
01661 Datum
01662 OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01663                      Datum arg3, Datum arg4)
01664 {
01665     FmgrInfo    flinfo;
01666     FunctionCallInfoData fcinfo;
01667     Datum       result;
01668 
01669     fmgr_info(functionId, &flinfo);
01670 
01671     InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, NULL, NULL);
01672 
01673     fcinfo.arg[0] = arg1;
01674     fcinfo.arg[1] = arg2;
01675     fcinfo.arg[2] = arg3;
01676     fcinfo.arg[3] = arg4;
01677     fcinfo.argnull[0] = false;
01678     fcinfo.argnull[1] = false;
01679     fcinfo.argnull[2] = false;
01680     fcinfo.argnull[3] = false;
01681 
01682     result = FunctionCallInvoke(&fcinfo);
01683 
01684     /* Check for null result, since caller is clearly not expecting one */
01685     if (fcinfo.isnull)
01686         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01687 
01688     return result;
01689 }
01690 
01691 Datum
01692 OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01693                      Datum arg3, Datum arg4, Datum arg5)
01694 {
01695     FmgrInfo    flinfo;
01696     FunctionCallInfoData fcinfo;
01697     Datum       result;
01698 
01699     fmgr_info(functionId, &flinfo);
01700 
01701     InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, NULL, NULL);
01702 
01703     fcinfo.arg[0] = arg1;
01704     fcinfo.arg[1] = arg2;
01705     fcinfo.arg[2] = arg3;
01706     fcinfo.arg[3] = arg4;
01707     fcinfo.arg[4] = arg5;
01708     fcinfo.argnull[0] = false;
01709     fcinfo.argnull[1] = false;
01710     fcinfo.argnull[2] = false;
01711     fcinfo.argnull[3] = false;
01712     fcinfo.argnull[4] = false;
01713 
01714     result = FunctionCallInvoke(&fcinfo);
01715 
01716     /* Check for null result, since caller is clearly not expecting one */
01717     if (fcinfo.isnull)
01718         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01719 
01720     return result;
01721 }
01722 
01723 Datum
01724 OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01725                      Datum arg3, Datum arg4, Datum arg5,
01726                      Datum arg6)
01727 {
01728     FmgrInfo    flinfo;
01729     FunctionCallInfoData fcinfo;
01730     Datum       result;
01731 
01732     fmgr_info(functionId, &flinfo);
01733 
01734     InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, NULL, NULL);
01735 
01736     fcinfo.arg[0] = arg1;
01737     fcinfo.arg[1] = arg2;
01738     fcinfo.arg[2] = arg3;
01739     fcinfo.arg[3] = arg4;
01740     fcinfo.arg[4] = arg5;
01741     fcinfo.arg[5] = arg6;
01742     fcinfo.argnull[0] = false;
01743     fcinfo.argnull[1] = false;
01744     fcinfo.argnull[2] = false;
01745     fcinfo.argnull[3] = false;
01746     fcinfo.argnull[4] = false;
01747     fcinfo.argnull[5] = false;
01748 
01749     result = FunctionCallInvoke(&fcinfo);
01750 
01751     /* Check for null result, since caller is clearly not expecting one */
01752     if (fcinfo.isnull)
01753         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01754 
01755     return result;
01756 }
01757 
01758 Datum
01759 OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01760                      Datum arg3, Datum arg4, Datum arg5,
01761                      Datum arg6, Datum arg7)
01762 {
01763     FmgrInfo    flinfo;
01764     FunctionCallInfoData fcinfo;
01765     Datum       result;
01766 
01767     fmgr_info(functionId, &flinfo);
01768 
01769     InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, NULL, NULL);
01770 
01771     fcinfo.arg[0] = arg1;
01772     fcinfo.arg[1] = arg2;
01773     fcinfo.arg[2] = arg3;
01774     fcinfo.arg[3] = arg4;
01775     fcinfo.arg[4] = arg5;
01776     fcinfo.arg[5] = arg6;
01777     fcinfo.arg[6] = arg7;
01778     fcinfo.argnull[0] = false;
01779     fcinfo.argnull[1] = false;
01780     fcinfo.argnull[2] = false;
01781     fcinfo.argnull[3] = false;
01782     fcinfo.argnull[4] = false;
01783     fcinfo.argnull[5] = false;
01784     fcinfo.argnull[6] = false;
01785 
01786     result = FunctionCallInvoke(&fcinfo);
01787 
01788     /* Check for null result, since caller is clearly not expecting one */
01789     if (fcinfo.isnull)
01790         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01791 
01792     return result;
01793 }
01794 
01795 Datum
01796 OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01797                      Datum arg3, Datum arg4, Datum arg5,
01798                      Datum arg6, Datum arg7, Datum arg8)
01799 {
01800     FmgrInfo    flinfo;
01801     FunctionCallInfoData fcinfo;
01802     Datum       result;
01803 
01804     fmgr_info(functionId, &flinfo);
01805 
01806     InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, NULL, NULL);
01807 
01808     fcinfo.arg[0] = arg1;
01809     fcinfo.arg[1] = arg2;
01810     fcinfo.arg[2] = arg3;
01811     fcinfo.arg[3] = arg4;
01812     fcinfo.arg[4] = arg5;
01813     fcinfo.arg[5] = arg6;
01814     fcinfo.arg[6] = arg7;
01815     fcinfo.arg[7] = arg8;
01816     fcinfo.argnull[0] = false;
01817     fcinfo.argnull[1] = false;
01818     fcinfo.argnull[2] = false;
01819     fcinfo.argnull[3] = false;
01820     fcinfo.argnull[4] = false;
01821     fcinfo.argnull[5] = false;
01822     fcinfo.argnull[6] = false;
01823     fcinfo.argnull[7] = false;
01824 
01825     result = FunctionCallInvoke(&fcinfo);
01826 
01827     /* Check for null result, since caller is clearly not expecting one */
01828     if (fcinfo.isnull)
01829         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01830 
01831     return result;
01832 }
01833 
01834 Datum
01835 OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
01836                      Datum arg3, Datum arg4, Datum arg5,
01837                      Datum arg6, Datum arg7, Datum arg8,
01838                      Datum arg9)
01839 {
01840     FmgrInfo    flinfo;
01841     FunctionCallInfoData fcinfo;
01842     Datum       result;
01843 
01844     fmgr_info(functionId, &flinfo);
01845 
01846     InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, NULL, NULL);
01847 
01848     fcinfo.arg[0] = arg1;
01849     fcinfo.arg[1] = arg2;
01850     fcinfo.arg[2] = arg3;
01851     fcinfo.arg[3] = arg4;
01852     fcinfo.arg[4] = arg5;
01853     fcinfo.arg[5] = arg6;
01854     fcinfo.arg[6] = arg7;
01855     fcinfo.arg[7] = arg8;
01856     fcinfo.arg[8] = arg9;
01857     fcinfo.argnull[0] = false;
01858     fcinfo.argnull[1] = false;
01859     fcinfo.argnull[2] = false;
01860     fcinfo.argnull[3] = false;
01861     fcinfo.argnull[4] = false;
01862     fcinfo.argnull[5] = false;
01863     fcinfo.argnull[6] = false;
01864     fcinfo.argnull[7] = false;
01865     fcinfo.argnull[8] = false;
01866 
01867     result = FunctionCallInvoke(&fcinfo);
01868 
01869     /* Check for null result, since caller is clearly not expecting one */
01870     if (fcinfo.isnull)
01871         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
01872 
01873     return result;
01874 }
01875 
01876 
01877 /*
01878  * Special cases for convenient invocation of datatype I/O functions.
01879  */
01880 
01881 /*
01882  * Call a previously-looked-up datatype input function.
01883  *
01884  * "str" may be NULL to indicate we are reading a NULL.  In this case
01885  * the caller should assume the result is NULL, but we'll call the input
01886  * function anyway if it's not strict.  So this is almost but not quite
01887  * the same as FunctionCall3.
01888  *
01889  * One important difference from the bare function call is that we will
01890  * push any active SPI context, allowing SPI-using I/O functions to be
01891  * called from other SPI functions without extra notation.  This is a hack,
01892  * but the alternative of expecting all SPI functions to do SPI_push/SPI_pop
01893  * around I/O calls seems worse.
01894  */
01895 Datum
01896 InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
01897 {
01898     FunctionCallInfoData fcinfo;
01899     Datum       result;
01900     bool        pushed;
01901 
01902     if (str == NULL && flinfo->fn_strict)
01903         return (Datum) 0;       /* just return null result */
01904 
01905     pushed = SPI_push_conditional();
01906 
01907     InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
01908 
01909     fcinfo.arg[0] = CStringGetDatum(str);
01910     fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
01911     fcinfo.arg[2] = Int32GetDatum(typmod);
01912     fcinfo.argnull[0] = (str == NULL);
01913     fcinfo.argnull[1] = false;
01914     fcinfo.argnull[2] = false;
01915 
01916     result = FunctionCallInvoke(&fcinfo);
01917 
01918     /* Should get null result if and only if str is NULL */
01919     if (str == NULL)
01920     {
01921         if (!fcinfo.isnull)
01922             elog(ERROR, "input function %u returned non-NULL",
01923                  fcinfo.flinfo->fn_oid);
01924     }
01925     else
01926     {
01927         if (fcinfo.isnull)
01928             elog(ERROR, "input function %u returned NULL",
01929                  fcinfo.flinfo->fn_oid);
01930     }
01931 
01932     SPI_pop_conditional(pushed);
01933 
01934     return result;
01935 }
01936 
01937 /*
01938  * Call a previously-looked-up datatype output function.
01939  *
01940  * Do not call this on NULL datums.
01941  *
01942  * This is almost just window dressing for FunctionCall1, but it includes
01943  * SPI context pushing for the same reasons as InputFunctionCall.
01944  */
01945 char *
01946 OutputFunctionCall(FmgrInfo *flinfo, Datum val)
01947 {
01948     char       *result;
01949     bool        pushed;
01950 
01951     pushed = SPI_push_conditional();
01952 
01953     result = DatumGetCString(FunctionCall1(flinfo, val));
01954 
01955     SPI_pop_conditional(pushed);
01956 
01957     return result;
01958 }
01959 
01960 /*
01961  * Call a previously-looked-up datatype binary-input function.
01962  *
01963  * "buf" may be NULL to indicate we are reading a NULL.  In this case
01964  * the caller should assume the result is NULL, but we'll call the receive
01965  * function anyway if it's not strict.  So this is almost but not quite
01966  * the same as FunctionCall3.  Also, this includes SPI context pushing for
01967  * the same reasons as InputFunctionCall.
01968  */
01969 Datum
01970 ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
01971                     Oid typioparam, int32 typmod)
01972 {
01973     FunctionCallInfoData fcinfo;
01974     Datum       result;
01975     bool        pushed;
01976 
01977     if (buf == NULL && flinfo->fn_strict)
01978         return (Datum) 0;       /* just return null result */
01979 
01980     pushed = SPI_push_conditional();
01981 
01982     InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
01983 
01984     fcinfo.arg[0] = PointerGetDatum(buf);
01985     fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
01986     fcinfo.arg[2] = Int32GetDatum(typmod);
01987     fcinfo.argnull[0] = (buf == NULL);
01988     fcinfo.argnull[1] = false;
01989     fcinfo.argnull[2] = false;
01990 
01991     result = FunctionCallInvoke(&fcinfo);
01992 
01993     /* Should get null result if and only if buf is NULL */
01994     if (buf == NULL)
01995     {
01996         if (!fcinfo.isnull)
01997             elog(ERROR, "receive function %u returned non-NULL",
01998                  fcinfo.flinfo->fn_oid);
01999     }
02000     else
02001     {
02002         if (fcinfo.isnull)
02003             elog(ERROR, "receive function %u returned NULL",
02004                  fcinfo.flinfo->fn_oid);
02005     }
02006 
02007     SPI_pop_conditional(pushed);
02008 
02009     return result;
02010 }
02011 
02012 /*
02013  * Call a previously-looked-up datatype binary-output function.
02014  *
02015  * Do not call this on NULL datums.
02016  *
02017  * This is little more than window dressing for FunctionCall1, but it does
02018  * guarantee a non-toasted result, which strictly speaking the underlying
02019  * function doesn't.  Also, this includes SPI context pushing for the same
02020  * reasons as InputFunctionCall.
02021  */
02022 bytea *
02023 SendFunctionCall(FmgrInfo *flinfo, Datum val)
02024 {
02025     bytea      *result;
02026     bool        pushed;
02027 
02028     pushed = SPI_push_conditional();
02029 
02030     result = DatumGetByteaP(FunctionCall1(flinfo, val));
02031 
02032     SPI_pop_conditional(pushed);
02033 
02034     return result;
02035 }
02036 
02037 /*
02038  * As above, for I/O functions identified by OID.  These are only to be used
02039  * in seldom-executed code paths.  They are not only slow but leak memory.
02040  */
02041 Datum
02042 OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
02043 {
02044     FmgrInfo    flinfo;
02045 
02046     fmgr_info(functionId, &flinfo);
02047     return InputFunctionCall(&flinfo, str, typioparam, typmod);
02048 }
02049 
02050 char *
02051 OidOutputFunctionCall(Oid functionId, Datum val)
02052 {
02053     FmgrInfo    flinfo;
02054 
02055     fmgr_info(functionId, &flinfo);
02056     return OutputFunctionCall(&flinfo, val);
02057 }
02058 
02059 Datum
02060 OidReceiveFunctionCall(Oid functionId, StringInfo buf,
02061                        Oid typioparam, int32 typmod)
02062 {
02063     FmgrInfo    flinfo;
02064 
02065     fmgr_info(functionId, &flinfo);
02066     return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
02067 }
02068 
02069 bytea *
02070 OidSendFunctionCall(Oid functionId, Datum val)
02071 {
02072     FmgrInfo    flinfo;
02073 
02074     fmgr_info(functionId, &flinfo);
02075     return SendFunctionCall(&flinfo, val);
02076 }
02077 
02078 
02079 /*
02080  * !!! OLD INTERFACE !!!
02081  *
02082  * fmgr() is the only remaining vestige of the old-style caller support
02083  * functions.  It's no longer used anywhere in the Postgres distribution,
02084  * but we should leave it around for a release or two to ease the transition
02085  * for user-supplied C functions.  OidFunctionCallN() replaces it for new
02086  * code.
02087  *
02088  * DEPRECATED, DO NOT USE IN NEW CODE
02089  */
02090 char *
02091 fmgr(Oid procedureId,...)
02092 {
02093     FmgrInfo    flinfo;
02094     FunctionCallInfoData fcinfo;
02095     int         n_arguments;
02096     Datum       result;
02097 
02098     fmgr_info(procedureId, &flinfo);
02099 
02100     MemSet(&fcinfo, 0, sizeof(fcinfo));
02101     fcinfo.flinfo = &flinfo;
02102     fcinfo.nargs = flinfo.fn_nargs;
02103     n_arguments = fcinfo.nargs;
02104 
02105     if (n_arguments > 0)
02106     {
02107         va_list     pvar;
02108         int         i;
02109 
02110         if (n_arguments > FUNC_MAX_ARGS)
02111             ereport(ERROR,
02112                     (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
02113              errmsg("function %u has too many arguments (%d, maximum is %d)",
02114                     flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS)));
02115         va_start(pvar, procedureId);
02116         for (i = 0; i < n_arguments; i++)
02117             fcinfo.arg[i] = PointerGetDatum(va_arg(pvar, char *));
02118         va_end(pvar);
02119     }
02120 
02121     result = FunctionCallInvoke(&fcinfo);
02122 
02123     /* Check for null result, since caller is clearly not expecting one */
02124     if (fcinfo.isnull)
02125         elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
02126 
02127     return DatumGetPointer(result);
02128 }
02129 
02130 
02131 /*-------------------------------------------------------------------------
02132  *      Support routines for standard maybe-pass-by-reference datatypes
02133  *
02134  * int8, float4, and float8 can be passed by value if Datum is wide enough.
02135  * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
02136  * at compile time even if pass-by-val is possible.)  For the float types,
02137  * we need a support routine even if we are passing by value, because many
02138  * machines pass int and float function parameters/results differently;
02139  * so we need to play weird games with unions.
02140  *
02141  * Note: there is only one switch controlling the pass-by-value option for
02142  * both int8 and float8; this is to avoid making things unduly complicated
02143  * for the timestamp types, which might have either representation.
02144  *-------------------------------------------------------------------------
02145  */
02146 
02147 #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
02148 
02149 Datum
02150 Int64GetDatum(int64 X)
02151 {
02152     int64      *retval = (int64 *) palloc(sizeof(int64));
02153 
02154     *retval = X;
02155     return PointerGetDatum(retval);
02156 }
02157 #endif   /* USE_FLOAT8_BYVAL */
02158 
02159 Datum
02160 Float4GetDatum(float4 X)
02161 {
02162 #ifdef USE_FLOAT4_BYVAL
02163     union
02164     {
02165         float4      value;
02166         int32       retval;
02167     }           myunion;
02168 
02169     myunion.value = X;
02170     return SET_4_BYTES(myunion.retval);
02171 #else
02172     float4     *retval = (float4 *) palloc(sizeof(float4));
02173 
02174     *retval = X;
02175     return PointerGetDatum(retval);
02176 #endif
02177 }
02178 
02179 #ifdef USE_FLOAT4_BYVAL
02180 
02181 float4
02182 DatumGetFloat4(Datum X)
02183 {
02184     union
02185     {
02186         int32       value;
02187         float4      retval;
02188     }           myunion;
02189 
02190     myunion.value = GET_4_BYTES(X);
02191     return myunion.retval;
02192 }
02193 #endif   /* USE_FLOAT4_BYVAL */
02194 
02195 Datum
02196 Float8GetDatum(float8 X)
02197 {
02198 #ifdef USE_FLOAT8_BYVAL
02199     union
02200     {
02201         float8      value;
02202         int64       retval;
02203     }           myunion;
02204 
02205     myunion.value = X;
02206     return SET_8_BYTES(myunion.retval);
02207 #else
02208     float8     *retval = (float8 *) palloc(sizeof(float8));
02209 
02210     *retval = X;
02211     return PointerGetDatum(retval);
02212 #endif
02213 }
02214 
02215 #ifdef USE_FLOAT8_BYVAL
02216 
02217 float8
02218 DatumGetFloat8(Datum X)
02219 {
02220     union
02221     {
02222         int64       value;
02223         float8      retval;
02224     }           myunion;
02225 
02226     myunion.value = GET_8_BYTES(X);
02227     return myunion.retval;
02228 }
02229 #endif   /* USE_FLOAT8_BYVAL */
02230 
02231 
02232 /*-------------------------------------------------------------------------
02233  *      Support routines for toastable datatypes
02234  *-------------------------------------------------------------------------
02235  */
02236 
02237 struct varlena *
02238 pg_detoast_datum(struct varlena * datum)
02239 {
02240     if (VARATT_IS_EXTENDED(datum))
02241         return heap_tuple_untoast_attr(datum);
02242     else
02243         return datum;
02244 }
02245 
02246 struct varlena *
02247 pg_detoast_datum_copy(struct varlena * datum)
02248 {
02249     if (VARATT_IS_EXTENDED(datum))
02250         return heap_tuple_untoast_attr(datum);
02251     else
02252     {
02253         /* Make a modifiable copy of the varlena object */
02254         Size        len = VARSIZE(datum);
02255         struct varlena *result = (struct varlena *) palloc(len);
02256 
02257         memcpy(result, datum, len);
02258         return result;
02259     }
02260 }
02261 
02262 struct varlena *
02263 pg_detoast_datum_slice(struct varlena * datum, int32 first, int32 count)
02264 {
02265     /* Only get the specified portion from the toast rel */
02266     return heap_tuple_untoast_attr_slice(datum, first, count);
02267 }
02268 
02269 struct varlena *
02270 pg_detoast_datum_packed(struct varlena * datum)
02271 {
02272     if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
02273         return heap_tuple_untoast_attr(datum);
02274     else
02275         return datum;
02276 }
02277 
02278 /*-------------------------------------------------------------------------
02279  *      Support routines for extracting info from fn_expr parse tree
02280  *
02281  * These are needed by polymorphic functions, which accept multiple possible
02282  * input types and need help from the parser to know what they've got.
02283  * Also, some functions might be interested in whether a parameter is constant.
02284  * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
02285  *-------------------------------------------------------------------------
02286  */
02287 
02288 /*
02289  * Get the actual type OID of the function return type
02290  *
02291  * Returns InvalidOid if information is not available
02292  */
02293 Oid
02294 get_fn_expr_rettype(FmgrInfo *flinfo)
02295 {
02296     Node       *expr;
02297 
02298     /*
02299      * can't return anything useful if we have no FmgrInfo or if its fn_expr
02300      * node has not been initialized
02301      */
02302     if (!flinfo || !flinfo->fn_expr)
02303         return InvalidOid;
02304 
02305     expr = flinfo->fn_expr;
02306 
02307     return exprType(expr);
02308 }
02309 
02310 /*
02311  * Get the actual type OID of a specific function argument (counting from 0)
02312  *
02313  * Returns InvalidOid if information is not available
02314  */
02315 Oid
02316 get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
02317 {
02318     /*
02319      * can't return anything useful if we have no FmgrInfo or if its fn_expr
02320      * node has not been initialized
02321      */
02322     if (!flinfo || !flinfo->fn_expr)
02323         return InvalidOid;
02324 
02325     return get_call_expr_argtype(flinfo->fn_expr, argnum);
02326 }
02327 
02328 /*
02329  * Get the actual type OID of a specific function argument (counting from 0),
02330  * but working from the calling expression tree instead of FmgrInfo
02331  *
02332  * Returns InvalidOid if information is not available
02333  */
02334 Oid
02335 get_call_expr_argtype(Node *expr, int argnum)
02336 {
02337     List       *args;
02338     Oid         argtype;
02339 
02340     if (expr == NULL)
02341         return InvalidOid;
02342 
02343     if (IsA(expr, FuncExpr))
02344         args = ((FuncExpr *) expr)->args;
02345     else if (IsA(expr, OpExpr))
02346         args = ((OpExpr *) expr)->args;
02347     else if (IsA(expr, DistinctExpr))
02348         args = ((DistinctExpr *) expr)->args;
02349     else if (IsA(expr, ScalarArrayOpExpr))
02350         args = ((ScalarArrayOpExpr *) expr)->args;
02351     else if (IsA(expr, ArrayCoerceExpr))
02352         args = list_make1(((ArrayCoerceExpr *) expr)->arg);
02353     else if (IsA(expr, NullIfExpr))
02354         args = ((NullIfExpr *) expr)->args;
02355     else if (IsA(expr, WindowFunc))
02356         args = ((WindowFunc *) expr)->args;
02357     else
02358         return InvalidOid;
02359 
02360     if (argnum < 0 || argnum >= list_length(args))
02361         return InvalidOid;
02362 
02363     argtype = exprType((Node *) list_nth(args, argnum));
02364 
02365     /*
02366      * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the
02367      * underlying function will actually get passed is the element type of the
02368      * array.
02369      */
02370     if (IsA(expr, ScalarArrayOpExpr) &&
02371         argnum == 1)
02372         argtype = get_base_element_type(argtype);
02373     else if (IsA(expr, ArrayCoerceExpr) &&
02374              argnum == 0)
02375         argtype = get_base_element_type(argtype);
02376 
02377     return argtype;
02378 }
02379 
02380 /*
02381  * Find out whether a specific function argument is constant for the
02382  * duration of a query
02383  *
02384  * Returns false if information is not available
02385  */
02386 bool
02387 get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
02388 {
02389     /*
02390      * can't return anything useful if we have no FmgrInfo or if its fn_expr
02391      * node has not been initialized
02392      */
02393     if (!flinfo || !flinfo->fn_expr)
02394         return false;
02395 
02396     return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
02397 }
02398 
02399 /*
02400  * Find out whether a specific function argument is constant for the
02401  * duration of a query, but working from the calling expression tree
02402  *
02403  * Returns false if information is not available
02404  */
02405 bool
02406 get_call_expr_arg_stable(Node *expr, int argnum)
02407 {
02408     List       *args;
02409     Node       *arg;
02410 
02411     if (expr == NULL)
02412         return false;
02413 
02414     if (IsA(expr, FuncExpr))
02415         args = ((FuncExpr *) expr)->args;
02416     else if (IsA(expr, OpExpr))
02417         args = ((OpExpr *) expr)->args;
02418     else if (IsA(expr, DistinctExpr))
02419         args = ((DistinctExpr *) expr)->args;
02420     else if (IsA(expr, ScalarArrayOpExpr))
02421         args = ((ScalarArrayOpExpr *) expr)->args;
02422     else if (IsA(expr, ArrayCoerceExpr))
02423         args = list_make1(((ArrayCoerceExpr *) expr)->arg);
02424     else if (IsA(expr, NullIfExpr))
02425         args = ((NullIfExpr *) expr)->args;
02426     else if (IsA(expr, WindowFunc))
02427         args = ((WindowFunc *) expr)->args;
02428     else
02429         return false;
02430 
02431     if (argnum < 0 || argnum >= list_length(args))
02432         return false;
02433 
02434     arg = (Node *) list_nth(args, argnum);
02435 
02436     /*
02437      * Either a true Const or an external Param will have a value that doesn't
02438      * change during the execution of the query.  In future we might want to
02439      * consider other cases too, e.g. now().
02440      */
02441     if (IsA(arg, Const))
02442         return true;
02443     if (IsA(arg, Param) &&
02444         ((Param *) arg)->paramkind == PARAM_EXTERN)
02445         return true;
02446 
02447     return false;
02448 }
02449 
02450 /*
02451  * Get the VARIADIC flag from the function invocation
02452  *
02453  * Returns false (the default assumption) if information is not available
02454  */
02455 bool
02456 get_fn_expr_variadic(FmgrInfo *flinfo)
02457 {
02458     Node       *expr;
02459 
02460     /*
02461      * can't return anything useful if we have no FmgrInfo or if its fn_expr
02462      * node has not been initialized
02463      */
02464     if (!flinfo || !flinfo->fn_expr)
02465         return false;
02466 
02467     expr = flinfo->fn_expr;
02468 
02469     if (IsA(expr, FuncExpr))
02470         return ((FuncExpr *) expr)->funcvariadic;
02471     else
02472         return false;
02473 }