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