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