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