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