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