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