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