1 /*-------------------------------------------------------------------------
4 * The Postgres function manager.
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.88 2004/12/31 22:01:31 pgsql Exp $
13 *-------------------------------------------------------------------------
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"
30 * Declaration for old-style function pointer type. This is now used only
31 * in fmgr_oldstyle() and is no longer exported.
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...
43 #if (defined(__mc68000__) || (defined(__m68k__))) && defined(__ELF__)
44 typedef int32 (*func_ptr) ();
46 typedef char * (*func_ptr) ();
50 * For an oldstyle function, fn_extra points to a record like this:
54 func_ptr func; /* Address of the oldstyle function */
55 bool arg_toastable[FUNC_MAX_ARGS]; /* is n'th arg of a
56 * toastable datatype? */
60 * Hashtable for fast lookup of external C functions
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 */
68 PGFunction user_fn; /* the function's address */
69 Pg_finfo_record *inforec; /* address of its info record */
72 static HTAB *CFuncHash = NULL;
75 static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
76 bool ignore_security);
77 static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
78 static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
79 static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple);
80 static void record_C_func(HeapTuple procedureTuple,
81 PGFunction user_fn, Pg_finfo_record *inforec);
82 static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
83 static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
87 * Lookup routines for builtin-function table. We can search by either Oid
88 * or name, but search by Oid is much faster.
91 static const FmgrBuiltin *
92 fmgr_isbuiltin(Oid id)
95 int high = fmgr_nbuiltins - 1;
98 * Loop invariant: low is the first index that could contain target
99 * entry, and high is the last index that could contain it.
103 int i = (high + low) / 2;
104 const FmgrBuiltin *ptr = &fmgr_builtins[i];
108 else if (id > ptr->foid)
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
121 static const FmgrBuiltin *
122 fmgr_lookupByName(const char *name)
126 for (i = 0; i < fmgr_nbuiltins; i++)
128 if (strcmp(name, fmgr_builtins[i].funcName) == 0)
129 return fmgr_builtins + i;
135 * This routine fills a FmgrInfo struct, given the OID
136 * of the function to be called.
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.
148 fmgr_info(Oid functionId, FmgrInfo *finfo)
150 fmgr_info_cxt(functionId, finfo, CurrentMemoryContext);
154 * Fill a FmgrInfo struct, specifying a memory context in which its
155 * subsidiary data should go.
158 fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
160 fmgr_info_cxt_security(functionId, finfo, mcxt, false);
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
169 fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
170 bool ignore_security)
172 const FmgrBuiltin *fbp;
173 HeapTuple procedureTuple;
174 Form_pg_proc procedureStruct;
180 * fn_oid *must* be filled in last. Some code assumes that if fn_oid
181 * is valid, the whole struct is valid. Some FmgrInfo struct's do
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 */
189 if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
192 * Fast path for builtin functions: don't bother consulting
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;
203 /* Otherwise we need the pg_proc entry */
204 procedureTuple = SearchSysCache(PROCOID,
205 ObjectIdGetDatum(functionId),
207 if (!HeapTupleIsValid(procedureTuple))
208 elog(ERROR, "cache lookup failed for function %u", functionId);
209 procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
211 finfo->fn_nargs = procedureStruct->pronargs;
212 finfo->fn_strict = procedureStruct->proisstrict;
213 finfo->fn_retset = procedureStruct->proretset;
215 if (procedureStruct->prosecdef && !ignore_security)
217 finfo->fn_addr = fmgr_security_definer;
218 finfo->fn_oid = functionId;
219 ReleaseSysCache(procedureTuple);
223 switch (procedureStruct->prolang)
225 case INTERNALlanguageId:
228 * For an ordinary builtin function, we should never get here
229 * because the isbuiltin() search above will have succeeded.
230 * However, if the user has done a CREATE FUNCTION to create
231 * an alias for a builtin function, we can end up here. In
232 * that case we have to look up the function by name. The
233 * name of the internal function is stored in prosrc (it
234 * doesn't have to be the same as the name of the alias!)
236 prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
237 Anum_pg_proc_prosrc, &isnull);
239 elog(ERROR, "null prosrc");
240 prosrc = DatumGetCString(DirectFunctionCall1(textout,
242 fbp = fmgr_lookupByName(prosrc);
245 (errcode(ERRCODE_UNDEFINED_FUNCTION),
246 errmsg("internal function \"%s\" is not in internal lookup table",
249 /* Should we check that nargs, strict, retset match the table? */
250 finfo->fn_addr = fbp->func;
254 fmgr_info_C_lang(functionId, finfo, procedureTuple);
258 finfo->fn_addr = fmgr_sql;
262 fmgr_info_other_lang(functionId, finfo, procedureTuple);
266 finfo->fn_oid = functionId;
267 ReleaseSysCache(procedureTuple);
271 * Special fmgr_info processing for C-language functions. Note that
272 * finfo->fn_oid is not valid yet.
275 fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
277 Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
278 CFuncHashTabEntry *hashentry;
280 Pg_finfo_record *inforec;
281 Oldstyle_fnextra *fnextra;
286 * See if we have the function address cached already
288 hashentry = lookup_C_func(procedureTuple);
291 user_fn = hashentry->user_fn;
292 inforec = hashentry->inforec;
303 * Get prosrc and probin strings (link symbol and library
306 prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
307 Anum_pg_proc_prosrc, &isnull);
309 elog(ERROR, "null prosrc for function %u", functionId);
310 prosrcstring = DatumGetCString(DirectFunctionCall1(textout,
313 probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
314 Anum_pg_proc_probin, &isnull);
316 elog(ERROR, "null probin for function %u", functionId);
317 probinstring = DatumGetCString(DirectFunctionCall1(textout,
320 /* Look up the function itself */
321 user_fn = load_external_function(probinstring, prosrcstring, true,
324 /* Get the function information record (real or default) */
325 inforec = fetch_finfo_record(libraryhandle, prosrcstring);
327 /* Cache the addresses for later calls */
328 record_C_func(procedureTuple, user_fn, inforec);
334 switch (inforec->api_version)
337 /* Old style: need to use a handler */
338 finfo->fn_addr = fmgr_oldstyle;
339 fnextra = (Oldstyle_fnextra *)
340 MemoryContextAlloc(finfo->fn_mcxt, sizeof(Oldstyle_fnextra));
341 finfo->fn_extra = (void *) fnextra;
342 MemSet(fnextra, 0, sizeof(Oldstyle_fnextra));
343 fnextra->func = (func_ptr) user_fn;
344 for (i = 0; i < procedureStruct->pronargs; i++)
346 fnextra->arg_toastable[i] =
347 TypeIsToastable(procedureStruct->proargtypes[i]);
351 /* New style: call directly */
352 finfo->fn_addr = user_fn;
355 /* Shouldn't get here if fetch_finfo_record did its job */
356 elog(ERROR, "unrecognized function API version: %d",
357 inforec->api_version);
363 * Special fmgr_info processing for other-language functions. Note
364 * that finfo->fn_oid is not valid yet.
367 fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
369 Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
370 Oid language = procedureStruct->prolang;
371 HeapTuple languageTuple;
372 Form_pg_language languageStruct;
375 languageTuple = SearchSysCache(LANGOID,
376 ObjectIdGetDatum(language),
378 if (!HeapTupleIsValid(languageTuple))
379 elog(ERROR, "cache lookup failed for language %u", language);
380 languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
382 fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
383 finfo->fn_addr = plfinfo.fn_addr;
386 * If lookup of the PL handler function produced nonnull fn_extra,
387 * complain --- it must be an oldstyle function! We no longer support
388 * oldstyle PL handlers.
390 if (plfinfo.fn_extra != NULL)
391 elog(ERROR, "language %u has old-style handler", language);
393 ReleaseSysCache(languageTuple);
397 * Fetch and validate the information record for the given external function.
398 * The function is specified by a handle for the containing library
399 * (obtained from load_external_function) as well as the function name.
401 * If no info function exists for the given name, it is not an error.
402 * Instead we return a default info record for a version-0 function.
403 * We want to raise an error here only if the info function returns
406 * This function is broken out of fmgr_info_C_lang() so that ProcedureCreate()
407 * can validate the information record for a function not yet entered into
411 fetch_finfo_record(void *filehandle, char *funcname)
414 PGFInfoFunction infofunc;
415 Pg_finfo_record *inforec;
416 static Pg_finfo_record default_inforec = {0};
418 /* Compute name of info func */
419 infofuncname = (char *) palloc(strlen(funcname) + 10);
420 strcpy(infofuncname, "pg_finfo_");
421 strcat(infofuncname, funcname);
423 /* Try to look up the info function */
424 infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
426 if (infofunc == NULL)
428 /* Not found --- assume version 0 */
430 return &default_inforec;
433 /* Found, so call it */
434 inforec = (*infofunc) ();
436 /* Validate result as best we can */
438 elog(ERROR, "null result from info function \"%s\"", infofuncname);
439 switch (inforec->api_version)
443 /* OK, no additional fields to validate */
447 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
448 errmsg("unrecognized API version %d reported by info function \"%s\"",
449 inforec->api_version, infofuncname)));
458 /*-------------------------------------------------------------------------
459 * Routines for caching lookup information for external C functions.
461 * The routines in dfmgr.c are relatively slow, so we try to avoid running
462 * them more than once per external function per session. We use a hash table
463 * with the function OID as the lookup key.
464 *-------------------------------------------------------------------------
468 * lookup_C_func: try to find a C function in the hash table
470 * If an entry exists and is up to date, return it; else return NULL
472 static CFuncHashTabEntry *
473 lookup_C_func(HeapTuple procedureTuple)
475 Oid fn_oid = HeapTupleGetOid(procedureTuple);
476 CFuncHashTabEntry *entry;
478 if (CFuncHash == NULL)
479 return NULL; /* no table yet */
480 entry = (CFuncHashTabEntry *)
481 hash_search(CFuncHash,
486 return NULL; /* no such entry */
487 if (entry->fn_xmin == HeapTupleHeaderGetXmin(procedureTuple->t_data) &&
488 entry->fn_cmin == HeapTupleHeaderGetCmin(procedureTuple->t_data))
489 return entry; /* OK */
490 return NULL; /* entry is out of date */
494 * record_C_func: enter (or update) info about a C function in the hash table
497 record_C_func(HeapTuple procedureTuple,
498 PGFunction user_fn, Pg_finfo_record *inforec)
500 Oid fn_oid = HeapTupleGetOid(procedureTuple);
501 CFuncHashTabEntry *entry;
504 /* Create the hash table if it doesn't exist yet */
505 if (CFuncHash == NULL)
509 MemSet(&hash_ctl, 0, sizeof(hash_ctl));
510 hash_ctl.keysize = sizeof(Oid);
511 hash_ctl.entrysize = sizeof(CFuncHashTabEntry);
512 hash_ctl.hash = tag_hash;
513 CFuncHash = hash_create("CFuncHash",
516 HASH_ELEM | HASH_FUNCTION);
519 entry = (CFuncHashTabEntry *)
520 hash_search(CFuncHash,
526 (errcode(ERRCODE_OUT_OF_MEMORY),
527 errmsg("out of memory")));
528 /* OID is already filled in */
529 entry->fn_xmin = HeapTupleHeaderGetXmin(procedureTuple->t_data);
530 entry->fn_cmin = HeapTupleHeaderGetCmin(procedureTuple->t_data);
531 entry->user_fn = user_fn;
532 entry->inforec = inforec;
536 * clear_external_function_hash: remove entries for a library being closed
538 * Presently we just zap the entire hash table, but later it might be worth
539 * the effort to remove only the entries associated with the given handle.
542 clear_external_function_hash(void *filehandle)
545 hash_destroy(CFuncHash);
551 * Copy an FmgrInfo struct
553 * This is inherently somewhat bogus since we can't reliably duplicate
554 * language-dependent subsidiary info. We cheat by zeroing fn_extra,
555 * instead, meaning that subsidiary info will have to be recomputed.
558 fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
559 MemoryContext destcxt)
561 memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
562 dstinfo->fn_mcxt = destcxt;
563 if (dstinfo->fn_addr == fmgr_oldstyle)
565 /* For oldstyle functions we must copy fn_extra */
566 Oldstyle_fnextra *fnextra;
568 fnextra = (Oldstyle_fnextra *)
569 MemoryContextAlloc(destcxt, sizeof(Oldstyle_fnextra));
570 memcpy(fnextra, srcinfo->fn_extra, sizeof(Oldstyle_fnextra));
571 dstinfo->fn_extra = (void *) fnextra;
574 dstinfo->fn_extra = NULL;
579 * Specialized lookup routine for ProcedureCreate(): given the alleged name
580 * of an internal function, return the OID of the function.
581 * If the name is not recognized, return InvalidOid.
584 fmgr_internal_function(const char *proname)
586 const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
595 * Handler for old-style "C" language functions
598 fmgr_oldstyle(PG_FUNCTION_ARGS)
600 Oldstyle_fnextra *fnextra;
601 int n_arguments = fcinfo->nargs;
607 if (fcinfo->flinfo == NULL || fcinfo->flinfo->fn_extra == NULL)
608 elog(ERROR, "fmgr_oldstyle received NULL pointer");
609 fnextra = (Oldstyle_fnextra *) fcinfo->flinfo->fn_extra;
612 * Result is NULL if any argument is NULL, but we still call the
613 * function (peculiar, but that's the way it worked before, and after
614 * all this is a backwards-compatibility wrapper). Note, however,
615 * that we'll never get here with NULL arguments if the function is
618 * We also need to detoast any TOAST-ed inputs, since it's unlikely that
619 * an old-style function knows about TOASTing.
622 for (i = 0; i < n_arguments; i++)
626 else if (fnextra->arg_toastable[i])
627 fcinfo->arg[i] = PointerGetDatum(PG_DETOAST_DATUM(fcinfo->arg[i]));
629 fcinfo->isnull = isnull;
631 user_fn = fnextra->func;
636 returnValue = (*user_fn) ();
641 * nullvalue() used to use isNull to check if arg is NULL;
642 * perhaps there are other functions still out there that also
643 * rely on this undocumented hack?
645 returnValue = (*user_fn) (fcinfo->arg[0], &fcinfo->isnull);
648 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1]);
651 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
655 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
656 fcinfo->arg[2], fcinfo->arg[3]);
659 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
660 fcinfo->arg[2], fcinfo->arg[3],
664 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
665 fcinfo->arg[2], fcinfo->arg[3],
666 fcinfo->arg[4], fcinfo->arg[5]);
669 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
670 fcinfo->arg[2], fcinfo->arg[3],
671 fcinfo->arg[4], fcinfo->arg[5],
675 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
676 fcinfo->arg[2], fcinfo->arg[3],
677 fcinfo->arg[4], fcinfo->arg[5],
678 fcinfo->arg[6], fcinfo->arg[7]);
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],
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]);
695 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
696 fcinfo->arg[2], fcinfo->arg[3],
697 fcinfo->arg[4], fcinfo->arg[5],
698 fcinfo->arg[6], fcinfo->arg[7],
699 fcinfo->arg[8], fcinfo->arg[9],
703 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
704 fcinfo->arg[2], fcinfo->arg[3],
705 fcinfo->arg[4], fcinfo->arg[5],
706 fcinfo->arg[6], fcinfo->arg[7],
707 fcinfo->arg[8], fcinfo->arg[9],
708 fcinfo->arg[10], fcinfo->arg[11]);
711 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
712 fcinfo->arg[2], fcinfo->arg[3],
713 fcinfo->arg[4], fcinfo->arg[5],
714 fcinfo->arg[6], fcinfo->arg[7],
715 fcinfo->arg[8], fcinfo->arg[9],
716 fcinfo->arg[10], fcinfo->arg[11],
720 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
721 fcinfo->arg[2], fcinfo->arg[3],
722 fcinfo->arg[4], fcinfo->arg[5],
723 fcinfo->arg[6], fcinfo->arg[7],
724 fcinfo->arg[8], fcinfo->arg[9],
725 fcinfo->arg[10], fcinfo->arg[11],
726 fcinfo->arg[12], fcinfo->arg[13]);
729 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
730 fcinfo->arg[2], fcinfo->arg[3],
731 fcinfo->arg[4], fcinfo->arg[5],
732 fcinfo->arg[6], fcinfo->arg[7],
733 fcinfo->arg[8], fcinfo->arg[9],
734 fcinfo->arg[10], fcinfo->arg[11],
735 fcinfo->arg[12], fcinfo->arg[13],
739 returnValue = (*user_fn) (fcinfo->arg[0], fcinfo->arg[1],
740 fcinfo->arg[2], fcinfo->arg[3],
741 fcinfo->arg[4], fcinfo->arg[5],
742 fcinfo->arg[6], fcinfo->arg[7],
743 fcinfo->arg[8], fcinfo->arg[9],
744 fcinfo->arg[10], fcinfo->arg[11],
745 fcinfo->arg[12], fcinfo->arg[13],
746 fcinfo->arg[14], fcinfo->arg[15]);
751 * Increasing FUNC_MAX_ARGS doesn't automatically add cases to
752 * the above code, so mention the actual value in this error
753 * not FUNC_MAX_ARGS. You could add cases to the above if you
754 * needed to support old-style functions with many arguments,
755 * but making 'em be new-style is probably a better idea.
758 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
759 errmsg("function %u has too many arguments (%d, maximum is %d)",
760 fcinfo->flinfo->fn_oid, n_arguments, 16)));
761 returnValue = NULL; /* keep compiler quiet */
765 return (Datum) returnValue;
770 * Support for security definer functions
773 struct fmgr_security_definer_cache
780 * Function handler for security definer functions. We extract the
781 * OID of the actual function and do a fmgr lookup again. Then we
782 * look up the owner of the function and cache both the fmgr info and
783 * the owner ID. During the call we temporarily replace the flinfo
784 * with the cached/looked-up one, while keeping the outer fcinfo
785 * (which contains all the actual arguments, etc.) intact.
788 fmgr_security_definer(PG_FUNCTION_ARGS)
791 FmgrInfo *save_flinfo;
792 struct fmgr_security_definer_cache * volatile fcache;
796 if (!fcinfo->flinfo->fn_extra)
798 fcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*fcache));
799 memset(fcache, 0, sizeof(*fcache));
801 fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
802 fcinfo->flinfo->fn_mcxt, true);
804 tuple = SearchSysCache(PROCOID,
805 ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
807 if (!HeapTupleIsValid(tuple))
808 elog(ERROR, "cache lookup failed for function %u",
809 fcinfo->flinfo->fn_oid);
810 fcache->userid = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
811 ReleaseSysCache(tuple);
813 fcinfo->flinfo->fn_extra = fcache;
816 fcache = fcinfo->flinfo->fn_extra;
818 save_flinfo = fcinfo->flinfo;
819 save_userid = GetUserId();
823 fcinfo->flinfo = &fcache->flinfo;
824 SetUserId(fcache->userid);
826 result = FunctionCallInvoke(fcinfo);
830 fcinfo->flinfo = save_flinfo;
831 SetUserId(save_userid);
836 fcinfo->flinfo = save_flinfo;
837 SetUserId(save_userid);
843 /*-------------------------------------------------------------------------
844 * Support routines for callers of fmgr-compatible functions
846 * NOTE: the simplest way to reliably initialize a FunctionCallInfoData
847 * is to MemSet it to zeroes and then fill in the fields that should be
848 * nonzero. However, in a few of the most heavily used paths, we instead
849 * just zero the fields that must be zero. This saves a fair number of
850 * cycles so it's worth the extra maintenance effort. Also see inlined
851 * version of FunctionCall2 in utils/sort/tuplesort.c if you need to change
853 *-------------------------------------------------------------------------
856 /* These are for invocation of a specifically named function with a
857 * directly-computed parameter list. Note that neither arguments nor result
858 * are allowed to be NULL. Also, the function cannot be one that needs to
859 * look at FmgrInfo, since there won't be any.
862 DirectFunctionCall1(PGFunction func, Datum arg1)
864 FunctionCallInfoData fcinfo;
867 /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */
868 fcinfo.flinfo = NULL;
869 fcinfo.context = NULL;
870 fcinfo.resultinfo = NULL;
871 fcinfo.isnull = false;
874 fcinfo.arg[0] = arg1;
875 fcinfo.argnull[0] = false;
877 result = (*func) (&fcinfo);
879 /* Check for null result, since caller is clearly not expecting one */
881 elog(ERROR, "function %p returned NULL", (void *) func);
887 DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2)
889 FunctionCallInfoData fcinfo;
892 /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */
893 fcinfo.flinfo = NULL;
894 fcinfo.context = NULL;
895 fcinfo.resultinfo = NULL;
896 fcinfo.isnull = false;
899 fcinfo.arg[0] = arg1;
900 fcinfo.arg[1] = arg2;
901 fcinfo.argnull[0] = false;
902 fcinfo.argnull[1] = false;
904 result = (*func) (&fcinfo);
906 /* Check for null result, since caller is clearly not expecting one */
908 elog(ERROR, "function %p returned NULL", (void *) func);
914 DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
917 FunctionCallInfoData fcinfo;
920 MemSet(&fcinfo, 0, sizeof(fcinfo));
922 fcinfo.arg[0] = arg1;
923 fcinfo.arg[1] = arg2;
924 fcinfo.arg[2] = arg3;
926 result = (*func) (&fcinfo);
928 /* Check for null result, since caller is clearly not expecting one */
930 elog(ERROR, "function %p returned NULL", (void *) func);
936 DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
937 Datum arg3, Datum arg4)
939 FunctionCallInfoData fcinfo;
942 MemSet(&fcinfo, 0, sizeof(fcinfo));
944 fcinfo.arg[0] = arg1;
945 fcinfo.arg[1] = arg2;
946 fcinfo.arg[2] = arg3;
947 fcinfo.arg[3] = arg4;
949 result = (*func) (&fcinfo);
951 /* Check for null result, since caller is clearly not expecting one */
953 elog(ERROR, "function %p returned NULL", (void *) func);
959 DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
960 Datum arg3, Datum arg4, Datum arg5)
962 FunctionCallInfoData fcinfo;
965 MemSet(&fcinfo, 0, sizeof(fcinfo));
967 fcinfo.arg[0] = arg1;
968 fcinfo.arg[1] = arg2;
969 fcinfo.arg[2] = arg3;
970 fcinfo.arg[3] = arg4;
971 fcinfo.arg[4] = arg5;
973 result = (*func) (&fcinfo);
975 /* Check for null result, since caller is clearly not expecting one */
977 elog(ERROR, "function %p returned NULL", (void *) func);
983 DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
984 Datum arg3, Datum arg4, Datum arg5,
987 FunctionCallInfoData fcinfo;
990 MemSet(&fcinfo, 0, sizeof(fcinfo));
992 fcinfo.arg[0] = arg1;
993 fcinfo.arg[1] = arg2;
994 fcinfo.arg[2] = arg3;
995 fcinfo.arg[3] = arg4;
996 fcinfo.arg[4] = arg5;
997 fcinfo.arg[5] = arg6;
999 result = (*func) (&fcinfo);
1001 /* Check for null result, since caller is clearly not expecting one */
1003 elog(ERROR, "function %p returned NULL", (void *) func);
1009 DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
1010 Datum arg3, Datum arg4, Datum arg5,
1011 Datum arg6, Datum arg7)
1013 FunctionCallInfoData fcinfo;
1016 MemSet(&fcinfo, 0, sizeof(fcinfo));
1018 fcinfo.arg[0] = arg1;
1019 fcinfo.arg[1] = arg2;
1020 fcinfo.arg[2] = arg3;
1021 fcinfo.arg[3] = arg4;
1022 fcinfo.arg[4] = arg5;
1023 fcinfo.arg[5] = arg6;
1024 fcinfo.arg[6] = arg7;
1026 result = (*func) (&fcinfo);
1028 /* Check for null result, since caller is clearly not expecting one */
1030 elog(ERROR, "function %p returned NULL", (void *) func);
1036 DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
1037 Datum arg3, Datum arg4, Datum arg5,
1038 Datum arg6, Datum arg7, Datum arg8)
1040 FunctionCallInfoData fcinfo;
1043 MemSet(&fcinfo, 0, sizeof(fcinfo));
1045 fcinfo.arg[0] = arg1;
1046 fcinfo.arg[1] = arg2;
1047 fcinfo.arg[2] = arg3;
1048 fcinfo.arg[3] = arg4;
1049 fcinfo.arg[4] = arg5;
1050 fcinfo.arg[5] = arg6;
1051 fcinfo.arg[6] = arg7;
1052 fcinfo.arg[7] = arg8;
1054 result = (*func) (&fcinfo);
1056 /* Check for null result, since caller is clearly not expecting one */
1058 elog(ERROR, "function %p returned NULL", (void *) func);
1064 DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
1065 Datum arg3, Datum arg4, Datum arg5,
1066 Datum arg6, Datum arg7, Datum arg8,
1069 FunctionCallInfoData fcinfo;
1072 MemSet(&fcinfo, 0, sizeof(fcinfo));
1074 fcinfo.arg[0] = arg1;
1075 fcinfo.arg[1] = arg2;
1076 fcinfo.arg[2] = arg3;
1077 fcinfo.arg[3] = arg4;
1078 fcinfo.arg[4] = arg5;
1079 fcinfo.arg[5] = arg6;
1080 fcinfo.arg[6] = arg7;
1081 fcinfo.arg[7] = arg8;
1082 fcinfo.arg[8] = arg9;
1084 result = (*func) (&fcinfo);
1086 /* Check for null result, since caller is clearly not expecting one */
1088 elog(ERROR, "function %p returned NULL", (void *) func);
1094 /* These are for invocation of a previously-looked-up function with a
1095 * directly-computed parameter list. Note that neither arguments nor result
1096 * are allowed to be NULL.
1099 FunctionCall1(FmgrInfo *flinfo, Datum arg1)
1101 FunctionCallInfoData fcinfo;
1104 /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */
1105 fcinfo.context = NULL;
1106 fcinfo.resultinfo = NULL;
1107 fcinfo.isnull = false;
1109 fcinfo.flinfo = flinfo;
1111 fcinfo.arg[0] = arg1;
1112 fcinfo.argnull[0] = false;
1114 result = FunctionCallInvoke(&fcinfo);
1116 /* Check for null result, since caller is clearly not expecting one */
1118 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1124 FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
1126 FunctionCallInfoData fcinfo;
1129 /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */
1130 fcinfo.context = NULL;
1131 fcinfo.resultinfo = NULL;
1132 fcinfo.isnull = false;
1134 fcinfo.flinfo = flinfo;
1136 fcinfo.arg[0] = arg1;
1137 fcinfo.arg[1] = arg2;
1138 fcinfo.argnull[0] = false;
1139 fcinfo.argnull[1] = false;
1141 result = FunctionCallInvoke(&fcinfo);
1143 /* Check for null result, since caller is clearly not expecting one */
1145 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1151 FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1154 FunctionCallInfoData fcinfo;
1157 MemSet(&fcinfo, 0, sizeof(fcinfo));
1158 fcinfo.flinfo = flinfo;
1160 fcinfo.arg[0] = arg1;
1161 fcinfo.arg[1] = arg2;
1162 fcinfo.arg[2] = arg3;
1164 result = FunctionCallInvoke(&fcinfo);
1166 /* Check for null result, since caller is clearly not expecting one */
1168 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1174 FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1175 Datum arg3, Datum arg4)
1177 FunctionCallInfoData fcinfo;
1180 MemSet(&fcinfo, 0, sizeof(fcinfo));
1181 fcinfo.flinfo = flinfo;
1183 fcinfo.arg[0] = arg1;
1184 fcinfo.arg[1] = arg2;
1185 fcinfo.arg[2] = arg3;
1186 fcinfo.arg[3] = arg4;
1188 result = FunctionCallInvoke(&fcinfo);
1190 /* Check for null result, since caller is clearly not expecting one */
1192 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1198 FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1199 Datum arg3, Datum arg4, Datum arg5)
1201 FunctionCallInfoData fcinfo;
1204 MemSet(&fcinfo, 0, sizeof(fcinfo));
1205 fcinfo.flinfo = flinfo;
1207 fcinfo.arg[0] = arg1;
1208 fcinfo.arg[1] = arg2;
1209 fcinfo.arg[2] = arg3;
1210 fcinfo.arg[3] = arg4;
1211 fcinfo.arg[4] = arg5;
1213 result = FunctionCallInvoke(&fcinfo);
1215 /* Check for null result, since caller is clearly not expecting one */
1217 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1223 FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1224 Datum arg3, Datum arg4, Datum arg5,
1227 FunctionCallInfoData fcinfo;
1230 MemSet(&fcinfo, 0, sizeof(fcinfo));
1231 fcinfo.flinfo = flinfo;
1233 fcinfo.arg[0] = arg1;
1234 fcinfo.arg[1] = arg2;
1235 fcinfo.arg[2] = arg3;
1236 fcinfo.arg[3] = arg4;
1237 fcinfo.arg[4] = arg5;
1238 fcinfo.arg[5] = arg6;
1240 result = FunctionCallInvoke(&fcinfo);
1242 /* Check for null result, since caller is clearly not expecting one */
1244 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1250 FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1251 Datum arg3, Datum arg4, Datum arg5,
1252 Datum arg6, Datum arg7)
1254 FunctionCallInfoData fcinfo;
1257 MemSet(&fcinfo, 0, sizeof(fcinfo));
1258 fcinfo.flinfo = flinfo;
1260 fcinfo.arg[0] = arg1;
1261 fcinfo.arg[1] = arg2;
1262 fcinfo.arg[2] = arg3;
1263 fcinfo.arg[3] = arg4;
1264 fcinfo.arg[4] = arg5;
1265 fcinfo.arg[5] = arg6;
1266 fcinfo.arg[6] = arg7;
1268 result = FunctionCallInvoke(&fcinfo);
1270 /* Check for null result, since caller is clearly not expecting one */
1272 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1278 FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1279 Datum arg3, Datum arg4, Datum arg5,
1280 Datum arg6, Datum arg7, Datum arg8)
1282 FunctionCallInfoData fcinfo;
1285 MemSet(&fcinfo, 0, sizeof(fcinfo));
1286 fcinfo.flinfo = flinfo;
1288 fcinfo.arg[0] = arg1;
1289 fcinfo.arg[1] = arg2;
1290 fcinfo.arg[2] = arg3;
1291 fcinfo.arg[3] = arg4;
1292 fcinfo.arg[4] = arg5;
1293 fcinfo.arg[5] = arg6;
1294 fcinfo.arg[6] = arg7;
1295 fcinfo.arg[7] = arg8;
1297 result = FunctionCallInvoke(&fcinfo);
1299 /* Check for null result, since caller is clearly not expecting one */
1301 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1307 FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
1308 Datum arg3, Datum arg4, Datum arg5,
1309 Datum arg6, Datum arg7, Datum arg8,
1312 FunctionCallInfoData fcinfo;
1315 MemSet(&fcinfo, 0, sizeof(fcinfo));
1316 fcinfo.flinfo = flinfo;
1318 fcinfo.arg[0] = arg1;
1319 fcinfo.arg[1] = arg2;
1320 fcinfo.arg[2] = arg3;
1321 fcinfo.arg[3] = arg4;
1322 fcinfo.arg[4] = arg5;
1323 fcinfo.arg[5] = arg6;
1324 fcinfo.arg[6] = arg7;
1325 fcinfo.arg[7] = arg8;
1326 fcinfo.arg[8] = arg9;
1328 result = FunctionCallInvoke(&fcinfo);
1330 /* Check for null result, since caller is clearly not expecting one */
1332 elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid);
1338 /* These are for invocation of a function identified by OID with a
1339 * directly-computed parameter list. Note that neither arguments nor result
1340 * are allowed to be NULL. These are essentially fmgr_info() followed
1341 * by FunctionCallN(). If the same function is to be invoked repeatedly,
1342 * do the fmgr_info() once and then use FunctionCallN().
1345 OidFunctionCall1(Oid functionId, Datum arg1)
1348 FunctionCallInfoData fcinfo;
1351 fmgr_info(functionId, &flinfo);
1353 MemSet(&fcinfo, 0, sizeof(fcinfo));
1354 fcinfo.flinfo = &flinfo;
1356 fcinfo.arg[0] = arg1;
1358 result = FunctionCallInvoke(&fcinfo);
1360 /* Check for null result, since caller is clearly not expecting one */
1362 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1368 OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2)
1371 FunctionCallInfoData fcinfo;
1374 fmgr_info(functionId, &flinfo);
1376 MemSet(&fcinfo, 0, sizeof(fcinfo));
1377 fcinfo.flinfo = &flinfo;
1379 fcinfo.arg[0] = arg1;
1380 fcinfo.arg[1] = arg2;
1382 result = FunctionCallInvoke(&fcinfo);
1384 /* Check for null result, since caller is clearly not expecting one */
1386 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1392 OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
1396 FunctionCallInfoData fcinfo;
1399 fmgr_info(functionId, &flinfo);
1401 MemSet(&fcinfo, 0, sizeof(fcinfo));
1402 fcinfo.flinfo = &flinfo;
1404 fcinfo.arg[0] = arg1;
1405 fcinfo.arg[1] = arg2;
1406 fcinfo.arg[2] = arg3;
1408 result = FunctionCallInvoke(&fcinfo);
1410 /* Check for null result, since caller is clearly not expecting one */
1412 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1418 OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
1419 Datum arg3, Datum arg4)
1422 FunctionCallInfoData fcinfo;
1425 fmgr_info(functionId, &flinfo);
1427 MemSet(&fcinfo, 0, sizeof(fcinfo));
1428 fcinfo.flinfo = &flinfo;
1430 fcinfo.arg[0] = arg1;
1431 fcinfo.arg[1] = arg2;
1432 fcinfo.arg[2] = arg3;
1433 fcinfo.arg[3] = arg4;
1435 result = FunctionCallInvoke(&fcinfo);
1437 /* Check for null result, since caller is clearly not expecting one */
1439 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1445 OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
1446 Datum arg3, Datum arg4, Datum arg5)
1449 FunctionCallInfoData fcinfo;
1452 fmgr_info(functionId, &flinfo);
1454 MemSet(&fcinfo, 0, sizeof(fcinfo));
1455 fcinfo.flinfo = &flinfo;
1457 fcinfo.arg[0] = arg1;
1458 fcinfo.arg[1] = arg2;
1459 fcinfo.arg[2] = arg3;
1460 fcinfo.arg[3] = arg4;
1461 fcinfo.arg[4] = arg5;
1463 result = FunctionCallInvoke(&fcinfo);
1465 /* Check for null result, since caller is clearly not expecting one */
1467 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1473 OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
1474 Datum arg3, Datum arg4, Datum arg5,
1478 FunctionCallInfoData fcinfo;
1481 fmgr_info(functionId, &flinfo);
1483 MemSet(&fcinfo, 0, sizeof(fcinfo));
1484 fcinfo.flinfo = &flinfo;
1486 fcinfo.arg[0] = arg1;
1487 fcinfo.arg[1] = arg2;
1488 fcinfo.arg[2] = arg3;
1489 fcinfo.arg[3] = arg4;
1490 fcinfo.arg[4] = arg5;
1491 fcinfo.arg[5] = arg6;
1493 result = FunctionCallInvoke(&fcinfo);
1495 /* Check for null result, since caller is clearly not expecting one */
1497 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1503 OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
1504 Datum arg3, Datum arg4, Datum arg5,
1505 Datum arg6, Datum arg7)
1508 FunctionCallInfoData fcinfo;
1511 fmgr_info(functionId, &flinfo);
1513 MemSet(&fcinfo, 0, sizeof(fcinfo));
1514 fcinfo.flinfo = &flinfo;
1516 fcinfo.arg[0] = arg1;
1517 fcinfo.arg[1] = arg2;
1518 fcinfo.arg[2] = arg3;
1519 fcinfo.arg[3] = arg4;
1520 fcinfo.arg[4] = arg5;
1521 fcinfo.arg[5] = arg6;
1522 fcinfo.arg[6] = arg7;
1524 result = FunctionCallInvoke(&fcinfo);
1526 /* Check for null result, since caller is clearly not expecting one */
1528 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1534 OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
1535 Datum arg3, Datum arg4, Datum arg5,
1536 Datum arg6, Datum arg7, Datum arg8)
1539 FunctionCallInfoData fcinfo;
1542 fmgr_info(functionId, &flinfo);
1544 MemSet(&fcinfo, 0, sizeof(fcinfo));
1545 fcinfo.flinfo = &flinfo;
1547 fcinfo.arg[0] = arg1;
1548 fcinfo.arg[1] = arg2;
1549 fcinfo.arg[2] = arg3;
1550 fcinfo.arg[3] = arg4;
1551 fcinfo.arg[4] = arg5;
1552 fcinfo.arg[5] = arg6;
1553 fcinfo.arg[6] = arg7;
1554 fcinfo.arg[7] = arg8;
1556 result = FunctionCallInvoke(&fcinfo);
1558 /* Check for null result, since caller is clearly not expecting one */
1560 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1566 OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
1567 Datum arg3, Datum arg4, Datum arg5,
1568 Datum arg6, Datum arg7, Datum arg8,
1572 FunctionCallInfoData fcinfo;
1575 fmgr_info(functionId, &flinfo);
1577 MemSet(&fcinfo, 0, sizeof(fcinfo));
1578 fcinfo.flinfo = &flinfo;
1580 fcinfo.arg[0] = arg1;
1581 fcinfo.arg[1] = arg2;
1582 fcinfo.arg[2] = arg3;
1583 fcinfo.arg[3] = arg4;
1584 fcinfo.arg[4] = arg5;
1585 fcinfo.arg[5] = arg6;
1586 fcinfo.arg[6] = arg7;
1587 fcinfo.arg[7] = arg8;
1588 fcinfo.arg[8] = arg9;
1590 result = FunctionCallInvoke(&fcinfo);
1592 /* Check for null result, since caller is clearly not expecting one */
1594 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1601 * !!! OLD INTERFACE !!!
1603 * fmgr() is the only remaining vestige of the old-style caller support
1604 * functions. It's no longer used anywhere in the Postgres distribution,
1605 * but we should leave it around for a release or two to ease the transition
1606 * for user-supplied C functions. OidFunctionCallN() replaces it for new
1609 * DEPRECATED, DO NOT USE IN NEW CODE
1612 fmgr(Oid procedureId,...)
1615 FunctionCallInfoData fcinfo;
1619 fmgr_info(procedureId, &flinfo);
1621 MemSet(&fcinfo, 0, sizeof(fcinfo));
1622 fcinfo.flinfo = &flinfo;
1623 fcinfo.nargs = flinfo.fn_nargs;
1624 n_arguments = fcinfo.nargs;
1626 if (n_arguments > 0)
1631 if (n_arguments > FUNC_MAX_ARGS)
1633 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1634 errmsg("function %u has too many arguments (%d, maximum is %d)",
1635 flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS)));
1636 va_start(pvar, procedureId);
1637 for (i = 0; i < n_arguments; i++)
1638 fcinfo.arg[i] = (Datum) va_arg(pvar, char *);
1642 result = FunctionCallInvoke(&fcinfo);
1644 /* Check for null result, since caller is clearly not expecting one */
1646 elog(ERROR, "function %u returned NULL", flinfo.fn_oid);
1648 return (char *) result;
1652 /*-------------------------------------------------------------------------
1653 * Support routines for standard pass-by-reference datatypes
1655 * Note: at some point, at least on some platforms, these might become
1656 * pass-by-value types. Obviously Datum must be >= 8 bytes to allow
1657 * int64 or float8 to be pass-by-value. I think that Float4GetDatum
1658 * and Float8GetDatum will need to be out-of-line routines anyway,
1659 * since just casting from float to Datum will not do the right thing;
1660 * some kind of trick with pointer-casting or a union will be needed.
1661 *-------------------------------------------------------------------------
1665 Int64GetDatum(int64 X)
1667 #ifndef INT64_IS_BUSTED
1668 int64 *retval = (int64 *) palloc(sizeof(int64));
1671 return PointerGetDatum(retval);
1672 #else /* INT64_IS_BUSTED */
1675 * On a machine with no 64-bit-int C datatype, sizeof(int64) will not
1676 * be 8, but we want Int64GetDatum to return an 8-byte object anyway,
1677 * with zeroes in the unused bits. This is needed so that, for
1678 * example, hash join of int8 will behave properly.
1680 int64 *retval = (int64 *) palloc0(Max(sizeof(int64), 8));
1683 return PointerGetDatum(retval);
1684 #endif /* INT64_IS_BUSTED */
1688 Float4GetDatum(float4 X)
1690 float4 *retval = (float4 *) palloc(sizeof(float4));
1693 return PointerGetDatum(retval);
1697 Float8GetDatum(float8 X)
1699 float8 *retval = (float8 *) palloc(sizeof(float8));
1702 return PointerGetDatum(retval);
1705 /*-------------------------------------------------------------------------
1706 * Support routines for toastable datatypes
1707 *-------------------------------------------------------------------------
1711 pg_detoast_datum(struct varlena * datum)
1713 if (VARATT_IS_EXTENDED(datum))
1714 return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);
1720 pg_detoast_datum_copy(struct varlena * datum)
1722 if (VARATT_IS_EXTENDED(datum))
1723 return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);
1726 /* Make a modifiable copy of the varlena object */
1727 Size len = VARSIZE(datum);
1728 struct varlena *result = (struct varlena *) palloc(len);
1730 memcpy(result, datum, len);
1736 pg_detoast_datum_slice(struct varlena * datum, int32 first, int32 count)
1738 /* Only get the specified portion from the toast rel */
1739 return (struct varlena *) heap_tuple_untoast_attr_slice((varattrib *) datum, first, count);
1742 /*-------------------------------------------------------------------------
1743 * Support routines for extracting info from fn_expr parse tree
1745 * These are needed by polymorphic functions, which accept multiple possible
1746 * input types and need help from the parser to know what they've got.
1747 *-------------------------------------------------------------------------
1751 * Get the actual type OID of the function return type
1753 * Returns InvalidOid if information is not available
1756 get_fn_expr_rettype(FmgrInfo *flinfo)
1761 * can't return anything useful if we have no FmgrInfo or if its
1762 * fn_expr node has not been initialized
1764 if (!flinfo || !flinfo->fn_expr)
1767 expr = flinfo->fn_expr;
1769 return exprType(expr);
1773 * Get the actual type OID of a specific function argument (counting from 0)
1775 * Returns InvalidOid if information is not available
1778 get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
1785 * can't return anything useful if we have no FmgrInfo or if its
1786 * fn_expr node has not been initialized
1788 if (!flinfo || !flinfo->fn_expr)
1791 expr = flinfo->fn_expr;
1793 if (IsA(expr, FuncExpr))
1794 args = ((FuncExpr *) expr)->args;
1795 else if (IsA(expr, OpExpr))
1796 args = ((OpExpr *) expr)->args;
1797 else if (IsA(expr, DistinctExpr))
1798 args = ((DistinctExpr *) expr)->args;
1799 else if (IsA(expr, ScalarArrayOpExpr))
1800 args = ((ScalarArrayOpExpr *) expr)->args;
1801 else if (IsA(expr, NullIfExpr))
1802 args = ((NullIfExpr *) expr)->args;
1806 if (argnum < 0 || argnum >= list_length(args))
1809 argtype = exprType((Node *) list_nth(args, argnum));
1812 * special hack for ScalarArrayOpExpr: what the underlying function
1813 * will actually get passed is the element type of the array.
1815 if (IsA(expr, ScalarArrayOpExpr) &&
1817 argtype = get_element_type(argtype);