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