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