]> granicus.if.org Git - postgresql/blob - src/backend/utils/fmgr/fmgr.c
42de04c60a8368038d2afdd3cde849251fdcb283
[postgresql] / src / backend / utils / fmgr / fmgr.c
1 /*-------------------------------------------------------------------------
2  *
3  * fmgr.c
4  *        The Postgres function manager.
5  *
6  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/utils/fmgr/fmgr.c
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include "access/tuptoaster.h"
19 #include "catalog/pg_language.h"
20 #include "catalog/pg_proc.h"
21 #include "executor/functions.h"
22 #include "executor/spi.h"
23 #include "lib/stringinfo.h"
24 #include "miscadmin.h"
25 #include "nodes/nodeFuncs.h"
26 #include "pgstat.h"
27 #include "utils/builtins.h"
28 #include "utils/fmgrtab.h"
29 #include "utils/guc.h"
30 #include "utils/lsyscache.h"
31 #include "utils/syscache.h"
32
33 /*
34  * Hooks for function calls
35  */
36 PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook = NULL;
37 PGDLLIMPORT fmgr_hook_type fmgr_hook = NULL;
38
39 /*
40  * Declaration for old-style function pointer type.  This is now used only
41  * in fmgr_oldstyle() and is no longer exported.
42  *
43  * The m68k SVR4 ABI defines that pointers are returned in %a0 instead of
44  * %d0. So if a function pointer is declared to return a pointer, the
45  * compiler may look only into %a0, but if the called function was declared
46  * to return an integer type, it puts its value only into %d0. So the
47  * caller doesn't pick up the correct return value. The solution is to
48  * declare the function pointer to return int, so the compiler picks up the
49  * return value from %d0. (Functions returning pointers put their value
50  * *additionally* into %d0 for compatibility.) The price is that there are
51  * some warnings about int->pointer conversions ... which we can suppress
52  * with suitably ugly casts in fmgr_oldstyle().
53  */
54 #if (defined(__mc68000__) || (defined(__m68k__))) && defined(__ELF__)
55 typedef int32 (*func_ptr) ();
56 #else
57 typedef char *(*func_ptr) ();
58 #endif
59
60 /*
61  * For an oldstyle function, fn_extra points to a record like this:
62  */
63 typedef struct
64 {
65         func_ptr        func;                   /* Address of the oldstyle function */
66         bool            arg_toastable[FUNC_MAX_ARGS];   /* is n'th arg of a toastable
67                                                                                                  * datatype? */
68 } Oldstyle_fnextra;
69
70 /*
71  * Hashtable for fast lookup of external C functions
72  */
73 typedef struct
74 {
75         /* fn_oid is the hash key and so must be first! */
76         Oid                     fn_oid;                 /* OID of an external C function */
77         TransactionId fn_xmin;          /* for checking up-to-dateness */
78         ItemPointerData fn_tid;
79         PGFunction      user_fn;                /* the function's address */
80         const Pg_finfo_record *inforec;         /* address of its info record */
81 } CFuncHashTabEntry;
82
83 static HTAB *CFuncHash = NULL;
84
85
86 static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
87                                            bool ignore_security);
88 static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
89 static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
90 static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
91 static void record_C_func(HeapTuple procedureTuple,
92                           PGFunction user_fn, const Pg_finfo_record *inforec);
93 static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
94 static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
95
96
97 /*
98  * Lookup routines for builtin-function table.  We can search by either Oid
99  * or name, but search by Oid is much faster.
100  */
101
102 static const FmgrBuiltin *
103 fmgr_isbuiltin(Oid id)
104 {
105         int                     low = 0;
106         int                     high = fmgr_nbuiltins - 1;
107
108         /*
109          * Loop invariant: low is the first index that could contain target entry,
110          * and high is the last index that could contain it.
111          */
112         while (low <= high)
113         {
114                 int                     i = (high + low) / 2;
115                 const FmgrBuiltin *ptr = &fmgr_builtins[i];
116
117                 if (id == ptr->foid)
118                         return ptr;
119                 else if (id > ptr->foid)
120                         low = i + 1;
121                 else
122                         high = i - 1;
123         }
124         return NULL;
125 }
126
127 /*
128  * Lookup a builtin by name.  Note there can be more than one entry in
129  * the array with the same name, but they should all point to the same
130  * routine.
131  */
132 static const FmgrBuiltin *
133 fmgr_lookupByName(const char *name)
134 {
135         int                     i;
136
137         for (i = 0; i < fmgr_nbuiltins; i++)
138         {
139                 if (strcmp(name, fmgr_builtins[i].funcName) == 0)
140                         return fmgr_builtins + i;
141         }
142         return NULL;
143 }
144
145 /*
146  * This routine fills a FmgrInfo struct, given the OID
147  * of the function to be called.
148  *
149  * The caller's CurrentMemoryContext is used as the fn_mcxt of the info
150  * struct; this means that any subsidiary data attached to the info struct
151  * (either by fmgr_info itself, or later on by a function call handler)
152  * will be allocated in that context.  The caller must ensure that this
153  * context is at least as long-lived as the info struct itself.  This is
154  * not a problem in typical cases where the info struct is on the stack or
155  * in freshly-palloc'd space.  However, if one intends to store an info
156  * struct in a long-lived table, it's better to use fmgr_info_cxt.
157  */
158 void
159 fmgr_info(Oid functionId, FmgrInfo *finfo)
160 {
161         fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
162 }
163
164 /*
165  * Fill a FmgrInfo struct, specifying a memory context in which its
166  * subsidiary data should go.
167  */
168 void
169 fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
170 {
171         fmgr_info_cxt_security(functionId, finfo, mcxt, false);
172 }
173
174 /*
175  * This one does the actual work.  ignore_security is ordinarily false
176  * but is set to true when we need to avoid recursion.
177  */
178 static void
179 fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
180                                            bool ignore_security)
181 {
182         const FmgrBuiltin *fbp;
183         HeapTuple       procedureTuple;
184         Form_pg_proc procedureStruct;
185         Datum           prosrcdatum;
186         bool            isnull;
187         char       *prosrc;
188
189         /*
190          * fn_oid *must* be filled in last.  Some code assumes that if fn_oid is
191          * valid, the whole struct is valid.  Some FmgrInfo struct's do survive
192          * elogs.
193          */
194         finfo->fn_oid = InvalidOid;
195         finfo->fn_extra = NULL;
196         finfo->fn_mcxt = mcxt;
197         finfo->fn_expr = NULL;          /* caller may set this later */
198
199         if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
200         {
201                 /*
202                  * Fast path for builtin functions: don't bother consulting pg_proc
203                  */
204                 finfo->fn_nargs = fbp->nargs;
205                 finfo->fn_strict = fbp->strict;
206                 finfo->fn_retset = fbp->retset;
207                 finfo->fn_stats = TRACK_FUNC_ALL;               /* ie, never track */
208                 finfo->fn_addr = fbp->func;
209                 finfo->fn_oid = functionId;
210                 return;
211         }
212
213         /* Otherwise we need the pg_proc entry */
214         procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
215         if (!HeapTupleIsValid(procedureTuple))
216                 elog(ERROR, "cache lookup failed for function %u", functionId);
217         procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
218
219         finfo->fn_nargs = procedureStruct->pronargs;
220         finfo->fn_strict = procedureStruct->proisstrict;
221         finfo->fn_retset = procedureStruct->proretset;
222
223         /*
224          * If it has prosecdef set, non-null proconfig, or if a plugin wants to
225          * hook function entry/exit, use fmgr_security_definer call handler ---
226          * unless we are being called again by fmgr_security_definer or
227          * fmgr_info_other_lang.
228          *
229          * When using fmgr_security_definer, function stats tracking is always
230          * disabled at the outer level, and instead we set the flag properly in
231          * fmgr_security_definer's private flinfo and implement the tracking
232          * inside fmgr_security_definer.  This loses the ability to charge the
233          * overhead of fmgr_security_definer to the function, but gains the
234          * ability to set the track_functions GUC as a local GUC parameter of an
235          * interesting function and have the right things happen.
236          */
237         if (!ignore_security &&
238                 (procedureStruct->prosecdef ||
239                  !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig) ||
240                  FmgrHookIsNeeded(functionId)))
241         {
242                 finfo->fn_addr = fmgr_security_definer;
243                 finfo->fn_stats = TRACK_FUNC_ALL;               /* ie, never track */
244                 finfo->fn_oid = functionId;
245                 ReleaseSysCache(procedureTuple);
246                 return;
247         }
248
249         switch (procedureStruct->prolang)
250         {
251                 case INTERNALlanguageId:
252
253                         /*
254                          * For an ordinary builtin function, we should never get here
255                          * because the isbuiltin() search above will have succeeded.
256                          * However, if the user has done a CREATE FUNCTION to create an
257                          * alias for a builtin function, we can end up here.  In that case
258                          * we have to look up the function by name.  The name of the
259                          * internal function is stored in prosrc (it doesn't have to be
260                          * the same as the name of the alias!)
261                          */
262                         prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
263                                                                                   Anum_pg_proc_prosrc, &isnull);
264                         if (isnull)
265                                 elog(ERROR, "null prosrc");
266                         prosrc = TextDatumGetCString(prosrcdatum);
267                         fbp = fmgr_lookupByName(prosrc);
268                         if (fbp == NULL)
269                                 ereport(ERROR,
270                                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
271                                                  errmsg("internal function \"%s\" is not in internal lookup table",
272                                                                 prosrc)));
273                         pfree(prosrc);
274                         /* Should we check that nargs, strict, retset match the table? */
275                         finfo->fn_addr = fbp->func;
276                         /* note this policy is also assumed in fast path above */
277                         finfo->fn_stats = TRACK_FUNC_ALL;       /* ie, never track */
278                         break;
279
280                 case ClanguageId:
281                         fmgr_info_C_lang(functionId, finfo, procedureTuple);
282                         finfo->fn_stats = TRACK_FUNC_PL;        /* ie, track if ALL */
283                         break;
284
285                 case SQLlanguageId:
286                         finfo->fn_addr = fmgr_sql;
287                         finfo->fn_stats = TRACK_FUNC_PL;        /* ie, track if ALL */
288                         break;
289
290                 default:
291                         fmgr_info_other_lang(functionId, finfo, procedureTuple);
292                         finfo->fn_stats = TRACK_FUNC_OFF;       /* ie, track if not OFF */
293                         break;
294         }
295
296         finfo->fn_oid = functionId;
297         ReleaseSysCache(procedureTuple);
298 }
299
300 /*
301  * Special fmgr_info processing for C-language functions.  Note that
302  * finfo->fn_oid is not valid yet.
303  */
304 static void
305 fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
306 {
307         Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
308         CFuncHashTabEntry *hashentry;
309         PGFunction      user_fn;
310         const Pg_finfo_record *inforec;
311         Oldstyle_fnextra *fnextra;
312         bool            isnull;
313         int                     i;
314
315         /*
316          * See if we have the function address cached already
317          */
318         hashentry = lookup_C_func(procedureTuple);
319         if (hashentry)
320         {
321                 user_fn = hashentry->user_fn;
322                 inforec = hashentry->inforec;
323         }
324         else
325         {
326                 Datum           prosrcattr,
327                                         probinattr;
328                 char       *prosrcstring,
329                                    *probinstring;
330                 void       *libraryhandle;
331
332                 /*
333                  * Get prosrc and probin strings (link symbol and library filename).
334                  * While in general these columns might be null, that's not allowed
335                  * for C-language functions.
336                  */
337                 prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
338                                                                          Anum_pg_proc_prosrc, &isnull);
339                 if (isnull)
340                         elog(ERROR, "null prosrc for C function %u", functionId);
341                 prosrcstring = TextDatumGetCString(prosrcattr);
342
343                 probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
344                                                                          Anum_pg_proc_probin, &isnull);
345                 if (isnull)
346                         elog(ERROR, "null probin for C function %u", functionId);
347                 probinstring = TextDatumGetCString(probinattr);
348
349                 /* Look up the function itself */
350                 user_fn = load_external_function(probinstring, prosrcstring, true,
351                                                                                  &libraryhandle);
352
353                 /* Get the function information record (real or default) */
354                 inforec = fetch_finfo_record(libraryhandle, prosrcstring);
355
356                 /* Cache the addresses for later calls */
357                 record_C_func(procedureTuple, user_fn, inforec);
358
359                 pfree(prosrcstring);
360                 pfree(probinstring);
361         }
362
363         switch (inforec->api_version)
364         {
365                 case 0:
366                         /* Old style: need to use a handler */
367                         finfo->fn_addr = fmgr_oldstyle;
368                         fnextra = (Oldstyle_fnextra *)
369                                 MemoryContextAllocZero(finfo->fn_mcxt,
370                                                                            sizeof(Oldstyle_fnextra));
371                         finfo->fn_extra = (void *) fnextra;
372                         fnextra->func = (func_ptr) user_fn;
373                         for (i = 0; i < procedureStruct->pronargs; i++)
374                         {
375                                 fnextra->arg_toastable[i] =
376                                         TypeIsToastable(procedureStruct->proargtypes.values[i]);
377                         }
378                         break;
379                 case 1:
380                         /* New style: call directly */
381                         finfo->fn_addr = user_fn;
382                         break;
383                 default:
384                         /* Shouldn't get here if fetch_finfo_record did its job */
385                         elog(ERROR, "unrecognized function API version: %d",
386                                  inforec->api_version);
387                         break;
388         }
389 }
390
391 /*
392  * Special fmgr_info processing for other-language functions.  Note
393  * that finfo->fn_oid is not valid yet.
394  */
395 static void
396 fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
397 {
398         Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
399         Oid                     language = procedureStruct->prolang;
400         HeapTuple       languageTuple;
401         Form_pg_language languageStruct;
402         FmgrInfo        plfinfo;
403
404         languageTuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(language));
405         if (!HeapTupleIsValid(languageTuple))
406                 elog(ERROR, "cache lookup failed for language %u", language);
407         languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
408
409         /*
410          * Look up the language's call handler function, ignoring any attributes
411          * that would normally cause insertion of fmgr_security_definer.  We need
412          * to get back a bare pointer to the actual C-language function.
413          */
414         fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
415                                                    CurrentMemoryContext, true);
416         finfo->fn_addr = plfinfo.fn_addr;
417
418         /*
419          * If lookup of the PL handler function produced nonnull fn_extra,
420          * complain --- it must be an oldstyle function! We no longer support
421          * oldstyle PL handlers.
422          */
423         if (plfinfo.fn_extra != NULL)
424                 elog(ERROR, "language %u has old-style handler", language);
425
426         ReleaseSysCache(languageTuple);
427 }
428
429 /*
430  * Fetch and validate the information record for the given external function.
431  * The function is specified by a handle for the containing library
432  * (obtained from load_external_function) as well as the function name.
433  *
434  * If no info function exists for the given name, it is not an error.
435  * Instead we return a default info record for a version-0 function.
436  * We want to raise an error here only if the info function returns
437  * something bogus.
438  *
439  * This function is broken out of fmgr_info_C_lang so that fmgr_c_validator
440  * can validate the information record for a function not yet entered into
441  * pg_proc.
442  */
443 const Pg_finfo_record *
444 fetch_finfo_record(void *filehandle, char *funcname)
445 {
446         char       *infofuncname;
447         PGFInfoFunction infofunc;
448         const Pg_finfo_record *inforec;
449         static Pg_finfo_record default_inforec = {0};
450
451         /* Compute name of info func */
452         infofuncname = (char *) palloc(strlen(funcname) + 10);
453         strcpy(infofuncname, "pg_finfo_");
454         strcat(infofuncname, funcname);
455
456         /* Try to look up the info function */
457         infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
458                                                                                                                   infofuncname);
459         if (infofunc == NULL)
460         {
461                 /* Not found --- assume version 0 */
462                 pfree(infofuncname);
463                 return &default_inforec;
464         }
465
466         /* Found, so call it */
467         inforec = (*infofunc) ();
468
469         /* Validate result as best we can */
470         if (inforec == NULL)
471                 elog(ERROR, "null result from info function \"%s\"", infofuncname);
472         switch (inforec->api_version)
473         {
474                 case 0:
475                 case 1:
476                         /* OK, no additional fields to validate */
477                         break;
478                 default:
479                         ereport(ERROR,
480                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
481                                          errmsg("unrecognized API version %d reported by info function \"%s\"",
482                                                         inforec->api_version, infofuncname)));
483                         break;
484         }
485
486         pfree(infofuncname);
487         return inforec;
488 }
489
490
491 /*-------------------------------------------------------------------------
492  *              Routines for caching lookup information for external C functions.
493  *
494  * The routines in dfmgr.c are relatively slow, so we try to avoid running
495  * them more than once per external function per session.  We use a hash table
496  * with the function OID as the lookup key.
497  *-------------------------------------------------------------------------
498  */
499
500 /*
501  * lookup_C_func: try to find a C function in the hash table
502  *
503  * If an entry exists and is up to date, return it; else return NULL
504  */
505 static CFuncHashTabEntry *
506 lookup_C_func(HeapTuple procedureTuple)
507 {
508         Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
509         CFuncHashTabEntry *entry;
510
511         if (CFuncHash == NULL)
512                 return NULL;                    /* no table yet */
513         entry = (CFuncHashTabEntry *)
514                 hash_search(CFuncHash,
515                                         &fn_oid,
516                                         HASH_FIND,
517                                         NULL);
518         if (entry == NULL)
519                 return NULL;                    /* no such entry */
520         if (entry->fn_xmin == HeapTupleHeaderGetXmin(procedureTuple->t_data) &&
521                 ItemPointerEquals(&entry->fn_tid, &procedureTuple->t_self))
522                 return entry;                   /* OK */
523         return NULL;                            /* entry is out of date */
524 }
525
526 /*
527  * record_C_func: enter (or update) info about a C function in the hash table
528  */
529 static void
530 record_C_func(HeapTuple procedureTuple,
531                           PGFunction user_fn, const Pg_finfo_record *inforec)
532 {
533         Oid                     fn_oid = HeapTupleGetOid(procedureTuple);
534         CFuncHashTabEntry *entry;
535         bool            found;
536
537         /* Create the hash table if it doesn't exist yet */
538         if (CFuncHash == NULL)
539         {
540                 HASHCTL         hash_ctl;
541
542                 MemSet(&hash_ctl, 0, sizeof(hash_ctl));
543                 hash_ctl.keysize = sizeof(Oid);
544                 hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
545                 hash_ctl.hash = oid_hash;
546                 CFuncHash = hash_create("CFuncHash",
547                                                                 100,
548                                                                 &hash_ctl,
549                                                                 HASH_ELEM | HASH_FUNCTION);
550         }
551
552         entry = (CFuncHashTabEntry *)
553                 hash_search(CFuncHash,
554                                         &fn_oid,
555                                         HASH_ENTER,
556                                         &found);
557         /* OID is already filled in */
558         entry->fn_xmin = HeapTupleHeaderGetXmin(procedureTuple->t_data);
559         entry->fn_tid = procedureTuple->t_self;
560         entry->user_fn = user_fn;
561         entry->inforec = inforec;
562 }
563
564 /*
565  * clear_external_function_hash: remove entries for a library being closed
566  *
567  * Presently we just zap the entire hash table, but later it might be worth
568  * the effort to remove only the entries associated with the given handle.
569  */
570 void
571 clear_external_function_hash(void *filehandle)
572 {
573         if (CFuncHash)
574                 hash_destroy(CFuncHash);
575         CFuncHash = NULL;
576 }
577
578
579 /*
580  * Copy an FmgrInfo struct
581  *
582  * This is inherently somewhat bogus since we can't reliably duplicate
583  * language-dependent subsidiary info.  We cheat by zeroing fn_extra,
584  * instead, meaning that subsidiary info will have to be recomputed.
585  */
586 void
587 fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
588                            MemoryContext destcxt)
589 {
590         memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
591         dstinfo->fn_mcxt = destcxt;
592         if (dstinfo->fn_addr == fmgr_oldstyle)
593         {
594                 /* For oldstyle functions we must copy fn_extra */
595                 Oldstyle_fnextra *fnextra;
596
597                 fnextra = (Oldstyle_fnextra *)
598                         MemoryContextAlloc(destcxt, sizeof(Oldstyle_fnextra));
599                 memcpy(fnextra, srcinfo->fn_extra, sizeof(Oldstyle_fnextra));
600                 dstinfo->fn_extra = (void *) fnextra;
601         }
602         else
603                 dstinfo->fn_extra = NULL;
604 }
605
606
607 /*
608  * Specialized lookup routine for fmgr_internal_validator: given the alleged
609  * name of an internal function, return the OID of the function.
610  * If the name is not recognized, return InvalidOid.
611  */
612 Oid
613 fmgr_internal_function(const char *proname)
614 {
615         const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
616
617         if (fbp == NULL)
618                 return InvalidOid;
619         return fbp->foid;
620 }
621
622
623 /*
624  * Handler for old-style "C" language functions
625  */
626 static Datum
627 fmgr_oldstyle(PG_FUNCTION_ARGS)
628 {
629         Oldstyle_fnextra *fnextra;
630         int                     n_arguments = fcinfo->nargs;
631         int                     i;
632         bool            isnull;
633         func_ptr        user_fn;
634         char       *returnValue;
635
636         if (fcinfo->flinfo == NULL || fcinfo->flinfo->fn_extra == NULL)
637                 elog(ERROR, "fmgr_oldstyle received NULL pointer");
638         fnextra = (Oldstyle_fnextra *) fcinfo->flinfo->fn_extra;
639
640         /*
641          * Result is NULL if any argument is NULL, but we still call the function
642          * (peculiar, but that's the way it worked before, and after all this is a
643          * backwards-compatibility wrapper).  Note, however, that we'll never get
644          * here with NULL arguments if the function is marked strict.
645          *
646          * We also need to detoast any TOAST-ed inputs, since it's unlikely that
647          * an old-style function knows about TOASTing.
648          */
649         isnull = false;
650         for (i = 0; i < n_arguments; i++)
651         {
652                 if (PG_ARGISNULL(i))
653                         isnull = true;
654                 else if (fnextra->arg_toastable[i])
655                         fcinfo->arg[i] = PointerGetDatum(PG_DETOAST_DATUM(fcinfo->arg[i]));
656         }
657         fcinfo->isnull = isnull;
658
659         user_fn = fnextra->func;
660
661         switch (n_arguments)
662         {
663                 case 0:
664                         returnValue = (char *) (*user_fn) ();
665                         break;
666                 case 1:
667
668                         /*
669                          * nullvalue() used to use isNull to check if arg is NULL; perhaps
670                          * there are other functions still out there that also rely on
671                          * this undocumented hack?
672                          */
673                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
674                                                                                            &fcinfo->isnull);
675                         break;
676                 case 2:
677                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
678                                                                                            fcinfo->arg[1]);
679                         break;
680                 case 3:
681                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
682                                                                                            fcinfo->arg[1],
683                                                                                            fcinfo->arg[2]);
684                         break;
685                 case 4:
686                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
687                                                                                            fcinfo->arg[1],
688                                                                                            fcinfo->arg[2],
689                                                                                            fcinfo->arg[3]);
690                         break;
691                 case 5:
692                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
693                                                                                            fcinfo->arg[1],
694                                                                                            fcinfo->arg[2],
695                                                                                            fcinfo->arg[3],
696                                                                                            fcinfo->arg[4]);
697                         break;
698                 case 6:
699                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
700                                                                                            fcinfo->arg[1],
701                                                                                            fcinfo->arg[2],
702                                                                                            fcinfo->arg[3],
703                                                                                            fcinfo->arg[4],
704                                                                                            fcinfo->arg[5]);
705                         break;
706                 case 7:
707                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
708                                                                                            fcinfo->arg[1],
709                                                                                            fcinfo->arg[2],
710                                                                                            fcinfo->arg[3],
711                                                                                            fcinfo->arg[4],
712                                                                                            fcinfo->arg[5],
713                                                                                            fcinfo->arg[6]);
714                         break;
715                 case 8:
716                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
717                                                                                            fcinfo->arg[1],
718                                                                                            fcinfo->arg[2],
719                                                                                            fcinfo->arg[3],
720                                                                                            fcinfo->arg[4],
721                                                                                            fcinfo->arg[5],
722                                                                                            fcinfo->arg[6],
723                                                                                            fcinfo->arg[7]);
724                         break;
725                 case 9:
726                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
727                                                                                            fcinfo->arg[1],
728                                                                                            fcinfo->arg[2],
729                                                                                            fcinfo->arg[3],
730                                                                                            fcinfo->arg[4],
731                                                                                            fcinfo->arg[5],
732                                                                                            fcinfo->arg[6],
733                                                                                            fcinfo->arg[7],
734                                                                                            fcinfo->arg[8]);
735                         break;
736                 case 10:
737                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
738                                                                                            fcinfo->arg[1],
739                                                                                            fcinfo->arg[2],
740                                                                                            fcinfo->arg[3],
741                                                                                            fcinfo->arg[4],
742                                                                                            fcinfo->arg[5],
743                                                                                            fcinfo->arg[6],
744                                                                                            fcinfo->arg[7],
745                                                                                            fcinfo->arg[8],
746                                                                                            fcinfo->arg[9]);
747                         break;
748                 case 11:
749                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
750                                                                                            fcinfo->arg[1],
751                                                                                            fcinfo->arg[2],
752                                                                                            fcinfo->arg[3],
753                                                                                            fcinfo->arg[4],
754                                                                                            fcinfo->arg[5],
755                                                                                            fcinfo->arg[6],
756                                                                                            fcinfo->arg[7],
757                                                                                            fcinfo->arg[8],
758                                                                                            fcinfo->arg[9],
759                                                                                            fcinfo->arg[10]);
760                         break;
761                 case 12:
762                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
763                                                                                            fcinfo->arg[1],
764                                                                                            fcinfo->arg[2],
765                                                                                            fcinfo->arg[3],
766                                                                                            fcinfo->arg[4],
767                                                                                            fcinfo->arg[5],
768                                                                                            fcinfo->arg[6],
769                                                                                            fcinfo->arg[7],
770                                                                                            fcinfo->arg[8],
771                                                                                            fcinfo->arg[9],
772                                                                                            fcinfo->arg[10],
773                                                                                            fcinfo->arg[11]);
774                         break;
775                 case 13:
776                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
777                                                                                            fcinfo->arg[1],
778                                                                                            fcinfo->arg[2],
779                                                                                            fcinfo->arg[3],
780                                                                                            fcinfo->arg[4],
781                                                                                            fcinfo->arg[5],
782                                                                                            fcinfo->arg[6],
783                                                                                            fcinfo->arg[7],
784                                                                                            fcinfo->arg[8],
785                                                                                            fcinfo->arg[9],
786                                                                                            fcinfo->arg[10],
787                                                                                            fcinfo->arg[11],
788                                                                                            fcinfo->arg[12]);
789                         break;
790                 case 14:
791                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
792                                                                                            fcinfo->arg[1],
793                                                                                            fcinfo->arg[2],
794                                                                                            fcinfo->arg[3],
795                                                                                            fcinfo->arg[4],
796                                                                                            fcinfo->arg[5],
797                                                                                            fcinfo->arg[6],
798                                                                                            fcinfo->arg[7],
799                                                                                            fcinfo->arg[8],
800                                                                                            fcinfo->arg[9],
801                                                                                            fcinfo->arg[10],
802                                                                                            fcinfo->arg[11],
803                                                                                            fcinfo->arg[12],
804                                                                                            fcinfo->arg[13]);
805                         break;
806                 case 15:
807                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
808                                                                                            fcinfo->arg[1],
809                                                                                            fcinfo->arg[2],
810                                                                                            fcinfo->arg[3],
811                                                                                            fcinfo->arg[4],
812                                                                                            fcinfo->arg[5],
813                                                                                            fcinfo->arg[6],
814                                                                                            fcinfo->arg[7],
815                                                                                            fcinfo->arg[8],
816                                                                                            fcinfo->arg[9],
817                                                                                            fcinfo->arg[10],
818                                                                                            fcinfo->arg[11],
819                                                                                            fcinfo->arg[12],
820                                                                                            fcinfo->arg[13],
821                                                                                            fcinfo->arg[14]);
822                         break;
823                 case 16:
824                         returnValue = (char *) (*user_fn) (fcinfo->arg[0],
825                                                                                            fcinfo->arg[1],
826                                                                                            fcinfo->arg[2],
827                                                                                            fcinfo->arg[3],
828                                                                                            fcinfo->arg[4],
829                                                                                            fcinfo->arg[5],
830                                                                                            fcinfo->arg[6],
831                                                                                            fcinfo->arg[7],
832                                                                                            fcinfo->arg[8],
833                                                                                            fcinfo->arg[9],
834                                                                                            fcinfo->arg[10],
835                                                                                            fcinfo->arg[11],
836                                                                                            fcinfo->arg[12],
837                                                                                            fcinfo->arg[13],
838                                                                                            fcinfo->arg[14],
839                                                                                            fcinfo->arg[15]);
840                         break;
841                 default:
842
843                         /*
844                          * Increasing FUNC_MAX_ARGS doesn't automatically add cases to the
845                          * above code, so mention the actual value in this error not
846                          * FUNC_MAX_ARGS.  You could add cases to the above if you needed
847                          * to support old-style functions with many arguments, but making
848                          * 'em be new-style is probably a better idea.
849                          */
850                         ereport(ERROR,
851                                         (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
852                          errmsg("function %u has too many arguments (%d, maximum is %d)",
853                                         fcinfo->flinfo->fn_oid, n_arguments, 16)));
854                         returnValue = NULL; /* keep compiler quiet */
855                         break;
856         }
857
858         return PointerGetDatum(returnValue);
859 }
860
861
862 /*
863  * Support for security-definer and proconfig-using functions.  We support
864  * both of these features using the same call handler, because they are
865  * often used together and it would be inefficient (as well as notationally
866  * messy) to have two levels of call handler involved.
867  */
868 struct fmgr_security_definer_cache
869 {
870         FmgrInfo        flinfo;                 /* lookup info for target function */
871         Oid                     userid;                 /* userid to set, or InvalidOid */
872         ArrayType  *proconfig;          /* GUC values to set, or NULL */
873         Datum           arg;                    /* passthrough argument for plugin modules */
874 };
875
876 /*
877  * Function handler for security-definer/proconfig/plugin-hooked functions.
878  * We extract the OID of the actual function and do a fmgr lookup again.
879  * Then we fetch the pg_proc row and copy the owner ID and proconfig fields.
880  * (All this info is cached for the duration of the current query.)
881  * To execute a call, we temporarily replace the flinfo with the cached
882  * and looked-up one, while keeping the outer fcinfo (which contains all
883  * the actual arguments, etc.) intact.  This is not re-entrant, but then
884  * the fcinfo itself can't be used re-entrantly anyway.
885  */
886 static Datum
887 fmgr_security_definer(PG_FUNCTION_ARGS)
888 {
889         Datum           result;
890         struct fmgr_security_definer_cache *volatile fcache;
891         FmgrInfo   *save_flinfo;
892         Oid                     save_userid;
893         int                     save_sec_context;
894         volatile int save_nestlevel;
895         PgStat_FunctionCallUsage fcusage;
896
897         if (!fcinfo->flinfo->fn_extra)
898         {
899                 HeapTuple       tuple;
900                 Form_pg_proc procedureStruct;
901                 Datum           datum;
902                 bool            isnull;
903                 MemoryContext oldcxt;
904
905                 fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
906                                                                                 sizeof(*fcache));
907
908                 fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
909                                                            fcinfo->flinfo->fn_mcxt, true);
910                 fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
911
912                 tuple = SearchSysCache1(PROCOID,
913                                                                 ObjectIdGetDatum(fcinfo->flinfo->fn_oid));
914                 if (!HeapTupleIsValid(tuple))
915                         elog(ERROR, "cache lookup failed for function %u",
916                                  fcinfo->flinfo->fn_oid);
917                 procedureStruct = (Form_pg_proc) GETSTRUCT(tuple);
918
919                 if (procedureStruct->prosecdef)
920                         fcache->userid = procedureStruct->proowner;
921
922                 datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proconfig,
923                                                                 &isnull);
924                 if (!isnull)
925                 {
926                         oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
927                         fcache->proconfig = DatumGetArrayTypePCopy(datum);
928                         MemoryContextSwitchTo(oldcxt);
929                 }
930
931                 ReleaseSysCache(tuple);
932
933                 fcinfo->flinfo->fn_extra = fcache;
934         }
935         else
936                 fcache = fcinfo->flinfo->fn_extra;
937
938         /* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
939         GetUserIdAndSecContext(&save_userid, &save_sec_context);
940         if (fcache->proconfig)          /* Need a new GUC nesting level */
941                 save_nestlevel = NewGUCNestLevel();
942         else
943                 save_nestlevel = 0;             /* keep compiler quiet */
944
945         if (OidIsValid(fcache->userid))
946                 SetUserIdAndSecContext(fcache->userid,
947                                                         save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
948
949         if (fcache->proconfig)
950         {
951                 ProcessGUCArray(fcache->proconfig,
952                                                 (superuser() ? PGC_SUSET : PGC_USERSET),
953                                                 PGC_S_SESSION,
954                                                 GUC_ACTION_SAVE);
955         }
956
957         /* function manager hook */
958         if (fmgr_hook)
959                 (*fmgr_hook) (FHET_START, &fcache->flinfo, &fcache->arg);
960
961         /*
962          * We don't need to restore GUC or userid settings on error, because the
963          * ensuing xact or subxact abort will do that.  The PG_TRY block is only
964          * needed to clean up the flinfo link.
965          */
966         save_flinfo = fcinfo->flinfo;
967
968         PG_TRY();
969         {
970                 fcinfo->flinfo = &fcache->flinfo;
971
972                 /* See notes in fmgr_info_cxt_security */
973                 pgstat_init_function_usage(fcinfo, &fcusage);
974
975                 result = FunctionCallInvoke(fcinfo);
976
977                 /*
978                  * We could be calling either a regular or a set-returning function,
979                  * so we have to test to see what finalize flag to use.
980                  */
981                 pgstat_end_function_usage(&fcusage,
982                                                                   (fcinfo->resultinfo == NULL ||
983                                                                    !IsA(fcinfo->resultinfo, ReturnSetInfo) ||
984                                                                    ((ReturnSetInfo *) fcinfo->resultinfo)->isDone != ExprMultipleResult));
985         }
986         PG_CATCH();
987         {
988                 fcinfo->flinfo = save_flinfo;
989                 if (fmgr_hook)
990                         (*fmgr_hook) (FHET_ABORT, &fcache->flinfo, &fcache->arg);
991                 PG_RE_THROW();
992         }
993         PG_END_TRY();
994
995         fcinfo->flinfo = save_flinfo;
996
997         if (fcache->proconfig)
998                 AtEOXact_GUC(true, save_nestlevel);
999         if (OidIsValid(fcache->userid))
1000                 SetUserIdAndSecContext(save_userid, save_sec_context);
1001         if (fmgr_hook)
1002                 (*fmgr_hook) (FHET_END, &fcache->flinfo, &fcache->arg);
1003
1004         return result;
1005 }
1006
1007
1008 /*-------------------------------------------------------------------------
1009  *              Support routines for callers of fmgr-compatible functions
1010  *-------------------------------------------------------------------------
1011  */
1012
1013 /*
1014  * These are for invocation of a specifically named function with a
1015  * directly-computed parameter list.  Note that neither arguments nor result
1016  * are allowed to be NULL.      Also, the function cannot be one that needs to
1017  * look at FmgrInfo, since there won't be any.
1018  */
1019 Datum
1020 DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
1021 {
1022         FunctionCallInfoData fcinfo;
1023         Datum           result;
1024
1025         InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
1026
1027         fcinfo.arg[0] = arg1;
1028         fcinfo.argnull[0] = false;
1029
1030         result = (*func) (&fcinfo);
1031
1032         /* Check for null result, since caller is clearly not expecting one */
1033         if (fcinfo.isnull)
1034                 elog(ERROR, "function %p returned NULL", (void *) func);
1035
1036         return result;
1037 }
1038
1039 Datum
1040 DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
1041 {
1042         FunctionCallInfoData fcinfo;
1043         Datum           result;
1044
1045         InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
1046
1047         fcinfo.arg[0] = arg1;
1048         fcinfo.arg[1] = arg2;
1049         fcinfo.argnull[0] = false;
1050         fcinfo.argnull[1] = false;
1051
1052         result = (*func) (&fcinfo);
1053
1054         /* Check for null result, since caller is clearly not expecting one */
1055         if (fcinfo.isnull)
1056                 elog(ERROR, "function %p returned NULL", (void *) func);
1057
1058         return result;
1059 }
1060
1061 Datum
1062 DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1063                                                 Datum arg3)
1064 {
1065         FunctionCallInfoData fcinfo;
1066         Datum           result;
1067
1068         InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
1069
1070         fcinfo.arg[0] = arg1;
1071         fcinfo.arg[1] = arg2;
1072         fcinfo.arg[2] = arg3;
1073         fcinfo.argnull[0] = false;
1074         fcinfo.argnull[1] = false;
1075         fcinfo.argnull[2] = false;
1076
1077         result = (*func) (&fcinfo);
1078
1079         /* Check for null result, since caller is clearly not expecting one */
1080         if (fcinfo.isnull)
1081                 elog(ERROR, "function %p returned NULL", (void *) func);
1082
1083         return result;
1084 }
1085
1086 Datum
1087 DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1088                                                 Datum arg3, Datum arg4)
1089 {
1090         FunctionCallInfoData fcinfo;
1091         Datum           result;
1092
1093         InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
1094
1095         fcinfo.arg[0] = arg1;
1096         fcinfo.arg[1] = arg2;
1097         fcinfo.arg[2] = arg3;
1098         fcinfo.arg[3] = arg4;
1099         fcinfo.argnull[0] = false;
1100         fcinfo.argnull[1] = false;
1101         fcinfo.argnull[2] = false;
1102         fcinfo.argnull[3] = false;
1103
1104         result = (*func) (&fcinfo);
1105
1106         /* Check for null result, since caller is clearly not expecting one */
1107         if (fcinfo.isnull)
1108                 elog(ERROR, "function %p returned NULL", (void *) func);
1109
1110         return result;
1111 }
1112
1113 Datum
1114 DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1115                                                 Datum arg3, Datum arg4, Datum arg5)
1116 {
1117         FunctionCallInfoData fcinfo;
1118         Datum           result;
1119
1120         InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
1121
1122         fcinfo.arg[0] = arg1;
1123         fcinfo.arg[1] = arg2;
1124         fcinfo.arg[2] = arg3;
1125         fcinfo.arg[3] = arg4;
1126         fcinfo.arg[4] = arg5;
1127         fcinfo.argnull[0] = false;
1128         fcinfo.argnull[1] = false;
1129         fcinfo.argnull[2] = false;
1130         fcinfo.argnull[3] = false;
1131         fcinfo.argnull[4] = false;
1132
1133         result = (*func) (&fcinfo);
1134
1135         /* Check for null result, since caller is clearly not expecting one */
1136         if (fcinfo.isnull)
1137                 elog(ERROR, "function %p returned NULL", (void *) func);
1138
1139         return result;
1140 }
1141
1142 Datum
1143 DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1144                                                 Datum arg3, Datum arg4, Datum arg5,
1145                                                 Datum arg6)
1146 {
1147         FunctionCallInfoData fcinfo;
1148         Datum           result;
1149
1150         InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
1151
1152         fcinfo.arg[0] = arg1;
1153         fcinfo.arg[1] = arg2;
1154         fcinfo.arg[2] = arg3;
1155         fcinfo.arg[3] = arg4;
1156         fcinfo.arg[4] = arg5;
1157         fcinfo.arg[5] = arg6;
1158         fcinfo.argnull[0] = false;
1159         fcinfo.argnull[1] = false;
1160         fcinfo.argnull[2] = false;
1161         fcinfo.argnull[3] = false;
1162         fcinfo.argnull[4] = false;
1163         fcinfo.argnull[5] = false;
1164
1165         result = (*func) (&fcinfo);
1166
1167         /* Check for null result, since caller is clearly not expecting one */
1168         if (fcinfo.isnull)
1169                 elog(ERROR, "function %p returned NULL", (void *) func);
1170
1171         return result;
1172 }
1173
1174 Datum
1175 DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1176                                                 Datum arg3, Datum arg4, Datum arg5,
1177                                                 Datum arg6, Datum arg7)
1178 {
1179         FunctionCallInfoData fcinfo;
1180         Datum           result;
1181
1182         InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
1183
1184         fcinfo.arg[0] = arg1;
1185         fcinfo.arg[1] = arg2;
1186         fcinfo.arg[2] = arg3;
1187         fcinfo.arg[3] = arg4;
1188         fcinfo.arg[4] = arg5;
1189         fcinfo.arg[5] = arg6;
1190         fcinfo.arg[6] = arg7;
1191         fcinfo.argnull[0] = false;
1192         fcinfo.argnull[1] = false;
1193         fcinfo.argnull[2] = false;
1194         fcinfo.argnull[3] = false;
1195         fcinfo.argnull[4] = false;
1196         fcinfo.argnull[5] = false;
1197         fcinfo.argnull[6] = false;
1198
1199         result = (*func) (&fcinfo);
1200
1201         /* Check for null result, since caller is clearly not expecting one */
1202         if (fcinfo.isnull)
1203                 elog(ERROR, "function %p returned NULL", (void *) func);
1204
1205         return result;
1206 }
1207
1208 Datum
1209 DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1210                                                 Datum arg3, Datum arg4, Datum arg5,
1211                                                 Datum arg6, Datum arg7, Datum arg8)
1212 {
1213         FunctionCallInfoData fcinfo;
1214         Datum           result;
1215
1216         InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
1217
1218         fcinfo.arg[0] = arg1;
1219         fcinfo.arg[1] = arg2;
1220         fcinfo.arg[2] = arg3;
1221         fcinfo.arg[3] = arg4;
1222         fcinfo.arg[4] = arg5;
1223         fcinfo.arg[5] = arg6;
1224         fcinfo.arg[6] = arg7;
1225         fcinfo.arg[7] = arg8;
1226         fcinfo.argnull[0] = false;
1227         fcinfo.argnull[1] = false;
1228         fcinfo.argnull[2] = false;
1229         fcinfo.argnull[3] = false;
1230         fcinfo.argnull[4] = false;
1231         fcinfo.argnull[5] = false;
1232         fcinfo.argnull[6] = false;
1233         fcinfo.argnull[7] = false;
1234
1235         result = (*func) (&fcinfo);
1236
1237         /* Check for null result, since caller is clearly not expecting one */
1238         if (fcinfo.isnull)
1239                 elog(ERROR, "function %p returned NULL", (void *) func);
1240
1241         return result;
1242 }
1243
1244 Datum
1245 DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
1246                                                 Datum arg3, Datum arg4, Datum arg5,
1247                                                 Datum arg6, Datum arg7, Datum arg8,
1248                                                 Datum arg9)
1249 {
1250         FunctionCallInfoData fcinfo;
1251         Datum           result;
1252
1253         InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
1254
1255         fcinfo.arg[0] = arg1;
1256         fcinfo.arg[1] = arg2;
1257         fcinfo.arg[2] = arg3;
1258         fcinfo.arg[3] = arg4;
1259         fcinfo.arg[4] = arg5;
1260         fcinfo.arg[5] = arg6;
1261         fcinfo.arg[6] = arg7;
1262         fcinfo.arg[7] = arg8;
1263         fcinfo.arg[8] = arg9;
1264         fcinfo.argnull[0] = false;
1265         fcinfo.argnull[1] = false;
1266         fcinfo.argnull[2] = false;
1267         fcinfo.argnull[3] = false;
1268         fcinfo.argnull[4] = false;
1269         fcinfo.argnull[5] = false;
1270         fcinfo.argnull[6] = false;
1271         fcinfo.argnull[7] = false;
1272         fcinfo.argnull[8] = false;
1273
1274         result = (*func) (&fcinfo);
1275
1276         /* Check for null result, since caller is clearly not expecting one */
1277         if (fcinfo.isnull)
1278                 elog(ERROR, "function %p returned NULL", (void *) func);
1279
1280         return result;
1281 }
1282
1283
1284 /*
1285  * These are for invocation of a previously-looked-up function with a
1286  * directly-computed parameter list.  Note that neither arguments nor result
1287  * are allowed to be NULL.
1288  */
1289 Datum
1290 FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
1291 {
1292         FunctionCallInfoData fcinfo;
1293         Datum           result;
1294
1295         InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
1296
1297         fcinfo.arg[0] = arg1;
1298         fcinfo.argnull[0] = false;
1299
1300         result = FunctionCallInvoke(&fcinfo);
1301
1302         /* Check for null result, since caller is clearly not expecting one */
1303         if (fcinfo.isnull)
1304                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1305
1306         return result;
1307 }
1308
1309 Datum
1310 FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
1311 {
1312         /*
1313          * XXX if you change this routine, see also the inlined version in
1314          * utils/sort/tuplesort.c!
1315          */
1316         FunctionCallInfoData fcinfo;
1317         Datum           result;
1318
1319         InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
1320
1321         fcinfo.arg[0] = arg1;
1322         fcinfo.arg[1] = arg2;
1323         fcinfo.argnull[0] = false;
1324         fcinfo.argnull[1] = false;
1325
1326         result = FunctionCallInvoke(&fcinfo);
1327
1328         /* Check for null result, since caller is clearly not expecting one */
1329         if (fcinfo.isnull)
1330                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1331
1332         return result;
1333 }
1334
1335 Datum
1336 FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1337                                   Datum arg3)
1338 {
1339         FunctionCallInfoData fcinfo;
1340         Datum           result;
1341
1342         InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
1343
1344         fcinfo.arg[0] = arg1;
1345         fcinfo.arg[1] = arg2;
1346         fcinfo.arg[2] = arg3;
1347         fcinfo.argnull[0] = false;
1348         fcinfo.argnull[1] = false;
1349         fcinfo.argnull[2] = false;
1350
1351         result = FunctionCallInvoke(&fcinfo);
1352
1353         /* Check for null result, since caller is clearly not expecting one */
1354         if (fcinfo.isnull)
1355                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1356
1357         return result;
1358 }
1359
1360 Datum
1361 FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1362                                   Datum arg3, Datum arg4)
1363 {
1364         FunctionCallInfoData fcinfo;
1365         Datum           result;
1366
1367         InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
1368
1369         fcinfo.arg[0] = arg1;
1370         fcinfo.arg[1] = arg2;
1371         fcinfo.arg[2] = arg3;
1372         fcinfo.arg[3] = arg4;
1373         fcinfo.argnull[0] = false;
1374         fcinfo.argnull[1] = false;
1375         fcinfo.argnull[2] = false;
1376         fcinfo.argnull[3] = false;
1377
1378         result = FunctionCallInvoke(&fcinfo);
1379
1380         /* Check for null result, since caller is clearly not expecting one */
1381         if (fcinfo.isnull)
1382                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1383
1384         return result;
1385 }
1386
1387 Datum
1388 FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1389                                   Datum arg3, Datum arg4, Datum arg5)
1390 {
1391         FunctionCallInfoData fcinfo;
1392         Datum           result;
1393
1394         InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
1395
1396         fcinfo.arg[0] = arg1;
1397         fcinfo.arg[1] = arg2;
1398         fcinfo.arg[2] = arg3;
1399         fcinfo.arg[3] = arg4;
1400         fcinfo.arg[4] = arg5;
1401         fcinfo.argnull[0] = false;
1402         fcinfo.argnull[1] = false;
1403         fcinfo.argnull[2] = false;
1404         fcinfo.argnull[3] = false;
1405         fcinfo.argnull[4] = false;
1406
1407         result = FunctionCallInvoke(&fcinfo);
1408
1409         /* Check for null result, since caller is clearly not expecting one */
1410         if (fcinfo.isnull)
1411                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1412
1413         return result;
1414 }
1415
1416 Datum
1417 FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1418                                   Datum arg3, Datum arg4, Datum arg5,
1419                                   Datum arg6)
1420 {
1421         FunctionCallInfoData fcinfo;
1422         Datum           result;
1423
1424         InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
1425
1426         fcinfo.arg[0] = arg1;
1427         fcinfo.arg[1] = arg2;
1428         fcinfo.arg[2] = arg3;
1429         fcinfo.arg[3] = arg4;
1430         fcinfo.arg[4] = arg5;
1431         fcinfo.arg[5] = arg6;
1432         fcinfo.argnull[0] = false;
1433         fcinfo.argnull[1] = false;
1434         fcinfo.argnull[2] = false;
1435         fcinfo.argnull[3] = false;
1436         fcinfo.argnull[4] = false;
1437         fcinfo.argnull[5] = false;
1438
1439         result = FunctionCallInvoke(&fcinfo);
1440
1441         /* Check for null result, since caller is clearly not expecting one */
1442         if (fcinfo.isnull)
1443                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1444
1445         return result;
1446 }
1447
1448 Datum
1449 FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1450                                   Datum arg3, Datum arg4, Datum arg5,
1451                                   Datum arg6, Datum arg7)
1452 {
1453         FunctionCallInfoData fcinfo;
1454         Datum           result;
1455
1456         InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
1457
1458         fcinfo.arg[0] = arg1;
1459         fcinfo.arg[1] = arg2;
1460         fcinfo.arg[2] = arg3;
1461         fcinfo.arg[3] = arg4;
1462         fcinfo.arg[4] = arg5;
1463         fcinfo.arg[5] = arg6;
1464         fcinfo.arg[6] = arg7;
1465         fcinfo.argnull[0] = false;
1466         fcinfo.argnull[1] = false;
1467         fcinfo.argnull[2] = false;
1468         fcinfo.argnull[3] = false;
1469         fcinfo.argnull[4] = false;
1470         fcinfo.argnull[5] = false;
1471         fcinfo.argnull[6] = false;
1472
1473         result = FunctionCallInvoke(&fcinfo);
1474
1475         /* Check for null result, since caller is clearly not expecting one */
1476         if (fcinfo.isnull)
1477                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1478
1479         return result;
1480 }
1481
1482 Datum
1483 FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1484                                   Datum arg3, Datum arg4, Datum arg5,
1485                                   Datum arg6, Datum arg7, Datum arg8)
1486 {
1487         FunctionCallInfoData fcinfo;
1488         Datum           result;
1489
1490         InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
1491
1492         fcinfo.arg[0] = arg1;
1493         fcinfo.arg[1] = arg2;
1494         fcinfo.arg[2] = arg3;
1495         fcinfo.arg[3] = arg4;
1496         fcinfo.arg[4] = arg5;
1497         fcinfo.arg[5] = arg6;
1498         fcinfo.arg[6] = arg7;
1499         fcinfo.arg[7] = arg8;
1500         fcinfo.argnull[0] = false;
1501         fcinfo.argnull[1] = false;
1502         fcinfo.argnull[2] = false;
1503         fcinfo.argnull[3] = false;
1504         fcinfo.argnull[4] = false;
1505         fcinfo.argnull[5] = false;
1506         fcinfo.argnull[6] = false;
1507         fcinfo.argnull[7] = false;
1508
1509         result = FunctionCallInvoke(&fcinfo);
1510
1511         /* Check for null result, since caller is clearly not expecting one */
1512         if (fcinfo.isnull)
1513                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1514
1515         return result;
1516 }
1517
1518 Datum
1519 FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
1520                                   Datum arg3, Datum arg4, Datum arg5,
1521                                   Datum arg6, Datum arg7, Datum arg8,
1522                                   Datum arg9)
1523 {
1524         FunctionCallInfoData fcinfo;
1525         Datum           result;
1526
1527         InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
1528
1529         fcinfo.arg[0] = arg1;
1530         fcinfo.arg[1] = arg2;
1531         fcinfo.arg[2] = arg3;
1532         fcinfo.arg[3] = arg4;
1533         fcinfo.arg[4] = arg5;
1534         fcinfo.arg[5] = arg6;
1535         fcinfo.arg[6] = arg7;
1536         fcinfo.arg[7] = arg8;
1537         fcinfo.arg[8] = arg9;
1538         fcinfo.argnull[0] = false;
1539         fcinfo.argnull[1] = false;
1540         fcinfo.argnull[2] = false;
1541         fcinfo.argnull[3] = false;
1542         fcinfo.argnull[4] = false;
1543         fcinfo.argnull[5] = false;
1544         fcinfo.argnull[6] = false;
1545         fcinfo.argnull[7] = false;
1546         fcinfo.argnull[8] = false;
1547
1548         result = FunctionCallInvoke(&fcinfo);
1549
1550         /* Check for null result, since caller is clearly not expecting one */
1551         if (fcinfo.isnull)
1552                 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1553
1554         return result;
1555 }
1556
1557
1558 /*
1559  * These are for invocation of a function identified by OID with a
1560  * directly-computed parameter list.  Note that neither arguments nor result
1561  * are allowed to be NULL.      These are essentially fmgr_info() followed
1562  * by FunctionCallN().  If the same function is to be invoked repeatedly,
1563  * do the fmgr_info() once and then use FunctionCallN().
1564  */
1565 Datum
1566 OidFunctionCall0Coll(Oid functionId, Oid collation)
1567 {
1568         FmgrInfo        flinfo;
1569         FunctionCallInfoData fcinfo;
1570         Datum           result;
1571
1572         fmgr_info(functionId, &flinfo);
1573
1574         InitFunctionCallInfoData(fcinfo, &flinfo, 0, collation, NULL, NULL);
1575
1576         result = FunctionCallInvoke(&fcinfo);
1577
1578         /* Check for null result, since caller is clearly not expecting one */
1579         if (fcinfo.isnull)
1580                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1581
1582         return result;
1583 }
1584
1585 Datum
1586 OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
1587 {
1588         FmgrInfo        flinfo;
1589         FunctionCallInfoData fcinfo;
1590         Datum           result;
1591
1592         fmgr_info(functionId, &flinfo);
1593
1594         InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL);
1595
1596         fcinfo.arg[0] = arg1;
1597         fcinfo.argnull[0] = false;
1598
1599         result = FunctionCallInvoke(&fcinfo);
1600
1601         /* Check for null result, since caller is clearly not expecting one */
1602         if (fcinfo.isnull)
1603                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1604
1605         return result;
1606 }
1607
1608 Datum
1609 OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
1610 {
1611         FmgrInfo        flinfo;
1612         FunctionCallInfoData fcinfo;
1613         Datum           result;
1614
1615         fmgr_info(functionId, &flinfo);
1616
1617         InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL);
1618
1619         fcinfo.arg[0] = arg1;
1620         fcinfo.arg[1] = arg2;
1621         fcinfo.argnull[0] = false;
1622         fcinfo.argnull[1] = false;
1623
1624         result = FunctionCallInvoke(&fcinfo);
1625
1626         /* Check for null result, since caller is clearly not expecting one */
1627         if (fcinfo.isnull)
1628                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1629
1630         return result;
1631 }
1632
1633 Datum
1634 OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1635                                          Datum arg3)
1636 {
1637         FmgrInfo        flinfo;
1638         FunctionCallInfoData fcinfo;
1639         Datum           result;
1640
1641         fmgr_info(functionId, &flinfo);
1642
1643         InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, NULL, NULL);
1644
1645         fcinfo.arg[0] = arg1;
1646         fcinfo.arg[1] = arg2;
1647         fcinfo.arg[2] = arg3;
1648         fcinfo.argnull[0] = false;
1649         fcinfo.argnull[1] = false;
1650         fcinfo.argnull[2] = false;
1651
1652         result = FunctionCallInvoke(&fcinfo);
1653
1654         /* Check for null result, since caller is clearly not expecting one */
1655         if (fcinfo.isnull)
1656                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1657
1658         return result;
1659 }
1660
1661 Datum
1662 OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1663                                          Datum arg3, Datum arg4)
1664 {
1665         FmgrInfo        flinfo;
1666         FunctionCallInfoData fcinfo;
1667         Datum           result;
1668
1669         fmgr_info(functionId, &flinfo);
1670
1671         InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, NULL, NULL);
1672
1673         fcinfo.arg[0] = arg1;
1674         fcinfo.arg[1] = arg2;
1675         fcinfo.arg[2] = arg3;
1676         fcinfo.arg[3] = arg4;
1677         fcinfo.argnull[0] = false;
1678         fcinfo.argnull[1] = false;
1679         fcinfo.argnull[2] = false;
1680         fcinfo.argnull[3] = false;
1681
1682         result = FunctionCallInvoke(&fcinfo);
1683
1684         /* Check for null result, since caller is clearly not expecting one */
1685         if (fcinfo.isnull)
1686                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1687
1688         return result;
1689 }
1690
1691 Datum
1692 OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1693                                          Datum arg3, Datum arg4, Datum arg5)
1694 {
1695         FmgrInfo        flinfo;
1696         FunctionCallInfoData fcinfo;
1697         Datum           result;
1698
1699         fmgr_info(functionId, &flinfo);
1700
1701         InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, NULL, NULL);
1702
1703         fcinfo.arg[0] = arg1;
1704         fcinfo.arg[1] = arg2;
1705         fcinfo.arg[2] = arg3;
1706         fcinfo.arg[3] = arg4;
1707         fcinfo.arg[4] = arg5;
1708         fcinfo.argnull[0] = false;
1709         fcinfo.argnull[1] = false;
1710         fcinfo.argnull[2] = false;
1711         fcinfo.argnull[3] = false;
1712         fcinfo.argnull[4] = false;
1713
1714         result = FunctionCallInvoke(&fcinfo);
1715
1716         /* Check for null result, since caller is clearly not expecting one */
1717         if (fcinfo.isnull)
1718                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1719
1720         return result;
1721 }
1722
1723 Datum
1724 OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1725                                          Datum arg3, Datum arg4, Datum arg5,
1726                                          Datum arg6)
1727 {
1728         FmgrInfo        flinfo;
1729         FunctionCallInfoData fcinfo;
1730         Datum           result;
1731
1732         fmgr_info(functionId, &flinfo);
1733
1734         InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, NULL, NULL);
1735
1736         fcinfo.arg[0] = arg1;
1737         fcinfo.arg[1] = arg2;
1738         fcinfo.arg[2] = arg3;
1739         fcinfo.arg[3] = arg4;
1740         fcinfo.arg[4] = arg5;
1741         fcinfo.arg[5] = arg6;
1742         fcinfo.argnull[0] = false;
1743         fcinfo.argnull[1] = false;
1744         fcinfo.argnull[2] = false;
1745         fcinfo.argnull[3] = false;
1746         fcinfo.argnull[4] = false;
1747         fcinfo.argnull[5] = false;
1748
1749         result = FunctionCallInvoke(&fcinfo);
1750
1751         /* Check for null result, since caller is clearly not expecting one */
1752         if (fcinfo.isnull)
1753                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1754
1755         return result;
1756 }
1757
1758 Datum
1759 OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1760                                          Datum arg3, Datum arg4, Datum arg5,
1761                                          Datum arg6, Datum arg7)
1762 {
1763         FmgrInfo        flinfo;
1764         FunctionCallInfoData fcinfo;
1765         Datum           result;
1766
1767         fmgr_info(functionId, &flinfo);
1768
1769         InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, NULL, NULL);
1770
1771         fcinfo.arg[0] = arg1;
1772         fcinfo.arg[1] = arg2;
1773         fcinfo.arg[2] = arg3;
1774         fcinfo.arg[3] = arg4;
1775         fcinfo.arg[4] = arg5;
1776         fcinfo.arg[5] = arg6;
1777         fcinfo.arg[6] = arg7;
1778         fcinfo.argnull[0] = false;
1779         fcinfo.argnull[1] = false;
1780         fcinfo.argnull[2] = false;
1781         fcinfo.argnull[3] = false;
1782         fcinfo.argnull[4] = false;
1783         fcinfo.argnull[5] = false;
1784         fcinfo.argnull[6] = false;
1785
1786         result = FunctionCallInvoke(&fcinfo);
1787
1788         /* Check for null result, since caller is clearly not expecting one */
1789         if (fcinfo.isnull)
1790                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1791
1792         return result;
1793 }
1794
1795 Datum
1796 OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1797                                          Datum arg3, Datum arg4, Datum arg5,
1798                                          Datum arg6, Datum arg7, Datum arg8)
1799 {
1800         FmgrInfo        flinfo;
1801         FunctionCallInfoData fcinfo;
1802         Datum           result;
1803
1804         fmgr_info(functionId, &flinfo);
1805
1806         InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, NULL, NULL);
1807
1808         fcinfo.arg[0] = arg1;
1809         fcinfo.arg[1] = arg2;
1810         fcinfo.arg[2] = arg3;
1811         fcinfo.arg[3] = arg4;
1812         fcinfo.arg[4] = arg5;
1813         fcinfo.arg[5] = arg6;
1814         fcinfo.arg[6] = arg7;
1815         fcinfo.arg[7] = arg8;
1816         fcinfo.argnull[0] = false;
1817         fcinfo.argnull[1] = false;
1818         fcinfo.argnull[2] = false;
1819         fcinfo.argnull[3] = false;
1820         fcinfo.argnull[4] = false;
1821         fcinfo.argnull[5] = false;
1822         fcinfo.argnull[6] = false;
1823         fcinfo.argnull[7] = false;
1824
1825         result = FunctionCallInvoke(&fcinfo);
1826
1827         /* Check for null result, since caller is clearly not expecting one */
1828         if (fcinfo.isnull)
1829                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1830
1831         return result;
1832 }
1833
1834 Datum
1835 OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1836                                          Datum arg3, Datum arg4, Datum arg5,
1837                                          Datum arg6, Datum arg7, Datum arg8,
1838                                          Datum arg9)
1839 {
1840         FmgrInfo        flinfo;
1841         FunctionCallInfoData fcinfo;
1842         Datum           result;
1843
1844         fmgr_info(functionId, &flinfo);
1845
1846         InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, NULL, NULL);
1847
1848         fcinfo.arg[0] = arg1;
1849         fcinfo.arg[1] = arg2;
1850         fcinfo.arg[2] = arg3;
1851         fcinfo.arg[3] = arg4;
1852         fcinfo.arg[4] = arg5;
1853         fcinfo.arg[5] = arg6;
1854         fcinfo.arg[6] = arg7;
1855         fcinfo.arg[7] = arg8;
1856         fcinfo.arg[8] = arg9;
1857         fcinfo.argnull[0] = false;
1858         fcinfo.argnull[1] = false;
1859         fcinfo.argnull[2] = false;
1860         fcinfo.argnull[3] = false;
1861         fcinfo.argnull[4] = false;
1862         fcinfo.argnull[5] = false;
1863         fcinfo.argnull[6] = false;
1864         fcinfo.argnull[7] = false;
1865         fcinfo.argnull[8] = false;
1866
1867         result = FunctionCallInvoke(&fcinfo);
1868
1869         /* Check for null result, since caller is clearly not expecting one */
1870         if (fcinfo.isnull)
1871                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1872
1873         return result;
1874 }
1875
1876
1877 /*
1878  * Special cases for convenient invocation of datatype I/O functions.
1879  */
1880
1881 /*
1882  * Call a previously-looked-up datatype input function.
1883  *
1884  * "str" may be NULL to indicate we are reading a NULL.  In this case
1885  * the caller should assume the result is NULL, but we'll call the input
1886  * function anyway if it's not strict.  So this is almost but not quite
1887  * the same as FunctionCall3.
1888  *
1889  * One important difference from the bare function call is that we will
1890  * push any active SPI context, allowing SPI-using I/O functions to be
1891  * called from other SPI functions without extra notation.      This is a hack,
1892  * but the alternative of expecting all SPI functions to do SPI_push/SPI_pop
1893  * around I/O calls seems worse.
1894  */
1895 Datum
1896 InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
1897 {
1898         FunctionCallInfoData fcinfo;
1899         Datum           result;
1900         bool            pushed;
1901
1902         if (str == NULL && flinfo->fn_strict)
1903                 return (Datum) 0;               /* just return null result */
1904
1905         pushed = SPI_push_conditional();
1906
1907         InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1908
1909         fcinfo.arg[0] = CStringGetDatum(str);
1910         fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
1911         fcinfo.arg[2] = Int32GetDatum(typmod);
1912         fcinfo.argnull[0] = (str == NULL);
1913         fcinfo.argnull[1] = false;
1914         fcinfo.argnull[2] = false;
1915
1916         result = FunctionCallInvoke(&fcinfo);
1917
1918         /* Should get null result if and only if str is NULL */
1919         if (str == NULL)
1920         {
1921                 if (!fcinfo.isnull)
1922                         elog(ERROR, "input function %u returned non-NULL",
1923                                  fcinfo.flinfo->fn_oid);
1924         }
1925         else
1926         {
1927                 if (fcinfo.isnull)
1928                         elog(ERROR, "input function %u returned NULL",
1929                                  fcinfo.flinfo->fn_oid);
1930         }
1931
1932         SPI_pop_conditional(pushed);
1933
1934         return result;
1935 }
1936
1937 /*
1938  * Call a previously-looked-up datatype output function.
1939  *
1940  * Do not call this on NULL datums.
1941  *
1942  * This is almost just window dressing for FunctionCall1, but it includes
1943  * SPI context pushing for the same reasons as InputFunctionCall.
1944  */
1945 char *
1946 OutputFunctionCall(FmgrInfo *flinfo, Datum val)
1947 {
1948         char       *result;
1949         bool            pushed;
1950
1951         pushed = SPI_push_conditional();
1952
1953         result = DatumGetCString(FunctionCall1(flinfo, val));
1954
1955         SPI_pop_conditional(pushed);
1956
1957         return result;
1958 }
1959
1960 /*
1961  * Call a previously-looked-up datatype binary-input function.
1962  *
1963  * "buf" may be NULL to indicate we are reading a NULL.  In this case
1964  * the caller should assume the result is NULL, but we'll call the receive
1965  * function anyway if it's not strict.  So this is almost but not quite
1966  * the same as FunctionCall3.  Also, this includes SPI context pushing for
1967  * the same reasons as InputFunctionCall.
1968  */
1969 Datum
1970 ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
1971                                         Oid typioparam, int32 typmod)
1972 {
1973         FunctionCallInfoData fcinfo;
1974         Datum           result;
1975         bool            pushed;
1976
1977         if (buf == NULL && flinfo->fn_strict)
1978                 return (Datum) 0;               /* just return null result */
1979
1980         pushed = SPI_push_conditional();
1981
1982         InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1983
1984         fcinfo.arg[0] = PointerGetDatum(buf);
1985         fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
1986         fcinfo.arg[2] = Int32GetDatum(typmod);
1987         fcinfo.argnull[0] = (buf == NULL);
1988         fcinfo.argnull[1] = false;
1989         fcinfo.argnull[2] = false;
1990
1991         result = FunctionCallInvoke(&fcinfo);
1992
1993         /* Should get null result if and only if buf is NULL */
1994         if (buf == NULL)
1995         {
1996                 if (!fcinfo.isnull)
1997                         elog(ERROR, "receive function %u returned non-NULL",
1998                                  fcinfo.flinfo->fn_oid);
1999         }
2000         else
2001         {
2002                 if (fcinfo.isnull)
2003                         elog(ERROR, "receive function %u returned NULL",
2004                                  fcinfo.flinfo->fn_oid);
2005         }
2006
2007         SPI_pop_conditional(pushed);
2008
2009         return result;
2010 }
2011
2012 /*
2013  * Call a previously-looked-up datatype binary-output function.
2014  *
2015  * Do not call this on NULL datums.
2016  *
2017  * This is little more than window dressing for FunctionCall1, but it does
2018  * guarantee a non-toasted result, which strictly speaking the underlying
2019  * function doesn't.  Also, this includes SPI context pushing for the same
2020  * reasons as InputFunctionCall.
2021  */
2022 bytea *
2023 SendFunctionCall(FmgrInfo *flinfo, Datum val)
2024 {
2025         bytea      *result;
2026         bool            pushed;
2027
2028         pushed = SPI_push_conditional();
2029
2030         result = DatumGetByteaP(FunctionCall1(flinfo, val));
2031
2032         SPI_pop_conditional(pushed);
2033
2034         return result;
2035 }
2036
2037 /*
2038  * As above, for I/O functions identified by OID.  These are only to be used
2039  * in seldom-executed code paths.  They are not only slow but leak memory.
2040  */
2041 Datum
2042 OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
2043 {
2044         FmgrInfo        flinfo;
2045
2046         fmgr_info(functionId, &flinfo);
2047         return InputFunctionCall(&flinfo, str, typioparam, typmod);
2048 }
2049
2050 char *
2051 OidOutputFunctionCall(Oid functionId, Datum val)
2052 {
2053         FmgrInfo        flinfo;
2054
2055         fmgr_info(functionId, &flinfo);
2056         return OutputFunctionCall(&flinfo, val);
2057 }
2058
2059 Datum
2060 OidReceiveFunctionCall(Oid functionId, StringInfo buf,
2061                                            Oid typioparam, int32 typmod)
2062 {
2063         FmgrInfo        flinfo;
2064
2065         fmgr_info(functionId, &flinfo);
2066         return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
2067 }
2068
2069 bytea *
2070 OidSendFunctionCall(Oid functionId, Datum val)
2071 {
2072         FmgrInfo        flinfo;
2073
2074         fmgr_info(functionId, &flinfo);
2075         return SendFunctionCall(&flinfo, val);
2076 }
2077
2078
2079 /*
2080  * !!! OLD INTERFACE !!!
2081  *
2082  * fmgr() is the only remaining vestige of the old-style caller support
2083  * functions.  It's no longer used anywhere in the Postgres distribution,
2084  * but we should leave it around for a release or two to ease the transition
2085  * for user-supplied C functions.  OidFunctionCallN() replaces it for new
2086  * code.
2087  *
2088  * DEPRECATED, DO NOT USE IN NEW CODE
2089  */
2090 char *
2091 fmgr(Oid procedureId,...)
2092 {
2093         FmgrInfo        flinfo;
2094         FunctionCallInfoData fcinfo;
2095         int                     n_arguments;
2096         Datum           result;
2097
2098         fmgr_info(procedureId, &flinfo);
2099
2100         MemSet(&fcinfo, 0, sizeof(fcinfo));
2101         fcinfo.flinfo = &flinfo;
2102         fcinfo.nargs = flinfo.fn_nargs;
2103         n_arguments = fcinfo.nargs;
2104
2105         if (n_arguments > 0)
2106         {
2107                 va_list         pvar;
2108                 int                     i;
2109
2110                 if (n_arguments > FUNC_MAX_ARGS)
2111                         ereport(ERROR,
2112                                         (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2113                          errmsg("function %u has too many arguments (%d, maximum is %d)",
2114                                         flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS)));
2115                 va_start(pvar, procedureId);
2116                 for (i = 0; i < n_arguments; i++)
2117                         fcinfo.arg[i] = PointerGetDatum(va_arg(pvar, char *));
2118                 va_end(pvar);
2119         }
2120
2121         result = FunctionCallInvoke(&fcinfo);
2122
2123         /* Check for null result, since caller is clearly not expecting one */
2124         if (fcinfo.isnull)
2125                 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
2126
2127         return DatumGetPointer(result);
2128 }
2129
2130
2131 /*-------------------------------------------------------------------------
2132  *              Support routines for standard maybe-pass-by-reference datatypes
2133  *
2134  * int8, float4, and float8 can be passed by value if Datum is wide enough.
2135  * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
2136  * at compile time even if pass-by-val is possible.)  For the float types,
2137  * we need a support routine even if we are passing by value, because many
2138  * machines pass int and float function parameters/results differently;
2139  * so we need to play weird games with unions.
2140  *
2141  * Note: there is only one switch controlling the pass-by-value option for
2142  * both int8 and float8; this is to avoid making things unduly complicated
2143  * for the timestamp types, which might have either representation.
2144  *-------------------------------------------------------------------------
2145  */
2146
2147 #ifndef USE_FLOAT8_BYVAL                /* controls int8 too */
2148
2149 Datum
2150 Int64GetDatum(int64 X)
2151 {
2152         int64      *retval = (int64 *) palloc(sizeof(int64));
2153
2154         *retval = X;
2155         return PointerGetDatum(retval);
2156 }
2157 #endif   /* USE_FLOAT8_BYVAL */
2158
2159 Datum
2160 Float4GetDatum(float4 X)
2161 {
2162 #ifdef USE_FLOAT4_BYVAL
2163         union
2164         {
2165                 float4          value;
2166                 int32           retval;
2167         }                       myunion;
2168
2169         myunion.value = X;
2170         return SET_4_BYTES(myunion.retval);
2171 #else
2172         float4     *retval = (float4 *) palloc(sizeof(float4));
2173
2174         *retval = X;
2175         return PointerGetDatum(retval);
2176 #endif
2177 }
2178
2179 #ifdef USE_FLOAT4_BYVAL
2180
2181 float4
2182 DatumGetFloat4(Datum X)
2183 {
2184         union
2185         {
2186                 int32           value;
2187                 float4          retval;
2188         }                       myunion;
2189
2190         myunion.value = GET_4_BYTES(X);
2191         return myunion.retval;
2192 }
2193 #endif   /* USE_FLOAT4_BYVAL */
2194
2195 Datum
2196 Float8GetDatum(float8 X)
2197 {
2198 #ifdef USE_FLOAT8_BYVAL
2199         union
2200         {
2201                 float8          value;
2202                 int64           retval;
2203         }                       myunion;
2204
2205         myunion.value = X;
2206         return SET_8_BYTES(myunion.retval);
2207 #else
2208         float8     *retval = (float8 *) palloc(sizeof(float8));
2209
2210         *retval = X;
2211         return PointerGetDatum(retval);
2212 #endif
2213 }
2214
2215 #ifdef USE_FLOAT8_BYVAL
2216
2217 float8
2218 DatumGetFloat8(Datum X)
2219 {
2220         union
2221         {
2222                 int64           value;
2223                 float8          retval;
2224         }                       myunion;
2225
2226         myunion.value = GET_8_BYTES(X);
2227         return myunion.retval;
2228 }
2229 #endif   /* USE_FLOAT8_BYVAL */
2230
2231
2232 /*-------------------------------------------------------------------------
2233  *              Support routines for toastable datatypes
2234  *-------------------------------------------------------------------------
2235  */
2236
2237 struct varlena *
2238 pg_detoast_datum(struct varlena * datum)
2239 {
2240         if (VARATT_IS_EXTENDED(datum))
2241                 return heap_tuple_untoast_attr(datum);
2242         else
2243                 return datum;
2244 }
2245
2246 struct varlena *
2247 pg_detoast_datum_copy(struct varlena * datum)
2248 {
2249         if (VARATT_IS_EXTENDED(datum))
2250                 return heap_tuple_untoast_attr(datum);
2251         else
2252         {
2253                 /* Make a modifiable copy of the varlena object */
2254                 Size            len = VARSIZE(datum);
2255                 struct varlena *result = (struct varlena *) palloc(len);
2256
2257                 memcpy(result, datum, len);
2258                 return result;
2259         }
2260 }
2261
2262 struct varlena *
2263 pg_detoast_datum_slice(struct varlena * datum, int32 first, int32 count)
2264 {
2265         /* Only get the specified portion from the toast rel */
2266         return heap_tuple_untoast_attr_slice(datum, first, count);
2267 }
2268
2269 struct varlena *
2270 pg_detoast_datum_packed(struct varlena * datum)
2271 {
2272         if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
2273                 return heap_tuple_untoast_attr(datum);
2274         else
2275                 return datum;
2276 }
2277
2278 /*-------------------------------------------------------------------------
2279  *              Support routines for extracting info from fn_expr parse tree
2280  *
2281  * These are needed by polymorphic functions, which accept multiple possible
2282  * input types and need help from the parser to know what they've got.
2283  * Also, some functions might be interested in whether a parameter is constant.
2284  * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
2285  *-------------------------------------------------------------------------
2286  */
2287
2288 /*
2289  * Get the actual type OID of the function return type
2290  *
2291  * Returns InvalidOid if information is not available
2292  */
2293 Oid
2294 get_fn_expr_rettype(FmgrInfo *flinfo)
2295 {
2296         Node       *expr;
2297
2298         /*
2299          * can't return anything useful if we have no FmgrInfo or if its fn_expr
2300          * node has not been initialized
2301          */
2302         if (!flinfo || !flinfo->fn_expr)
2303                 return InvalidOid;
2304
2305         expr = flinfo->fn_expr;
2306
2307         return exprType(expr);
2308 }
2309
2310 /*
2311  * Get the actual type OID of a specific function argument (counting from 0)
2312  *
2313  * Returns InvalidOid if information is not available
2314  */
2315 Oid
2316 get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
2317 {
2318         /*
2319          * can't return anything useful if we have no FmgrInfo or if its fn_expr
2320          * node has not been initialized
2321          */
2322         if (!flinfo || !flinfo->fn_expr)
2323                 return InvalidOid;
2324
2325         return get_call_expr_argtype(flinfo->fn_expr, argnum);
2326 }
2327
2328 /*
2329  * Get the actual type OID of a specific function argument (counting from 0),
2330  * but working from the calling expression tree instead of FmgrInfo
2331  *
2332  * Returns InvalidOid if information is not available
2333  */
2334 Oid
2335 get_call_expr_argtype(Node *expr, int argnum)
2336 {
2337         List       *args;
2338         Oid                     argtype;
2339
2340         if (expr == NULL)
2341                 return InvalidOid;
2342
2343         if (IsA(expr, FuncExpr))
2344                 args = ((FuncExpr *) expr)->args;
2345         else if (IsA(expr, OpExpr))
2346                 args = ((OpExpr *) expr)->args;
2347         else if (IsA(expr, DistinctExpr))
2348                 args = ((DistinctExpr *) expr)->args;
2349         else if (IsA(expr, ScalarArrayOpExpr))
2350                 args = ((ScalarArrayOpExpr *) expr)->args;
2351         else if (IsA(expr, ArrayCoerceExpr))
2352                 args = list_make1(((ArrayCoerceExpr *) expr)->arg);
2353         else if (IsA(expr, NullIfExpr))
2354                 args = ((NullIfExpr *) expr)->args;
2355         else if (IsA(expr, WindowFunc))
2356                 args = ((WindowFunc *) expr)->args;
2357         else
2358                 return InvalidOid;
2359
2360         if (argnum < 0 || argnum >= list_length(args))
2361                 return InvalidOid;
2362
2363         argtype = exprType((Node *) list_nth(args, argnum));
2364
2365         /*
2366          * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the
2367          * underlying function will actually get passed is the element type of the
2368          * array.
2369          */
2370         if (IsA(expr, ScalarArrayOpExpr) &&
2371                 argnum == 1)
2372                 argtype = get_base_element_type(argtype);
2373         else if (IsA(expr, ArrayCoerceExpr) &&
2374                          argnum == 0)
2375                 argtype = get_base_element_type(argtype);
2376
2377         return argtype;
2378 }
2379
2380 /*
2381  * Find out whether a specific function argument is constant for the
2382  * duration of a query
2383  *
2384  * Returns false if information is not available
2385  */
2386 bool
2387 get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
2388 {
2389         /*
2390          * can't return anything useful if we have no FmgrInfo or if its fn_expr
2391          * node has not been initialized
2392          */
2393         if (!flinfo || !flinfo->fn_expr)
2394                 return false;
2395
2396         return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
2397 }
2398
2399 /*
2400  * Find out whether a specific function argument is constant for the
2401  * duration of a query, but working from the calling expression tree
2402  *
2403  * Returns false if information is not available
2404  */
2405 bool
2406 get_call_expr_arg_stable(Node *expr, int argnum)
2407 {
2408         List       *args;
2409         Node       *arg;
2410
2411         if (expr == NULL)
2412                 return false;
2413
2414         if (IsA(expr, FuncExpr))
2415                 args = ((FuncExpr *) expr)->args;
2416         else if (IsA(expr, OpExpr))
2417                 args = ((OpExpr *) expr)->args;
2418         else if (IsA(expr, DistinctExpr))
2419                 args = ((DistinctExpr *) expr)->args;
2420         else if (IsA(expr, ScalarArrayOpExpr))
2421                 args = ((ScalarArrayOpExpr *) expr)->args;
2422         else if (IsA(expr, ArrayCoerceExpr))
2423                 args = list_make1(((ArrayCoerceExpr *) expr)->arg);
2424         else if (IsA(expr, NullIfExpr))
2425                 args = ((NullIfExpr *) expr)->args;
2426         else if (IsA(expr, WindowFunc))
2427                 args = ((WindowFunc *) expr)->args;
2428         else
2429                 return false;
2430
2431         if (argnum < 0 || argnum >= list_length(args))
2432                 return false;
2433
2434         arg = (Node *) list_nth(args, argnum);
2435
2436         /*
2437          * Either a true Const or an external Param will have a value that doesn't
2438          * change during the execution of the query.  In future we might want to
2439          * consider other cases too, e.g. now().
2440          */
2441         if (IsA(arg, Const))
2442                 return true;
2443         if (IsA(arg, Param) &&
2444                 ((Param *) arg)->paramkind == PARAM_EXTERN)
2445                 return true;
2446
2447         return false;
2448 }
2449
2450 /*
2451  * Get the VARIADIC flag from the function invocation
2452  *
2453  * Returns false (the default assumption) if information is not available
2454  */
2455 bool
2456 get_fn_expr_variadic(FmgrInfo *flinfo)
2457 {
2458         Node       *expr;
2459
2460         /*
2461          * can't return anything useful if we have no FmgrInfo or if its fn_expr
2462          * node has not been initialized
2463          */
2464         if (!flinfo || !flinfo->fn_expr)
2465                 return false;
2466
2467         expr = flinfo->fn_expr;
2468
2469         if (IsA(expr, FuncExpr))
2470                 return ((FuncExpr *) expr)->funcvariadic;
2471         else
2472                 return false;
2473 }