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 *
fmgr_isbuiltin(Oid id)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 *
fmgr_lookupByName(const char * name)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
fmgr_info(Oid functionId,FmgrInfo * finfo)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
fmgr_info_cxt(Oid functionId,FmgrInfo * finfo,MemoryContext mcxt)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
fmgr_info_cxt_security(Oid functionId,FmgrInfo * finfo,MemoryContext mcxt,bool ignore_security)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
fmgr_info_C_lang(Oid functionId,FmgrInfo * finfo,HeapTuple procedureTuple)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
fmgr_info_other_lang(Oid functionId,FmgrInfo * finfo,HeapTuple procedureTuple)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 *
fetch_finfo_record(void * filehandle,const char * funcname)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 *
lookup_C_func(HeapTuple procedureTuple)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
record_C_func(HeapTuple procedureTuple,PGFunction user_fn,const Pg_finfo_record * inforec)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
clear_external_function_hash(void * filehandle)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
fmgr_info_copy(FmgrInfo * dstinfo,FmgrInfo * srcinfo,MemoryContext destcxt)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
fmgr_internal_function(const char * proname)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
fmgr_security_definer(PG_FUNCTION_ARGS)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
DirectFunctionCall1Coll(PGFunction func,Oid collation,Datum arg1)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
DirectFunctionCall2Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2)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
DirectFunctionCall3Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3)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
DirectFunctionCall4Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4)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
DirectFunctionCall5Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5)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
DirectFunctionCall6Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6)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
DirectFunctionCall7Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7)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
DirectFunctionCall8Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8)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
DirectFunctionCall9Coll(PGFunction func,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8,Datum arg9)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
CallerFInfoFunctionCall1(PGFunction func,FmgrInfo * flinfo,Oid collation,Datum arg1)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
CallerFInfoFunctionCall2(PGFunction func,FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2)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
FunctionCall1Coll(FmgrInfo * flinfo,Oid collation,Datum arg1)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
FunctionCall2Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2)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
FunctionCall3Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3)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
FunctionCall4Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4)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
FunctionCall5Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5)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
FunctionCall6Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6)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
FunctionCall7Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7)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
FunctionCall8Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8)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
FunctionCall9Coll(FmgrInfo * flinfo,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8,Datum arg9)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
OidFunctionCall0Coll(Oid functionId,Oid collation)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
OidFunctionCall1Coll(Oid functionId,Oid collation,Datum arg1)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
OidFunctionCall2Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2)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
OidFunctionCall3Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3)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
OidFunctionCall4Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4)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
OidFunctionCall5Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5)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
OidFunctionCall6Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6)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
OidFunctionCall7Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7)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
OidFunctionCall8Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8)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
OidFunctionCall9Coll(Oid functionId,Oid collation,Datum arg1,Datum arg2,Datum arg3,Datum arg4,Datum arg5,Datum arg6,Datum arg7,Datum arg8,Datum arg9)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
InputFunctionCall(FmgrInfo * flinfo,char * str,Oid typioparam,int32 typmod)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 *
OutputFunctionCall(FmgrInfo * flinfo,Datum val)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
ReceiveFunctionCall(FmgrInfo * flinfo,StringInfo buf,Oid typioparam,int32 typmod)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 *
SendFunctionCall(FmgrInfo * flinfo,Datum val)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
OidInputFunctionCall(Oid functionId,char * str,Oid typioparam,int32 typmod)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 *
OidOutputFunctionCall(Oid functionId,Datum val)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
OidReceiveFunctionCall(Oid functionId,StringInfo buf,Oid typioparam,int32 typmod)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 *
OidSendFunctionCall(Oid functionId,Datum val)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
Int64GetDatum(int64 X)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
Float4GetDatum(float4 X)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
Float8GetDatum(float8 X)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 *
pg_detoast_datum(struct varlena * datum)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 *
pg_detoast_datum_copy(struct varlena * datum)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 *
pg_detoast_datum_slice(struct varlena * datum,int32 first,int32 count)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 *
pg_detoast_datum_packed(struct varlena * datum)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
get_fn_expr_rettype(FmgrInfo * flinfo)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
get_fn_expr_argtype(FmgrInfo * flinfo,int argnum)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
get_call_expr_argtype(Node * expr,int argnum)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
get_fn_expr_arg_stable(FmgrInfo * flinfo,int argnum)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
get_call_expr_arg_stable(Node * expr,int argnum)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
get_fn_expr_variadic(FmgrInfo * flinfo)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
CheckFunctionValidatorAccess(Oid validatorOid,Oid functionOid)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 }
2157