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