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