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-2019, 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 > fmgr_last_builtin_oid)
79  return NULL;
80 
81  /*
82  * Lookup function data. If there's a miss in that range it's likely a
83  * nonexistent 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 = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
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 = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
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
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  LOCAL_FCINFO(fcinfo, 1);
796  Datum result;
797 
798  InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL);
799 
800  fcinfo->args[0].value = arg1;
801  fcinfo->args[0].isnull = 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  LOCAL_FCINFO(fcinfo, 2);
816  Datum result;
817 
818  InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL);
819 
820  fcinfo->args[0].value = arg1;
821  fcinfo->args[0].isnull = false;
822  fcinfo->args[1].value = arg2;
823  fcinfo->args[1].isnull = 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  LOCAL_FCINFO(fcinfo, 3);
839  Datum result;
840 
841  InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL);
842 
843  fcinfo->args[0].value = arg1;
844  fcinfo->args[0].isnull = false;
845  fcinfo->args[1].value = arg2;
846  fcinfo->args[1].isnull = false;
847  fcinfo->args[2].value = arg3;
848  fcinfo->args[2].isnull = 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  LOCAL_FCINFO(fcinfo, 4);
864  Datum result;
865 
866  InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL);
867 
868  fcinfo->args[0].value = arg1;
869  fcinfo->args[0].isnull = false;
870  fcinfo->args[1].value = arg2;
871  fcinfo->args[1].isnull = false;
872  fcinfo->args[2].value = arg3;
873  fcinfo->args[2].isnull = false;
874  fcinfo->args[3].value = arg4;
875  fcinfo->args[3].isnull = 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  LOCAL_FCINFO(fcinfo, 5);
891  Datum result;
892 
893  InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL);
894 
895  fcinfo->args[0].value = arg1;
896  fcinfo->args[0].isnull = false;
897  fcinfo->args[1].value = arg2;
898  fcinfo->args[1].isnull = false;
899  fcinfo->args[2].value = arg3;
900  fcinfo->args[2].isnull = false;
901  fcinfo->args[3].value = arg4;
902  fcinfo->args[3].isnull = false;
903  fcinfo->args[4].value = arg5;
904  fcinfo->args[4].isnull = 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  LOCAL_FCINFO(fcinfo, 6);
921  Datum result;
922 
923  InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL);
924 
925  fcinfo->args[0].value = arg1;
926  fcinfo->args[0].isnull = false;
927  fcinfo->args[1].value = arg2;
928  fcinfo->args[1].isnull = false;
929  fcinfo->args[2].value = arg3;
930  fcinfo->args[2].isnull = false;
931  fcinfo->args[3].value = arg4;
932  fcinfo->args[3].isnull = false;
933  fcinfo->args[4].value = arg5;
934  fcinfo->args[4].isnull = false;
935  fcinfo->args[5].value = arg6;
936  fcinfo->args[5].isnull = 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  LOCAL_FCINFO(fcinfo, 7);
953  Datum result;
954 
955  InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL);
956 
957  fcinfo->args[0].value = arg1;
958  fcinfo->args[0].isnull = false;
959  fcinfo->args[1].value = arg2;
960  fcinfo->args[1].isnull = false;
961  fcinfo->args[2].value = arg3;
962  fcinfo->args[2].isnull = false;
963  fcinfo->args[3].value = arg4;
964  fcinfo->args[3].isnull = false;
965  fcinfo->args[4].value = arg5;
966  fcinfo->args[4].isnull = false;
967  fcinfo->args[5].value = arg6;
968  fcinfo->args[5].isnull = false;
969  fcinfo->args[6].value = arg7;
970  fcinfo->args[6].isnull = 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  LOCAL_FCINFO(fcinfo, 8);
987  Datum result;
988 
989  InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL);
990 
991  fcinfo->args[0].value = arg1;
992  fcinfo->args[0].isnull = false;
993  fcinfo->args[1].value = arg2;
994  fcinfo->args[1].isnull = false;
995  fcinfo->args[2].value = arg3;
996  fcinfo->args[2].isnull = false;
997  fcinfo->args[3].value = arg4;
998  fcinfo->args[3].isnull = false;
999  fcinfo->args[4].value = arg5;
1000  fcinfo->args[4].isnull = false;
1001  fcinfo->args[5].value = arg6;
1002  fcinfo->args[5].isnull = false;
1003  fcinfo->args[6].value = arg7;
1004  fcinfo->args[6].isnull = false;
1005  fcinfo->args[7].value = arg8;
1006  fcinfo->args[7].isnull = 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  LOCAL_FCINFO(fcinfo, 9);
1024  Datum result;
1025 
1026  InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL);
1027 
1028  fcinfo->args[0].value = arg1;
1029  fcinfo->args[0].isnull = false;
1030  fcinfo->args[1].value = arg2;
1031  fcinfo->args[1].isnull = false;
1032  fcinfo->args[2].value = arg3;
1033  fcinfo->args[2].isnull = false;
1034  fcinfo->args[3].value = arg4;
1035  fcinfo->args[3].isnull = false;
1036  fcinfo->args[4].value = arg5;
1037  fcinfo->args[4].isnull = false;
1038  fcinfo->args[5].value = arg6;
1039  fcinfo->args[5].isnull = false;
1040  fcinfo->args[6].value = arg7;
1041  fcinfo->args[6].isnull = false;
1042  fcinfo->args[7].value = arg8;
1043  fcinfo->args[7].isnull = false;
1044  fcinfo->args[8].value = arg9;
1045  fcinfo->args[8].isnull = 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  LOCAL_FCINFO(fcinfo, 1);
1069  Datum result;
1070 
1071  InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
1072 
1073  fcinfo->args[0].value = arg1;
1074  fcinfo->args[0].isnull = 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  LOCAL_FCINFO(fcinfo, 2);
1089  Datum result;
1090 
1091  InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
1092 
1093  fcinfo->args[0].value = arg1;
1094  fcinfo->args[0].isnull = false;
1095  fcinfo->args[1].value = arg2;
1096  fcinfo->args[1].isnull = 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  LOCAL_FCINFO(fcinfo, 0);
1116  Datum result;
1117 
1118  InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL);
1119 
1120  result = FunctionCallInvoke(fcinfo);
1121 
1122  /* Check for null result, since caller is clearly not expecting one */
1123  if (fcinfo->isnull)
1124  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1125 
1126  return result;
1127 }
1128 
1129 Datum
1131 {
1132  LOCAL_FCINFO(fcinfo, 1);
1133  Datum result;
1134 
1135  InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL);
1136 
1137  fcinfo->args[0].value = arg1;
1138  fcinfo->args[0].isnull = false;
1139 
1140  result = FunctionCallInvoke(fcinfo);
1141 
1142  /* Check for null result, since caller is clearly not expecting one */
1143  if (fcinfo->isnull)
1144  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1145 
1146  return result;
1147 }
1148 
1149 Datum
1151 {
1152  LOCAL_FCINFO(fcinfo, 2);
1153  Datum result;
1154 
1155  InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL);
1156 
1157  fcinfo->args[0].value = arg1;
1158  fcinfo->args[0].isnull = false;
1159  fcinfo->args[1].value = arg2;
1160  fcinfo->args[1].isnull = false;
1161 
1162  result = FunctionCallInvoke(fcinfo);
1163 
1164  /* Check for null result, since caller is clearly not expecting one */
1165  if (fcinfo->isnull)
1166  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1167 
1168  return result;
1169 }
1170 
1171 Datum
1173  Datum arg3)
1174 {
1175  LOCAL_FCINFO(fcinfo, 3);
1176  Datum result;
1177 
1178  InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
1179 
1180  fcinfo->args[0].value = arg1;
1181  fcinfo->args[0].isnull = false;
1182  fcinfo->args[1].value = arg2;
1183  fcinfo->args[1].isnull = false;
1184  fcinfo->args[2].value = arg3;
1185  fcinfo->args[2].isnull = false;
1186 
1187  result = FunctionCallInvoke(fcinfo);
1188 
1189  /* Check for null result, since caller is clearly not expecting one */
1190  if (fcinfo->isnull)
1191  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1192 
1193  return result;
1194 }
1195 
1196 Datum
1198  Datum arg3, Datum arg4)
1199 {
1200  LOCAL_FCINFO(fcinfo, 4);
1201  Datum result;
1202 
1203  InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL);
1204 
1205  fcinfo->args[0].value = arg1;
1206  fcinfo->args[0].isnull = false;
1207  fcinfo->args[1].value = arg2;
1208  fcinfo->args[1].isnull = false;
1209  fcinfo->args[2].value = arg3;
1210  fcinfo->args[2].isnull = false;
1211  fcinfo->args[3].value = arg4;
1212  fcinfo->args[3].isnull = false;
1213 
1214  result = FunctionCallInvoke(fcinfo);
1215 
1216  /* Check for null result, since caller is clearly not expecting one */
1217  if (fcinfo->isnull)
1218  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1219 
1220  return result;
1221 }
1222 
1223 Datum
1225  Datum arg3, Datum arg4, Datum arg5)
1226 {
1227  LOCAL_FCINFO(fcinfo, 5);
1228  Datum result;
1229 
1230  InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL);
1231 
1232  fcinfo->args[0].value = arg1;
1233  fcinfo->args[0].isnull = false;
1234  fcinfo->args[1].value = arg2;
1235  fcinfo->args[1].isnull = false;
1236  fcinfo->args[2].value = arg3;
1237  fcinfo->args[2].isnull = false;
1238  fcinfo->args[3].value = arg4;
1239  fcinfo->args[3].isnull = false;
1240  fcinfo->args[4].value = arg5;
1241  fcinfo->args[4].isnull = false;
1242 
1243  result = FunctionCallInvoke(fcinfo);
1244 
1245  /* Check for null result, since caller is clearly not expecting one */
1246  if (fcinfo->isnull)
1247  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1248 
1249  return result;
1250 }
1251 
1252 Datum
1254  Datum arg3, Datum arg4, Datum arg5,
1255  Datum arg6)
1256 {
1257  LOCAL_FCINFO(fcinfo, 6);
1258  Datum result;
1259 
1260  InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL);
1261 
1262  fcinfo->args[0].value = arg1;
1263  fcinfo->args[0].isnull = false;
1264  fcinfo->args[1].value = arg2;
1265  fcinfo->args[1].isnull = false;
1266  fcinfo->args[2].value = arg3;
1267  fcinfo->args[2].isnull = false;
1268  fcinfo->args[3].value = arg4;
1269  fcinfo->args[3].isnull = false;
1270  fcinfo->args[4].value = arg5;
1271  fcinfo->args[4].isnull = false;
1272  fcinfo->args[5].value = arg6;
1273  fcinfo->args[5].isnull = false;
1274 
1275  result = FunctionCallInvoke(fcinfo);
1276 
1277  /* Check for null result, since caller is clearly not expecting one */
1278  if (fcinfo->isnull)
1279  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1280 
1281  return result;
1282 }
1283 
1284 Datum
1286  Datum arg3, Datum arg4, Datum arg5,
1287  Datum arg6, Datum arg7)
1288 {
1289  LOCAL_FCINFO(fcinfo, 7);
1290  Datum result;
1291 
1292  InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL);
1293 
1294  fcinfo->args[0].value = arg1;
1295  fcinfo->args[0].isnull = false;
1296  fcinfo->args[1].value = arg2;
1297  fcinfo->args[1].isnull = false;
1298  fcinfo->args[2].value = arg3;
1299  fcinfo->args[2].isnull = false;
1300  fcinfo->args[3].value = arg4;
1301  fcinfo->args[3].isnull = false;
1302  fcinfo->args[4].value = arg5;
1303  fcinfo->args[4].isnull = false;
1304  fcinfo->args[5].value = arg6;
1305  fcinfo->args[5].isnull = false;
1306  fcinfo->args[6].value = arg7;
1307  fcinfo->args[6].isnull = false;
1308 
1309  result = FunctionCallInvoke(fcinfo);
1310 
1311  /* Check for null result, since caller is clearly not expecting one */
1312  if (fcinfo->isnull)
1313  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1314 
1315  return result;
1316 }
1317 
1318 Datum
1320  Datum arg3, Datum arg4, Datum arg5,
1321  Datum arg6, Datum arg7, Datum arg8)
1322 {
1323  LOCAL_FCINFO(fcinfo, 8);
1324  Datum result;
1325 
1326  InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL);
1327 
1328  fcinfo->args[0].value = arg1;
1329  fcinfo->args[0].isnull = false;
1330  fcinfo->args[1].value = arg2;
1331  fcinfo->args[1].isnull = false;
1332  fcinfo->args[2].value = arg3;
1333  fcinfo->args[2].isnull = false;
1334  fcinfo->args[3].value = arg4;
1335  fcinfo->args[3].isnull = false;
1336  fcinfo->args[4].value = arg5;
1337  fcinfo->args[4].isnull = false;
1338  fcinfo->args[5].value = arg6;
1339  fcinfo->args[5].isnull = false;
1340  fcinfo->args[6].value = arg7;
1341  fcinfo->args[6].isnull = false;
1342  fcinfo->args[7].value = arg8;
1343  fcinfo->args[7].isnull = false;
1344 
1345  result = FunctionCallInvoke(fcinfo);
1346 
1347  /* Check for null result, since caller is clearly not expecting one */
1348  if (fcinfo->isnull)
1349  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1350 
1351  return result;
1352 }
1353 
1354 Datum
1356  Datum arg3, Datum arg4, Datum arg5,
1357  Datum arg6, Datum arg7, Datum arg8,
1358  Datum arg9)
1359 {
1360  LOCAL_FCINFO(fcinfo, 9);
1361  Datum result;
1362 
1363  InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL);
1364 
1365  fcinfo->args[0].value = arg1;
1366  fcinfo->args[0].isnull = false;
1367  fcinfo->args[1].value = arg2;
1368  fcinfo->args[1].isnull = false;
1369  fcinfo->args[2].value = arg3;
1370  fcinfo->args[2].isnull = false;
1371  fcinfo->args[3].value = arg4;
1372  fcinfo->args[3].isnull = false;
1373  fcinfo->args[4].value = arg5;
1374  fcinfo->args[4].isnull = false;
1375  fcinfo->args[5].value = arg6;
1376  fcinfo->args[5].isnull = false;
1377  fcinfo->args[6].value = arg7;
1378  fcinfo->args[6].isnull = false;
1379  fcinfo->args[7].value = arg8;
1380  fcinfo->args[7].isnull = false;
1381  fcinfo->args[8].value = arg9;
1382  fcinfo->args[8].isnull = false;
1383 
1384  result = FunctionCallInvoke(fcinfo);
1385 
1386  /* Check for null result, since caller is clearly not expecting one */
1387  if (fcinfo->isnull)
1388  elog(ERROR, "function %u returned NULL", flinfo->fn_oid);
1389 
1390  return result;
1391 }
1392 
1393 
1394 /*
1395  * These are for invocation of a function identified by OID with a
1396  * directly-computed parameter list. Note that neither arguments nor result
1397  * are allowed to be NULL. These are essentially fmgr_info() followed
1398  * by FunctionCallN(). If the same function is to be invoked repeatedly,
1399  * do the fmgr_info() once and then use FunctionCallN().
1400  */
1401 Datum
1402 OidFunctionCall0Coll(Oid functionId, Oid collation)
1403 {
1404  FmgrInfo flinfo;
1405 
1406  fmgr_info(functionId, &flinfo);
1407 
1408  return FunctionCall0Coll(&flinfo, collation);
1409 }
1410 
1411 Datum
1412 OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
1413 {
1414  FmgrInfo flinfo;
1415 
1416  fmgr_info(functionId, &flinfo);
1417 
1418  return FunctionCall1Coll(&flinfo, collation, arg1);
1419 }
1420 
1421 Datum
1422 OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
1423 {
1424  FmgrInfo flinfo;
1425 
1426  fmgr_info(functionId, &flinfo);
1427 
1428  return FunctionCall2Coll(&flinfo, collation, arg1, arg2);
1429 }
1430 
1431 Datum
1432 OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1433  Datum arg3)
1434 {
1435  FmgrInfo flinfo;
1436 
1437  fmgr_info(functionId, &flinfo);
1438 
1439  return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3);
1440 }
1441 
1442 Datum
1443 OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1444  Datum arg3, Datum arg4)
1445 {
1446  FmgrInfo flinfo;
1447 
1448  fmgr_info(functionId, &flinfo);
1449 
1450  return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4);
1451 }
1452 
1453 Datum
1454 OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1455  Datum arg3, Datum arg4, Datum arg5)
1456 {
1457  FmgrInfo flinfo;
1458 
1459  fmgr_info(functionId, &flinfo);
1460 
1461  return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5);
1462 }
1463 
1464 Datum
1465 OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1466  Datum arg3, Datum arg4, Datum arg5,
1467  Datum arg6)
1468 {
1469  FmgrInfo flinfo;
1470 
1471  fmgr_info(functionId, &flinfo);
1472 
1473  return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1474  arg6);
1475 }
1476 
1477 Datum
1478 OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1479  Datum arg3, Datum arg4, Datum arg5,
1480  Datum arg6, Datum arg7)
1481 {
1482  FmgrInfo flinfo;
1483 
1484  fmgr_info(functionId, &flinfo);
1485 
1486  return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1487  arg6, arg7);
1488 }
1489 
1490 Datum
1491 OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1492  Datum arg3, Datum arg4, Datum arg5,
1493  Datum arg6, Datum arg7, Datum arg8)
1494 {
1495  FmgrInfo flinfo;
1496 
1497  fmgr_info(functionId, &flinfo);
1498 
1499  return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1500  arg6, arg7, arg8);
1501 }
1502 
1503 Datum
1504 OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
1505  Datum arg3, Datum arg4, Datum arg5,
1506  Datum arg6, Datum arg7, Datum arg8,
1507  Datum arg9)
1508 {
1509  FmgrInfo flinfo;
1510 
1511  fmgr_info(functionId, &flinfo);
1512 
1513  return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5,
1514  arg6, arg7, arg8, arg9);
1515 }
1516 
1517 
1518 /*
1519  * Special cases for convenient invocation of datatype I/O functions.
1520  */
1521 
1522 /*
1523  * Call a previously-looked-up datatype input function.
1524  *
1525  * "str" may be NULL to indicate we are reading a NULL. In this case
1526  * the caller should assume the result is NULL, but we'll call the input
1527  * function anyway if it's not strict. So this is almost but not quite
1528  * the same as FunctionCall3.
1529  */
1530 Datum
1531 InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
1532 {
1533  LOCAL_FCINFO(fcinfo, 3);
1534  Datum result;
1535 
1536  if (str == NULL && flinfo->fn_strict)
1537  return (Datum) 0; /* just return null result */
1538 
1539  InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1540 
1541  fcinfo->args[0].value = CStringGetDatum(str);
1542  fcinfo->args[0].isnull = false;
1543  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1544  fcinfo->args[1].isnull = false;
1545  fcinfo->args[2].value = Int32GetDatum(typmod);
1546  fcinfo->args[2].isnull = false;
1547 
1548  result = FunctionCallInvoke(fcinfo);
1549 
1550  /* Should get null result if and only if str is NULL */
1551  if (str == NULL)
1552  {
1553  if (!fcinfo->isnull)
1554  elog(ERROR, "input function %u returned non-NULL",
1555  flinfo->fn_oid);
1556  }
1557  else
1558  {
1559  if (fcinfo->isnull)
1560  elog(ERROR, "input function %u returned NULL",
1561  flinfo->fn_oid);
1562  }
1563 
1564  return result;
1565 }
1566 
1567 /*
1568  * Call a previously-looked-up datatype output function.
1569  *
1570  * Do not call this on NULL datums.
1571  *
1572  * This is currently little more than window dressing for FunctionCall1.
1573  */
1574 char *
1576 {
1577  return DatumGetCString(FunctionCall1(flinfo, val));
1578 }
1579 
1580 /*
1581  * Call a previously-looked-up datatype binary-input function.
1582  *
1583  * "buf" may be NULL to indicate we are reading a NULL. In this case
1584  * the caller should assume the result is NULL, but we'll call the receive
1585  * function anyway if it's not strict. So this is almost but not quite
1586  * the same as FunctionCall3.
1587  */
1588 Datum
1590  Oid typioparam, int32 typmod)
1591 {
1592  LOCAL_FCINFO(fcinfo, 3);
1593  Datum result;
1594 
1595  if (buf == NULL && flinfo->fn_strict)
1596  return (Datum) 0; /* just return null result */
1597 
1598  InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
1599 
1600  fcinfo->args[0].value = PointerGetDatum(buf);
1601  fcinfo->args[0].isnull = false;
1602  fcinfo->args[1].value = ObjectIdGetDatum(typioparam);
1603  fcinfo->args[1].isnull = false;
1604  fcinfo->args[2].value = Int32GetDatum(typmod);
1605  fcinfo->args[2].isnull = false;
1606 
1607  result = FunctionCallInvoke(fcinfo);
1608 
1609  /* Should get null result if and only if buf is NULL */
1610  if (buf == NULL)
1611  {
1612  if (!fcinfo->isnull)
1613  elog(ERROR, "receive function %u returned non-NULL",
1614  flinfo->fn_oid);
1615  }
1616  else
1617  {
1618  if (fcinfo->isnull)
1619  elog(ERROR, "receive function %u returned NULL",
1620  flinfo->fn_oid);
1621  }
1622 
1623  return result;
1624 }
1625 
1626 /*
1627  * Call a previously-looked-up datatype binary-output function.
1628  *
1629  * Do not call this on NULL datums.
1630  *
1631  * This is little more than window dressing for FunctionCall1, but it does
1632  * guarantee a non-toasted result, which strictly speaking the underlying
1633  * function doesn't.
1634  */
1635 bytea *
1637 {
1638  return DatumGetByteaP(FunctionCall1(flinfo, val));
1639 }
1640 
1641 /*
1642  * As above, for I/O functions identified by OID. These are only to be used
1643  * in seldom-executed code paths. They are not only slow but leak memory.
1644  */
1645 Datum
1646 OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
1647 {
1648  FmgrInfo flinfo;
1649 
1650  fmgr_info(functionId, &flinfo);
1651  return InputFunctionCall(&flinfo, str, typioparam, typmod);
1652 }
1653 
1654 char *
1656 {
1657  FmgrInfo flinfo;
1658 
1659  fmgr_info(functionId, &flinfo);
1660  return OutputFunctionCall(&flinfo, val);
1661 }
1662 
1663 Datum
1665  Oid typioparam, int32 typmod)
1666 {
1667  FmgrInfo flinfo;
1668 
1669  fmgr_info(functionId, &flinfo);
1670  return ReceiveFunctionCall(&flinfo, buf, typioparam, typmod);
1671 }
1672 
1673 bytea *
1675 {
1676  FmgrInfo flinfo;
1677 
1678  fmgr_info(functionId, &flinfo);
1679  return SendFunctionCall(&flinfo, val);
1680 }
1681 
1682 
1683 /*-------------------------------------------------------------------------
1684  * Support routines for standard maybe-pass-by-reference datatypes
1685  *
1686  * int8, float4, and float8 can be passed by value if Datum is wide enough.
1687  * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
1688  * at compile time even if pass-by-val is possible.)
1689  *
1690  * Note: there is only one switch controlling the pass-by-value option for
1691  * both int8 and float8; this is to avoid making things unduly complicated
1692  * for the timestamp types, which might have either representation.
1693  *-------------------------------------------------------------------------
1694  */
1695 
1696 #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
1697 
1698 Datum
1700 {
1701  int64 *retval = (int64 *) palloc(sizeof(int64));
1702 
1703  *retval = X;
1704  return PointerGetDatum(retval);
1705 }
1706 #endif /* USE_FLOAT8_BYVAL */
1707 
1708 #ifndef USE_FLOAT4_BYVAL
1709 
1710 Datum
1712 {
1713  float4 *retval = (float4 *) palloc(sizeof(float4));
1714 
1715  *retval = X;
1716  return PointerGetDatum(retval);
1717 }
1718 #endif
1719 
1720 #ifndef USE_FLOAT8_BYVAL
1721 
1722 Datum
1724 {
1725  float8 *retval = (float8 *) palloc(sizeof(float8));
1726 
1727  *retval = X;
1728  return PointerGetDatum(retval);
1729 }
1730 #endif
1731 
1732 
1733 /*-------------------------------------------------------------------------
1734  * Support routines for toastable datatypes
1735  *-------------------------------------------------------------------------
1736  */
1737 
1738 struct varlena *
1740 {
1741  if (VARATT_IS_EXTENDED(datum))
1742  return heap_tuple_untoast_attr(datum);
1743  else
1744  return datum;
1745 }
1746 
1747 struct varlena *
1749 {
1750  if (VARATT_IS_EXTENDED(datum))
1751  return heap_tuple_untoast_attr(datum);
1752  else
1753  {
1754  /* Make a modifiable copy of the varlena object */
1755  Size len = VARSIZE(datum);
1756  struct varlena *result = (struct varlena *) palloc(len);
1757 
1758  memcpy(result, datum, len);
1759  return result;
1760  }
1761 }
1762 
1763 struct varlena *
1764 pg_detoast_datum_slice(struct varlena *datum, int32 first, int32 count)
1765 {
1766  /* Only get the specified portion from the toast rel */
1767  return heap_tuple_untoast_attr_slice(datum, first, count);
1768 }
1769 
1770 struct varlena *
1772 {
1773  if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum))
1774  return heap_tuple_untoast_attr(datum);
1775  else
1776  return datum;
1777 }
1778 
1779 /*-------------------------------------------------------------------------
1780  * Support routines for extracting info from fn_expr parse tree
1781  *
1782  * These are needed by polymorphic functions, which accept multiple possible
1783  * input types and need help from the parser to know what they've got.
1784  * Also, some functions might be interested in whether a parameter is constant.
1785  * Functions taking VARIADIC ANY also need to know about the VARIADIC keyword.
1786  *-------------------------------------------------------------------------
1787  */
1788 
1789 /*
1790  * Get the actual type OID of the function return type
1791  *
1792  * Returns InvalidOid if information is not available
1793  */
1794 Oid
1796 {
1797  Node *expr;
1798 
1799  /*
1800  * can't return anything useful if we have no FmgrInfo or if its fn_expr
1801  * node has not been initialized
1802  */
1803  if (!flinfo || !flinfo->fn_expr)
1804  return InvalidOid;
1805 
1806  expr = flinfo->fn_expr;
1807 
1808  return exprType(expr);
1809 }
1810 
1811 /*
1812  * Get the actual type OID of a specific function argument (counting from 0)
1813  *
1814  * Returns InvalidOid if information is not available
1815  */
1816 Oid
1818 {
1819  /*
1820  * can't return anything useful if we have no FmgrInfo or if its fn_expr
1821  * node has not been initialized
1822  */
1823  if (!flinfo || !flinfo->fn_expr)
1824  return InvalidOid;
1825 
1826  return get_call_expr_argtype(flinfo->fn_expr, argnum);
1827 }
1828 
1829 /*
1830  * Get the actual type OID of a specific function argument (counting from 0),
1831  * but working from the calling expression tree instead of FmgrInfo
1832  *
1833  * Returns InvalidOid if information is not available
1834  */
1835 Oid
1836 get_call_expr_argtype(Node *expr, int argnum)
1837 {
1838  List *args;
1839  Oid argtype;
1840 
1841  if (expr == NULL)
1842  return InvalidOid;
1843 
1844  if (IsA(expr, FuncExpr))
1845  args = ((FuncExpr *) expr)->args;
1846  else if (IsA(expr, OpExpr))
1847  args = ((OpExpr *) expr)->args;
1848  else if (IsA(expr, DistinctExpr))
1849  args = ((DistinctExpr *) expr)->args;
1850  else if (IsA(expr, ScalarArrayOpExpr))
1851  args = ((ScalarArrayOpExpr *) expr)->args;
1852  else if (IsA(expr, NullIfExpr))
1853  args = ((NullIfExpr *) expr)->args;
1854  else if (IsA(expr, WindowFunc))
1855  args = ((WindowFunc *) expr)->args;
1856  else
1857  return InvalidOid;
1858 
1859  if (argnum < 0 || argnum >= list_length(args))
1860  return InvalidOid;
1861 
1862  argtype = exprType((Node *) list_nth(args, argnum));
1863 
1864  /*
1865  * special hack for ScalarArrayOpExpr: what the underlying function will
1866  * actually get passed is the element type of the array.
1867  */
1868  if (IsA(expr, ScalarArrayOpExpr) &&
1869  argnum == 1)
1870  argtype = get_base_element_type(argtype);
1871 
1872  return argtype;
1873 }
1874 
1875 /*
1876  * Find out whether a specific function argument is constant for the
1877  * duration of a query
1878  *
1879  * Returns false if information is not available
1880  */
1881 bool
1883 {
1884  /*
1885  * can't return anything useful if we have no FmgrInfo or if its fn_expr
1886  * node has not been initialized
1887  */
1888  if (!flinfo || !flinfo->fn_expr)
1889  return false;
1890 
1891  return get_call_expr_arg_stable(flinfo->fn_expr, argnum);
1892 }
1893 
1894 /*
1895  * Find out whether a specific function argument is constant for the
1896  * duration of a query, but working from the calling expression tree
1897  *
1898  * Returns false if information is not available
1899  */
1900 bool
1901 get_call_expr_arg_stable(Node *expr, int argnum)
1902 {
1903  List *args;
1904  Node *arg;
1905 
1906  if (expr == NULL)
1907  return false;
1908 
1909  if (IsA(expr, FuncExpr))
1910  args = ((FuncExpr *) expr)->args;
1911  else if (IsA(expr, OpExpr))
1912  args = ((OpExpr *) expr)->args;
1913  else if (IsA(expr, DistinctExpr))
1914  args = ((DistinctExpr *) expr)->args;
1915  else if (IsA(expr, ScalarArrayOpExpr))
1916  args = ((ScalarArrayOpExpr *) expr)->args;
1917  else if (IsA(expr, NullIfExpr))
1918  args = ((NullIfExpr *) expr)->args;
1919  else if (IsA(expr, WindowFunc))
1920  args = ((WindowFunc *) expr)->args;
1921  else
1922  return false;
1923 
1924  if (argnum < 0 || argnum >= list_length(args))
1925  return false;
1926 
1927  arg = (Node *) list_nth(args, argnum);
1928 
1929  /*
1930  * Either a true Const or an external Param will have a value that doesn't
1931  * change during the execution of the query. In future we might want to
1932  * consider other cases too, e.g. now().
1933  */
1934  if (IsA(arg, Const))
1935  return true;
1936  if (IsA(arg, Param) &&
1937  ((Param *) arg)->paramkind == PARAM_EXTERN)
1938  return true;
1939 
1940  return false;
1941 }
1942 
1943 /*
1944  * Get the VARIADIC flag from the function invocation
1945  *
1946  * Returns false (the default assumption) if information is not available
1947  *
1948  * Note this is generally only of interest to VARIADIC ANY functions
1949  */
1950 bool
1952 {
1953  Node *expr;
1954 
1955  /*
1956  * can't return anything useful if we have no FmgrInfo or if its fn_expr
1957  * node has not been initialized
1958  */
1959  if (!flinfo || !flinfo->fn_expr)
1960  return false;
1961 
1962  expr = flinfo->fn_expr;
1963 
1964  if (IsA(expr, FuncExpr))
1965  return ((FuncExpr *) expr)->funcvariadic;
1966  else
1967  return false;
1968 }
1969 
1970 /*-------------------------------------------------------------------------
1971  * Support routines for procedural language implementations
1972  *-------------------------------------------------------------------------
1973  */
1974 
1975 /*
1976  * Verify that a validator is actually associated with the language of a
1977  * particular function and that the user has access to both the language and
1978  * the function. All validators should call this before doing anything
1979  * substantial. Doing so ensures a user cannot achieve anything with explicit
1980  * calls to validators that he could not achieve with CREATE FUNCTION or by
1981  * simply calling an existing function.
1982  *
1983  * When this function returns false, callers should skip all validation work
1984  * and call PG_RETURN_VOID(). This never happens at present; it is reserved
1985  * for future expansion.
1986  *
1987  * In particular, checking that the validator corresponds to the function's
1988  * language allows untrusted language validators to assume they process only
1989  * superuser-chosen source code. (Untrusted language call handlers, by
1990  * definition, do assume that.) A user lacking the USAGE language privilege
1991  * would be unable to reach the validator through CREATE FUNCTION, so we check
1992  * that to block explicit calls as well. Checking the EXECUTE privilege on
1993  * the function is often superfluous, because most users can clone the
1994  * function to get an executable copy. It is meaningful against users with no
1995  * database TEMP right and no permanent schema CREATE right, thereby unable to
1996  * create any function. Also, if the function tracks persistent state by
1997  * function OID or name, validating the original function might permit more
1998  * mischief than creating and validating a clone thereof.
1999  */
2000 bool
2001 CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
2002 {
2003  HeapTuple procTup;
2004  HeapTuple langTup;
2005  Form_pg_proc procStruct;
2006  Form_pg_language langStruct;
2007  AclResult aclresult;
2008 
2009  /*
2010  * Get the function's pg_proc entry. Throw a user-facing error for bad
2011  * OID, because validators can be called with user-specified OIDs.
2012  */
2013  procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionOid));
2014  if (!HeapTupleIsValid(procTup))
2015  ereport(ERROR,
2016  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2017  errmsg("function with OID %u does not exist", functionOid)));
2018  procStruct = (Form_pg_proc) GETSTRUCT(procTup);
2019 
2020  /*
2021  * Fetch pg_language entry to know if this is the correct validation
2022  * function for that pg_proc entry.
2023  */
2024  langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(procStruct->prolang));
2025  if (!HeapTupleIsValid(langTup))
2026  elog(ERROR, "cache lookup failed for language %u", procStruct->prolang);
2027  langStruct = (Form_pg_language) GETSTRUCT(langTup);
2028 
2029  if (langStruct->lanvalidator != validatorOid)
2030  ereport(ERROR,
2031  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2032  errmsg("language validation function %u called for language %u instead of %u",
2033  validatorOid, procStruct->prolang,
2034  langStruct->lanvalidator)));
2035 
2036  /* first validate that we have permissions to use the language */
2037  aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
2038  ACL_USAGE);
2039  if (aclresult != ACLCHECK_OK)
2040  aclcheck_error(aclresult, OBJECT_LANGUAGE,
2041  NameStr(langStruct->lanname));
2042 
2043  /*
2044  * Check whether we are allowed to execute the function itself. If we can
2045  * execute it, there should be no possible side-effect of
2046  * compiling/validation that execution can't have.
2047  */
2048  aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
2049  if (aclresult != ACLCHECK_OK)
2050  aclcheck_error(aclresult, OBJECT_FUNCTION, NameStr(procStruct->proname));
2051 
2052  ReleaseSysCache(procTup);
2053  ReleaseSysCache(langTup);
2054 
2055  return true;
2056 }
bool strict
Definition: fmgrtab.h:29
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:171
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:575
int errhint(const char *fmt,...)
Definition: elog.c:974
short fn_nargs
Definition: fmgr.h:60
NameData proname
Definition: pg_proc.h:36
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
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:1882
short nargs
Definition: fmgrtab.h:28
uint32 TransactionId
Definition: c.h:507
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:492
Oid GetUserId(void)
Definition: miscinit.c:380
struct varlena * pg_detoast_datum_copy(struct varlena *datum)
Definition: fmgr.c:1748
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:755
#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:1432
Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1086
#define PointerGetDatum(X)
Definition: postgres.h:556
Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)
Definition: fmgr.c:1224
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:1319
Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
Definition: fmgr.c:860
const int fmgr_nbuiltins
char * pstrdup(const char *in)
Definition: mcxt.c:1161
struct varlena * pg_detoast_datum(struct varlena *datum)
Definition: fmgr.c:1739
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:1504
Size entrysize
Definition: hsearch.h:73
Definition: nodes.h:524
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1951
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:1355
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:941
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition: fmgr.c:1836
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
const FmgrBuiltin fmgr_builtins[]
Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
Definition: fmgr.c:1197
#define InvalidOidBuiltinMapping
Definition: fmgrtab.h:45
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:1150
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:761
AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4667
#define PGDLLIMPORT
Definition: c.h:1229
void fmgr_symbol(Oid functionId, char **mod, char **fn)
Definition: fmgr.c:281
signed int int32
Definition: c.h:346
bool get_call_expr_arg_stable(Node *expr, int argnum)
Definition: fmgr.c:1901
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1723
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
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
Definition: dynahash.c:208
const Oid fmgr_last_builtin_oid
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
PGFunction func
Definition: fmgrtab.h:32
unsigned short uint16
Definition: c.h:357
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:507
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:491
bool fn_strict
Definition: fmgr.h:61
#define DatumGetCString(X)
Definition: postgres.h:566
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
Definition: pgstat.c:1622
bool(* needs_fmgr_hook_type)(Oid fn_oid)
Definition: fmgr.h:753
Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7)
Definition: fmgr.c:1285
bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
Definition: fmgr.c:2001
static void * list_nth(const List *list, int n)
Definition: pg_list.h:277
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1589
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:1771
Definition: guc.h:75
Datum Float4GetDatum(float4 X)
Definition: fmgr.c:1711
ItemPointerData t_self
Definition: htup.h:65
#define DatumGetByteaP(X)
Definition: fmgr.h:325
Datum OidReceiveFunctionCall(Oid functionId, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1664
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:610
bytea * OidSendFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1674
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:167
static char * buf
Definition: pg_test_fsync.c:68
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:485
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:5742
#define CStringGetDatum(X)
Definition: postgres.h:578
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:1636
#define ACL_USAGE
Definition: parsenodes.h:82
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
Definition: fmgr.h:749
Datum fmgr_sql(PG_FUNCTION_ARGS)
Definition: functions.c:984
struct varlena * pg_detoast_datum_slice(struct varlena *datum, int32 first, int32 count)
Definition: fmgr.c:1764
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
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:107
void clear_external_function_hash(void *filehandle)
Definition: fmgr.c:594
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1422
#define ereport(elevel, rest)
Definition: elog.h:141
Datum DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6)
Definition: fmgr.c:916
const uint16 fmgr_builtin_oid_index[]
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
float float4
Definition: c.h:490
#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:84
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:1795
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1130
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
#define DatumGetArrayTypePCopy(X)
Definition: array.h:250
Datum FunctionCall0Coll(FmgrInfo *flinfo, Oid collation)
Definition: fmgr.c:1113
Size keysize
Definition: hsearch.h:72
PGDLLIMPORT fmgr_hook_type fmgr_hook
Definition: fmgr.c:37
#define SECURITY_LOCAL_USERID_CHANGE
Definition: miscadmin.h:299
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:814
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1531
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:10332
Oid fn_oid
Definition: fmgr.h:59
Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)
Definition: fmgr.c:1172
Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
Definition: fmgr.c:1412
static void * fn(void *arg)
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
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:310
Datum OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6)
Definition: fmgr.c:1465
#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:1478
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:1491
Datum fmgr_security_definer(PG_FUNCTION_ARGS)
Definition: fmgr.c:660
size_t Size
Definition: c.h:466
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
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:1454
static int list_length(const List *l)
Definition: pg_list.h:169
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:308
#define PG_RE_THROW()
Definition: elog.h:331
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:1443
const Pg_finfo_record *(* PGFInfoFunction)(void)
Definition: fmgr.h:390
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:1694
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2599
#define Int32GetDatum(X)
Definition: postgres.h:479
int NewGUCNestLevel(void)
Definition: guc.c:5728
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1655
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
Datum OidFunctionCall0Coll(Oid functionId, Oid collation)
Definition: fmgr.c:1402
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:1253
#define elog(elevel,...)
Definition: elog.h:226
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4655
unsigned char fn_stats
Definition: fmgr.h:63
int i
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:634
#define NameStr(name)
Definition: c.h:609
TransactionId fn_xmin
Definition: fmgr.c:46
Definition: c.h:549
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188
#define PG_TRY()
Definition: elog.h:301
Definition: pg_list.h:50
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1646
ItemPointerData fn_tid
Definition: fmgr.c:47
int api_version
Definition: fmgr.h:385
long val
Definition: informix.c:689
#define PG_END_TRY()
Definition: elog.h:317
static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, bool ignore_security)
Definition: fmgr.c:144
bool retset
Definition: fmgrtab.h:30