1 /*-------------------------------------------------------------------------
2  *
3  * functions.c
4  *	  Execution of SQL-language functions
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/executor/functions.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/htup_details.h"
18 #include "access/xact.h"
19 #include "catalog/pg_proc.h"
20 #include "catalog/pg_type.h"
21 #include "executor/functions.h"
22 #include "funcapi.h"
23 #include "miscadmin.h"
24 #include "nodes/makefuncs.h"
25 #include "nodes/nodeFuncs.h"
26 #include "parser/parse_coerce.h"
27 #include "parser/parse_collate.h"
28 #include "parser/parse_func.h"
29 #include "storage/proc.h"
30 #include "tcop/utility.h"
31 #include "utils/builtins.h"
32 #include "utils/datum.h"
33 #include "utils/lsyscache.h"
34 #include "utils/memutils.h"
35 #include "utils/snapmgr.h"
36 #include "utils/syscache.h"
37 
38 
39 /*
40  * Specialized DestReceiver for collecting query output in a SQL function
41  */
42 typedef struct
43 {
44 	DestReceiver pub;			/* publicly-known function pointers */
45 	Tuplestorestate *tstore;	/* where to put result tuples */
46 	MemoryContext cxt;			/* context containing tstore */
47 	JunkFilter *filter;			/* filter to convert tuple type */
48 } DR_sqlfunction;
49 
50 /*
51  * We have an execution_state record for each query in a function.  Each
52  * record contains a plantree for its query.  If the query is currently in
53  * F_EXEC_RUN state then there's a QueryDesc too.
54  *
55  * The "next" fields chain together all the execution_state records generated
56  * from a single original parsetree.  (There will only be more than one in
57  * case of rule expansion of the original parsetree.)
58  */
59 typedef enum
60 {
61 	F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE
62 } ExecStatus;
63 
64 typedef struct execution_state
65 {
66 	struct execution_state *next;
67 	ExecStatus	status;
68 	bool		setsResult;		/* true if this query produces func's result */
69 	bool		lazyEval;		/* true if should fetch one row at a time */
70 	PlannedStmt *stmt;			/* plan for this query */
71 	QueryDesc  *qd;				/* null unless status == RUN */
72 } execution_state;
73 
74 
75 /*
76  * An SQLFunctionCache record is built during the first call,
77  * and linked to from the fn_extra field of the FmgrInfo struct.
78  *
79  * Note that currently this has only the lifespan of the calling query.
80  * Someday we should rewrite this code to use plancache.c to save parse/plan
81  * results for longer than that.
82  *
83  * Physically, though, the data has the lifespan of the FmgrInfo that's used
84  * to call the function, and there are cases (particularly with indexes)
85  * where the FmgrInfo might survive across transactions.  We cannot assume
86  * that the parse/plan trees are good for longer than the (sub)transaction in
87  * which parsing was done, so we must mark the record with the LXID/subxid of
88  * its creation time, and regenerate everything if that's obsolete.  To avoid
89  * memory leakage when we do have to regenerate things, all the data is kept
90  * in a sub-context of the FmgrInfo's fn_mcxt.
91  */
92 typedef struct
93 {
94 	char	   *fname;			/* function name (for error msgs) */
95 	char	   *src;			/* function body text (for error msgs) */
96 
tts_virtual_init(TupleTableSlot * slot)97 	SQLFunctionParseInfoPtr pinfo;	/* data for parser callback hooks */
98 
99 	Oid			rettype;		/* actual return type */
100 	int16		typlen;			/* length of the return type */
101 	bool		typbyval;		/* true if return type is pass by value */
tts_virtual_release(TupleTableSlot * slot)102 	bool		returnsSet;		/* true if returning multiple rows */
103 	bool		returnsTuple;	/* true if returning whole tuple result */
104 	bool		shutdown_reg;	/* true if registered shutdown callback */
105 	bool		readonly_func;	/* true to run in "read only" mode */
106 	bool		lazyEval;		/* true if using lazyEval for result query */
tts_virtual_clear(TupleTableSlot * slot)107 
108 	ParamListInfo paramLI;		/* Param list representing current args */
109 
110 	Tuplestorestate *tstore;	/* where we accumulate result tuples */
111 
112 	JunkFilter *junkFilter;		/* will be NULL if function returns VOID */
113 
114 	/*
115 	 * func_state is a List of execution_state records, each of which is the
116 	 * first for its original parsetree, with any additional records chained
117 	 * to it via the "next" fields.  This sublist structure is needed to keep
118 	 * track of where the original query boundaries are.
119 	 */
120 	List	   *func_state;
121 
122 	MemoryContext fcontext;		/* memory context holding this struct and all
123 								 * subsidiary data */
124 
125 	LocalTransactionId lxid;	/* lxid in which cache was made */
126 	SubTransactionId subxid;	/* subxid in which cache was made */
127 } SQLFunctionCache;
128 
tts_virtual_getsomeattrs(TupleTableSlot * slot,int natts)129 typedef SQLFunctionCache *SQLFunctionCachePtr;
130 
131 /*
132  * Data structure needed by the parser callback hooks to resolve parameter
133  * references during parsing of a SQL function's body.  This is separate from
134  * SQLFunctionCache since we sometimes do parsing separately from execution.
135  */
136 typedef struct SQLFunctionParseInfo
137 {
138 	char	   *fname;			/* function's name */
139 	int			nargs;			/* number of input arguments */
tts_virtual_getsysattr(TupleTableSlot * slot,int attnum,bool * isnull)140 	Oid		   *argtypes;		/* resolved types of input arguments */
141 	char	  **argnames;		/* names of input arguments; NULL if none */
142 	/* Note that argnames[i] can be NULL, if some args are unnamed */
143 	Oid			collation;		/* function's input collation, if known */
144 }			SQLFunctionParseInfo;
145 
146 
147 /* non-export function prototypes */
148 static Node *sql_fn_param_ref(ParseState *pstate, ParamRef *pref);
149 static Node *sql_fn_post_column_ref(ParseState *pstate,
150 									ColumnRef *cref, Node *var);
151 static Node *sql_fn_make_param(SQLFunctionParseInfoPtr pinfo,
152 							   int paramno, int location);
153 static Node *sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo,
154 									   const char *paramname, int location);
155 static List *init_execution_state(List *queryTree_list,
156 								  SQLFunctionCachePtr fcache,
157 								  bool lazyEvalOK);
158 static void init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK);
tts_virtual_materialize(TupleTableSlot * slot)159 static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
160 static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache);
161 static void postquel_end(execution_state *es);
162 static void postquel_sub_params(SQLFunctionCachePtr fcache,
163 								FunctionCallInfo fcinfo);
164 static Datum postquel_get_single_result(TupleTableSlot *slot,
165 										FunctionCallInfo fcinfo,
166 										SQLFunctionCachePtr fcache,
167 										MemoryContext resultcontext);
168 static void sql_exec_error_callback(void *arg);
169 static void ShutdownSQLFunction(Datum arg);
170 static bool coerce_fn_result_column(TargetEntry *src_tle,
171 									Oid res_type, int32 res_typmod,
172 									bool tlist_is_modifiable,
173 									List **upper_tlist,
174 									bool *upper_tlist_nontrivial);
175 static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo);
176 static bool sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self);
177 static void sqlfunction_shutdown(DestReceiver *self);
178 static void sqlfunction_destroy(DestReceiver *self);
179 
180 
181 /*
182  * Prepare the SQLFunctionParseInfo struct for parsing a SQL function body
183  *
184  * This includes resolving actual types of polymorphic arguments.
185  *
186  * call_expr can be passed as NULL, but then we will fail if there are any
187  * polymorphic arguments.
188  */
189 SQLFunctionParseInfoPtr
190 prepare_sql_fn_parse_info(HeapTuple procedureTuple,
191 						  Node *call_expr,
192 						  Oid inputCollation)
193 {
194 	SQLFunctionParseInfoPtr pinfo;
195 	Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
196 	int			nargs;
197 
198 	pinfo = (SQLFunctionParseInfoPtr) palloc0(sizeof(SQLFunctionParseInfo));
199 
200 	/* Function's name (only) can be used to qualify argument names */
201 	pinfo->fname = pstrdup(NameStr(procedureStruct->proname));
202 
203 	/* Save the function's input collation */
204 	pinfo->collation = inputCollation;
205 
206 	/*
207 	 * Copy input argument types from the pg_proc entry, then resolve any
208 	 * polymorphic types.
209 	 */
210 	pinfo->nargs = nargs = procedureStruct->pronargs;
211 	if (nargs > 0)
212 	{
213 		Oid		   *argOidVect;
214 		int			argnum;
215 
216 		argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
217 		memcpy(argOidVect,
218 			   procedureStruct->proargtypes.values,
219 			   nargs * sizeof(Oid));
220 
221 		for (argnum = 0; argnum < nargs; argnum++)
222 		{
223 			Oid			argtype = argOidVect[argnum];
224 
225 			if (IsPolymorphicType(argtype))
226 			{
227 				argtype = get_call_expr_argtype(call_expr, argnum);
228 				if (argtype == InvalidOid)
229 					ereport(ERROR,
230 							(errcode(ERRCODE_DATATYPE_MISMATCH),
231 							 errmsg("could not determine actual type of argument declared %s",
232 									format_type_be(argOidVect[argnum]))));
233 				argOidVect[argnum] = argtype;
234 			}
235 		}
236 
237 		pinfo->argtypes = argOidVect;
238 	}
239 
240 	/*
241 	 * Collect names of arguments, too, if any
242 	 */
243 	if (nargs > 0)
244 	{
245 		Datum		proargnames;
246 		Datum		proargmodes;
247 		int			n_arg_names;
248 		bool		isNull;
249 
250 		proargnames = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
251 									  Anum_pg_proc_proargnames,
tts_virtual_copyslot(TupleTableSlot * dstslot,TupleTableSlot * srcslot)252 									  &isNull);
253 		if (isNull)
254 			proargnames = PointerGetDatum(NULL);	/* just to be sure */
255 
256 		proargmodes = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
257 									  Anum_pg_proc_proargmodes,
258 									  &isNull);
259 		if (isNull)
260 			proargmodes = PointerGetDatum(NULL);	/* just to be sure */
261 
262 		n_arg_names = get_func_input_arg_names(proargnames, proargmodes,
263 											   &pinfo->argnames);
264 
265 		/* Paranoia: ignore the result if too few array entries */
266 		if (n_arg_names < nargs)
267 			pinfo->argnames = NULL;
268 	}
269 	else
270 		pinfo->argnames = NULL;
271 
272 	return pinfo;
273 }
274 
275 /*
tts_virtual_copy_heap_tuple(TupleTableSlot * slot)276  * Parser setup hook for parsing a SQL function body.
277  */
278 void
279 sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
280 {
281 	pstate->p_pre_columnref_hook = NULL;
282 	pstate->p_post_columnref_hook = sql_fn_post_column_ref;
283 	pstate->p_paramref_hook = sql_fn_param_ref;
284 	/* no need to use p_coerce_param_hook */
285 	pstate->p_ref_hook_state = (void *) pinfo;
286 }
287 
288 /*
289  * sql_fn_post_column_ref		parser callback for ColumnRefs
290  */
291 static Node *
292 sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
293 {
294 	SQLFunctionParseInfoPtr pinfo = (SQLFunctionParseInfoPtr) pstate->p_ref_hook_state;
295 	int			nnames;
296 	Node	   *field1;
297 	Node	   *subfield = NULL;
298 	const char *name1;
299 	const char *name2 = NULL;
300 	Node	   *param;
tts_heap_init(TupleTableSlot * slot)301 
302 	/*
303 	 * Never override a table-column reference.  This corresponds to
304 	 * considering the parameter names to appear in a scope outside the
305 	 * individual SQL commands, which is what we want.
306 	 */
307 	if (var != NULL)
308 		return NULL;
309 
310 	/*----------
tts_heap_clear(TupleTableSlot * slot)311 	 * The allowed syntaxes are:
312 	 *
313 	 * A		A = parameter name
314 	 * A.B		A = function name, B = parameter name
315 	 *			OR: A = record-typed parameter name, B = field name
316 	 *			(the first possibility takes precedence)
317 	 * A.B.C	A = function name, B = record-typed parameter name,
318 	 *			C = field name
319 	 * A.*		Whole-row reference to composite parameter A.
320 	 * A.B.*	Same, with A = function name, B = parameter name
321 	 *
322 	 * Here, it's sufficient to ignore the "*" in the last two cases --- the
323 	 * main parser will take care of expanding the whole-row reference.
324 	 *----------
325 	 */
326 	nnames = list_length(cref->fields);
327 
328 	if (nnames > 3)
329 		return NULL;
tts_heap_getsomeattrs(TupleTableSlot * slot,int natts)330 
331 	if (IsA(llast(cref->fields), A_Star))
332 		nnames--;
333 
334 	field1 = (Node *) linitial(cref->fields);
335 	Assert(IsA(field1, String));
336 	name1 = strVal(field1);
337 	if (nnames > 1)
338 	{
339 		subfield = (Node *) lsecond(cref->fields);
tts_heap_getsysattr(TupleTableSlot * slot,int attnum,bool * isnull)340 		Assert(IsA(subfield, String));
341 		name2 = strVal(subfield);
342 	}
343 
344 	if (nnames == 3)
345 	{
346 		/*
347 		 * Three-part name: if the first part doesn't match the function name,
348 		 * we can fail immediately. Otherwise, look up the second part, and
349 		 * take the third part to be a field reference.
350 		 */
351 		if (strcmp(name1, pinfo->fname) != 0)
352 			return NULL;
353 
354 		param = sql_fn_resolve_param_name(pinfo, name2, cref->location);
355 
356 		subfield = (Node *) lthird(cref->fields);
357 		Assert(IsA(subfield, String));
358 	}
359 	else if (nnames == 2 && strcmp(name1, pinfo->fname) == 0)
tts_heap_materialize(TupleTableSlot * slot)360 	{
361 		/*
362 		 * Two-part name with first part matching function name: first see if
363 		 * second part matches any parameter name.
364 		 */
365 		param = sql_fn_resolve_param_name(pinfo, name2, cref->location);
366 
367 		if (param)
368 		{
369 			/* Yes, so this is a parameter reference, no subfield */
370 			subfield = NULL;
371 		}
372 		else
373 		{
374 			/* No, so try to match as parameter name and subfield */
375 			param = sql_fn_resolve_param_name(pinfo, name1, cref->location);
376 		}
377 	}
378 	else
379 	{
380 		/* Single name, or parameter name followed by subfield */
381 		param = sql_fn_resolve_param_name(pinfo, name1, cref->location);
382 	}
383 
384 	if (!param)
385 		return NULL;			/* No match */
386 
387 	if (subfield)
388 	{
389 		/*
390 		 * Must be a reference to a field of a composite parameter; otherwise
391 		 * ParseFuncOrColumn will return NULL, and we'll fail back at the
392 		 * caller.
393 		 */
394 		param = ParseFuncOrColumn(pstate,
395 								  list_make1(subfield),
396 								  list_make1(param),
397 								  pstate->p_last_srf,
398 								  NULL,
399 								  false,
tts_heap_copyslot(TupleTableSlot * dstslot,TupleTableSlot * srcslot)400 								  cref->location);
401 	}
402 
403 	return param;
404 }
405 
406 /*
407  * sql_fn_param_ref		parser callback for ParamRefs ($n symbols)
408  */
409 static Node *
410 sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
411 {
412 	SQLFunctionParseInfoPtr pinfo = (SQLFunctionParseInfoPtr) pstate->p_ref_hook_state;
tts_heap_get_heap_tuple(TupleTableSlot * slot)413 	int			paramno = pref->number;
414 
415 	/* Check parameter number is valid */
416 	if (paramno <= 0 || paramno > pinfo->nargs)
417 		return NULL;			/* unknown parameter number */
418 
419 	return sql_fn_make_param(pinfo, paramno, pref->location);
420 }
421 
422 /*
423  * sql_fn_make_param		construct a Param node for the given paramno
424  */
tts_heap_copy_heap_tuple(TupleTableSlot * slot)425 static Node *
426 sql_fn_make_param(SQLFunctionParseInfoPtr pinfo,
427 				  int paramno, int location)
428 {
429 	Param	   *param;
430 
431 	param = makeNode(Param);
432 	param->paramkind = PARAM_EXTERN;
433 	param->paramid = paramno;
434 	param->paramtype = pinfo->argtypes[paramno - 1];
435 	param->paramtypmod = -1;
436 	param->paramcollid = get_typcollation(param->paramtype);
437 	param->location = location;
438 
439 	/*
440 	 * If we have a function input collation, allow it to override the
441 	 * type-derived collation for parameter symbols.  (XXX perhaps this should
442 	 * not happen if the type collation is not default?)
443 	 */
444 	if (OidIsValid(pinfo->collation) && OidIsValid(param->paramcollid))
445 		param->paramcollid = pinfo->collation;
446 
447 	return (Node *) param;
448 }
449 
450 /*
451  * Search for a function parameter of the given name; if there is one,
452  * construct and return a Param node for it.  If not, return NULL.
453  * Helper function for sql_fn_post_column_ref.
454  */
455 static Node *
456 sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo,
457 						  const char *paramname, int location)
458 {
459 	int			i;
460 
461 	if (pinfo->argnames == NULL)
462 		return NULL;
463 
464 	for (i = 0; i < pinfo->nargs; i++)
465 	{
466 		if (pinfo->argnames[i] && strcmp(pinfo->argnames[i], paramname) == 0)
467 			return sql_fn_make_param(pinfo, i + 1, location);
468 	}
469 
tts_minimal_init(TupleTableSlot * slot)470 	return NULL;
471 }
472 
473 /*
474  * Set up the per-query execution_state records for a SQL function.
475  *
476  * The input is a List of Lists of parsed and rewritten, but not planned,
477  * querytrees.  The sublist structure denotes the original query boundaries.
478  */
479 static List *
480 init_execution_state(List *queryTree_list,
481 					 SQLFunctionCachePtr fcache,
tts_minimal_release(TupleTableSlot * slot)482 					 bool lazyEvalOK)
483 {
484 	List	   *eslist = NIL;
485 	execution_state *lasttages = NULL;
486 	ListCell   *lc1;
487 
488 	foreach(lc1, queryTree_list)
489 	{
490 		List	   *qtlist = lfirst_node(List, lc1);
491 		execution_state *firstes = NULL;
492 		execution_state *preves = NULL;
493 		ListCell   *lc2;
494 
495 		foreach(lc2, qtlist)
496 		{
497 			Query	   *queryTree = lfirst_node(Query, lc2);
498 			PlannedStmt *stmt;
499 			execution_state *newes;
500 
501 			/* Plan the query if needed */
502 			if (queryTree->commandType == CMD_UTILITY)
503 			{
504 				/* Utility commands require no planning. */
505 				stmt = makeNode(PlannedStmt);
506 				stmt->commandType = CMD_UTILITY;
507 				stmt->canSetTag = queryTree->canSetTag;
508 				stmt->utilityStmt = queryTree->utilityStmt;
509 				stmt->stmt_location = queryTree->stmt_location;
510 				stmt->stmt_len = queryTree->stmt_len;
511 			}
512 			else
513 				stmt = pg_plan_query(queryTree,
514 									 fcache->src,
515 									 CURSOR_OPT_PARALLEL_OK,
516 									 NULL);
517 
518 			/*
519 			 * Precheck all commands for validity in a function.  This should
520 			 * generally match the restrictions spi.c applies.
521 			 */
522 			if (stmt->commandType == CMD_UTILITY)
523 			{
524 				if (IsA(stmt->utilityStmt, CopyStmt) &&
525 					((CopyStmt *) stmt->utilityStmt)->filename == NULL)
526 					ereport(ERROR,
527 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
528 							 errmsg("cannot COPY to/from client in a SQL function")));
529 
530 				if (IsA(stmt->utilityStmt, TransactionStmt))
531 					ereport(ERROR,
532 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
533 					/* translator: %s is a SQL statement name */
534 							 errmsg("%s is not allowed in a SQL function",
535 									CreateCommandName(stmt->utilityStmt))));
536 			}
537 
538 			if (fcache->readonly_func && !CommandIsReadOnly(stmt))
539 				ereport(ERROR,
540 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
541 				/* translator: %s is a SQL statement name */
542 						 errmsg("%s is not allowed in a non-volatile function",
543 								CreateCommandName((Node *) stmt))));
544 
545 			/* OK, build the execution_state for this query */
546 			newes = (execution_state *) palloc(sizeof(execution_state));
547 			if (preves)
548 				preves->next = newes;
549 			else
550 				firstes = newes;
551 
552 			newes->next = NULL;
553 			newes->status = F_EXEC_START;
554 			newes->setsResult = false;	/* might change below */
555 			newes->lazyEval = false;	/* might change below */
556 			newes->stmt = stmt;
557 			newes->qd = NULL;
558 
559 			if (queryTree->canSetTag)
560 				lasttages = newes;
561 
562 			preves = newes;
563 		}
564 
565 		eslist = lappend(eslist, firstes);
566 	}
567 
568 	/*
569 	 * Mark the last canSetTag query as delivering the function result; then,
570 	 * if it is a plain SELECT, mark it for lazy evaluation. If it's not a
571 	 * SELECT we must always run it to completion.
572 	 *
573 	 * Note: at some point we might add additional criteria for whether to use
574 	 * lazy eval.  However, we should prefer to use it whenever the function
575 	 * doesn't return set, since fetching more than one row is useless in that
576 	 * case.
577 	 *
578 	 * Note: don't set setsResult if the function returns VOID, as evidenced
579 	 * by not having made a junkfilter.  This ensures we'll throw away any
580 	 * output from the last statement in such a function.
581 	 */
582 	if (lasttages && fcache->junkFilter)
583 	{
584 		lasttages->setsResult = true;
585 		if (lazyEvalOK &&
586 			lasttages->stmt->commandType == CMD_SELECT &&
587 			!lasttages->stmt->hasModifyingCTE)
588 			fcache->lazyEval = lasttages->lazyEval = true;
589 	}
590 
591 	return eslist;
592 }
593 
594 /*
595  * Initialize the SQLFunctionCache for a SQL function
596  */
597 static void
tts_minimal_copy_heap_tuple(TupleTableSlot * slot)598 init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
599 {
600 	FmgrInfo   *finfo = fcinfo->flinfo;
601 	Oid			foid = finfo->fn_oid;
602 	MemoryContext fcontext;
603 	MemoryContext oldcontext;
604 	Oid			rettype;
605 	TupleDesc	rettupdesc;
606 	HeapTuple	procedureTuple;
607 	Form_pg_proc procedureStruct;
608 	SQLFunctionCachePtr fcache;
609 	List	   *raw_parsetree_list;
610 	List	   *queryTree_list;
611 	List	   *resulttlist;
612 	ListCell   *lc;
613 	Datum		tmp;
614 	bool		isNull;
615 
616 	/*
617 	 * Create memory context that holds all the SQLFunctionCache data.  It
618 	 * must be a child of whatever context holds the FmgrInfo.
619 	 */
620 	fcontext = AllocSetContextCreate(finfo->fn_mcxt,
621 									 "SQL function",
622 									 ALLOCSET_DEFAULT_SIZES);
623 
624 	oldcontext = MemoryContextSwitchTo(fcontext);
625 
626 	/*
627 	 * Create the struct proper, link it to fcontext and fn_extra.  Once this
628 	 * is done, we'll be able to recover the memory after failure, even if the
629 	 * FmgrInfo is long-lived.
630 	 */
631 	fcache = (SQLFunctionCachePtr) palloc0(sizeof(SQLFunctionCache));
632 	fcache->fcontext = fcontext;
633 	finfo->fn_extra = (void *) fcache;
634 
635 	/*
636 	 * get the procedure tuple corresponding to the given function Oid
637 	 */
638 	procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(foid));
639 	if (!HeapTupleIsValid(procedureTuple))
640 		elog(ERROR, "cache lookup failed for function %u", foid);
641 	procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
642 
643 	/*
644 	 * copy function name immediately for use by error reporting callback, and
645 	 * for use as memory context identifier
646 	 */
647 	fcache->fname = pstrdup(NameStr(procedureStruct->proname));
648 	MemoryContextSetIdentifier(fcontext, fcache->fname);
649 
650 	/*
651 	 * Resolve any polymorphism, obtaining the actual result type, and the
652 	 * corresponding tupdesc if it's a rowtype.
653 	 */
654 	(void) get_call_result_type(fcinfo, &rettype, &rettupdesc);
655 
656 	fcache->rettype = rettype;
657 
658 	/* Fetch the typlen and byval info for the result type */
659 	get_typlenbyval(rettype, &fcache->typlen, &fcache->typbyval);
660 
661 	/* Remember whether we're returning setof something */
662 	fcache->returnsSet = procedureStruct->proretset;
663 
664 	/* Remember if function is STABLE/IMMUTABLE */
665 	fcache->readonly_func =
666 		(procedureStruct->provolatile != PROVOLATILE_VOLATILE);
667 
668 	/*
669 	 * We need the actual argument types to pass to the parser.  Also make
670 	 * sure that parameter symbols are considered to have the function's
671 	 * resolved input collation.
672 	 */
673 	fcache->pinfo = prepare_sql_fn_parse_info(procedureTuple,
674 											  finfo->fn_expr,
675 											  collation);
676 
677 	/*
678 	 * And of course we need the function body text.
679 	 */
680 	tmp = SysCacheGetAttr(PROCOID,
681 						  procedureTuple,
682 						  Anum_pg_proc_prosrc,
683 						  &isNull);
684 	if (isNull)
685 		elog(ERROR, "null prosrc for function %u", foid);
686 	fcache->src = TextDatumGetCString(tmp);
687 
688 	/*
689 	 * Parse and rewrite the queries in the function text.  Use sublists to
690 	 * keep track of the original query boundaries.
691 	 *
692 	 * Note: since parsing and planning is done in fcontext, we will generate
693 	 * a lot of cruft that lives as long as the fcache does.  This is annoying
694 	 * but we'll not worry about it until the module is rewritten to use
695 	 * plancache.c.
696 	 */
697 	raw_parsetree_list = pg_parse_query(fcache->src);
698 
699 	queryTree_list = NIL;
700 	foreach(lc, raw_parsetree_list)
701 	{
702 		RawStmt    *parsetree = lfirst_node(RawStmt, lc);
703 		List	   *queryTree_sublist;
704 
705 		queryTree_sublist = pg_analyze_and_rewrite_params(parsetree,
706 														  fcache->src,
707 														  (ParserSetupHook) sql_fn_parser_setup,
708 														  fcache->pinfo,
709 														  NULL);
710 		queryTree_list = lappend(queryTree_list, queryTree_sublist);
711 	}
712 
713 	/*
714 	 * Check that there are no statements we don't want to allow.
715 	 */
716 	check_sql_fn_statements(queryTree_list);
717 
718 	/*
719 	 * Check that the function returns the type it claims to.  Although in
720 	 * simple cases this was already done when the function was defined, we
721 	 * have to recheck because database objects used in the function's queries
722 	 * might have changed type.  We'd have to recheck anyway if the function
723 	 * had any polymorphic arguments.  Moreover, check_sql_fn_retval takes
724 	 * care of injecting any required column type coercions.  (But we don't
725 	 * ask it to insert nulls for dropped columns; the junkfilter handles
726 	 * that.)
727 	 *
728 	 * Note: we set fcache->returnsTuple according to whether we are returning
729 	 * the whole tuple result or just a single column.  In the latter case we
730 	 * clear returnsTuple because we need not act different from the scalar
731 	 * result case, even if it's a rowtype column.  (However, we have to force
732 	 * lazy eval mode in that case; otherwise we'd need extra code to expand
733 	 * the rowtype column into multiple columns, since we have no way to
734 	 * notify the caller that it should do that.)
735 	 */
736 	fcache->returnsTuple = check_sql_fn_retval(queryTree_list,
737 											   rettype,
738 											   rettupdesc,
739 											   false,
740 											   &resulttlist);
741 
742 	/*
743 	 * Construct a JunkFilter we can use to coerce the returned rowtype to the
744 	 * desired form, unless the result type is VOID, in which case there's
745 	 * nothing to coerce to.  (XXX Frequently, the JunkFilter isn't doing
746 	 * anything very interesting, but much of this module expects it to be
747 	 * there anyway.)
748 	 */
749 	if (rettype != VOIDOID)
750 	{
751 		TupleTableSlot *slot = MakeSingleTupleTableSlot(NULL,
752 														&TTSOpsMinimalTuple);
753 
754 		/*
755 		 * If the result is composite, *and* we are returning the whole tuple
756 		 * result, we need to insert nulls for any dropped columns.  In the
757 		 * single-column-result case, there might be dropped columns within
758 		 * the composite column value, but it's not our problem here.  There
759 		 * should be no resjunk entries in resulttlist, so in the second case
760 		 * the JunkFilter is certainly a no-op.
761 		 */
762 		if (rettupdesc && fcache->returnsTuple)
763 			fcache->junkFilter = ExecInitJunkFilterConversion(resulttlist,
764 															  rettupdesc,
765 															  slot);
766 		else
767 			fcache->junkFilter = ExecInitJunkFilter(resulttlist, slot);
768 	}
769 
770 	if (fcache->returnsTuple)
771 	{
772 		/* Make sure output rowtype is properly blessed */
773 		BlessTupleDesc(fcache->junkFilter->jf_resultSlot->tts_tupleDescriptor);
774 	}
775 	else if (fcache->returnsSet && type_is_rowtype(fcache->rettype))
776 	{
777 		/*
778 		 * Returning rowtype as if it were scalar --- materialize won't work.
779 		 * Right now it's sufficient to override any caller preference for
780 		 * materialize mode, but to add more smarts in init_execution_state
781 		 * about this, we'd probably need a three-way flag instead of bool.
782 		 */
783 		lazyEvalOK = true;
784 	}
785 
786 	/* Finally, plan the queries */
787 	fcache->func_state = init_execution_state(queryTree_list,
788 											  fcache,
789 											  lazyEvalOK);
790 
791 	/* Mark fcache with time of creation to show it's valid */
792 	fcache->lxid = MyProc->lxid;
793 	fcache->subxid = GetCurrentSubTransactionId();
794 
795 	ReleaseSysCache(procedureTuple);
796 
797 	MemoryContextSwitchTo(oldcontext);
798 }
799 
800 /* Start up execution of one execution_state node */
801 static void
802 postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
803 {
804 	DestReceiver *dest;
805 
806 	Assert(es->qd == NULL);
807 
808 	/* Caller should have ensured a suitable snapshot is active */
809 	Assert(ActiveSnapshotSet());
810 
811 	/*
812 	 * If this query produces the function result, send its output to the
813 	 * tuplestore; else discard any output.
814 	 */
815 	if (es->setsResult)
816 	{
817 		DR_sqlfunction *myState;
818 
819 		dest = CreateDestReceiver(DestSQLFunction);
tts_buffer_heap_get_heap_tuple(TupleTableSlot * slot)820 		/* pass down the needed info to the dest receiver routines */
821 		myState = (DR_sqlfunction *) dest;
822 		Assert(myState->pub.mydest == DestSQLFunction);
823 		myState->tstore = fcache->tstore;
824 		myState->cxt = CurrentMemoryContext;
825 		myState->filter = fcache->junkFilter;
826 	}
827 	else
828 		dest = None_Receiver;
829 
830 	es->qd = CreateQueryDesc(es->stmt,
831 							 fcache->src,
832 							 GetActiveSnapshot(),
tts_buffer_heap_copy_heap_tuple(TupleTableSlot * slot)833 							 InvalidSnapshot,
834 							 dest,
835 							 fcache->paramLI,
836 							 es->qd ? es->qd->queryEnv : NULL,
837 							 0);
838 
839 	/* Utility commands don't need Executor. */
840 	if (es->qd->operation != CMD_UTILITY)
841 	{
842 		/*
843 		 * In lazyEval mode, do not let the executor set up an AfterTrigger
844 		 * context.  This is necessary not just an optimization, because we
845 		 * mustn't exit from the function execution with a stacked
tts_buffer_heap_copy_minimal_tuple(TupleTableSlot * slot)846 		 * AfterTrigger level still active.  We are careful not to select
847 		 * lazyEval mode for any statement that could possibly queue triggers.
848 		 */
849 		int			eflags;
850 
851 		if (es->lazyEval)
852 			eflags = EXEC_FLAG_SKIP_TRIGGERS;
853 		else
854 			eflags = 0;			/* default run-to-completion flags */
855 		ExecutorStart(es->qd, eflags);
856 	}
857 
858 	es->status = F_EXEC_RUN;
tts_buffer_heap_store_tuple(TupleTableSlot * slot,HeapTuple tuple,Buffer buffer,bool transfer_pin)859 }
860 
861 /* Run one execution_state; either to completion or to first result row */
862 /* Returns true if we ran to completion */
863 static bool
864 postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
865 {
866 	bool		result;
867 
868 	if (es->qd->operation == CMD_UTILITY)
869 	{
870 		ProcessUtility(es->qd->plannedstmt,
871 					   fcache->src,
872 					   PROCESS_UTILITY_QUERY,
873 					   es->qd->params,
874 					   es->qd->queryEnv,
875 					   es->qd->dest,
876 					   NULL);
877 		result = true;			/* never stops early */
878 	}
879 	else
880 	{
881 		/* Run regular commands to completion unless lazyEval */
882 		uint64		count = (es->lazyEval) ? 1 : 0;
883 
884 		ExecutorRun(es->qd, ForwardScanDirection, count, !fcache->returnsSet || !es->lazyEval);
885 
886 		/*
887 		 * If we requested run to completion OR there was no tuple returned,
888 		 * command must be complete.
889 		 */
890 		result = (count == 0 || es->qd->estate->es_processed == 0);
891 	}
892 
893 	return result;
894 }
895 
896 /* Shut down execution of one execution_state node */
897 static void
898 postquel_end(execution_state *es)
899 {
900 	/* mark status done to ensure we don't do ExecutorEnd twice */
901 	es->status = F_EXEC_DONE;
902 
903 	/* Utility commands don't need Executor. */
904 	if (es->qd->operation != CMD_UTILITY)
905 	{
906 		ExecutorFinish(es->qd);
907 		ExecutorEnd(es->qd);
908 	}
909 
910 	es->qd->dest->rDestroy(es->qd->dest);
911 
912 	FreeQueryDesc(es->qd);
913 	es->qd = NULL;
914 }
915 
916 /* Build ParamListInfo array representing current arguments */
917 static void
918 postquel_sub_params(SQLFunctionCachePtr fcache,
919 					FunctionCallInfo fcinfo)
920 {
921 	int			nargs = fcinfo->nargs;
922 
923 	if (nargs > 0)
924 	{
slot_deform_heap_tuple(TupleTableSlot * slot,HeapTuple tuple,uint32 * offp,int natts)925 		ParamListInfo paramLI;
926 
927 		if (fcache->paramLI == NULL)
928 		{
929 			paramLI = makeParamList(nargs);
930 			fcache->paramLI = paramLI;
931 		}
932 		else
933 		{
934 			paramLI = fcache->paramLI;
935 			Assert(paramLI->numParams == nargs);
936 		}
937 
938 		for (int i = 0; i < nargs; i++)
939 		{
940 			ParamExternData *prm = &paramLI->params[i];
941 
942 			prm->value = fcinfo->args[i].value;
943 			prm->isnull = fcinfo->args[i].isnull;
944 			prm->pflags = 0;
945 			prm->ptype = fcache->pinfo->argtypes[i];
946 		}
947 	}
948 	else
949 		fcache->paramLI = NULL;
950 }
951 
952 /*
953  * Extract the SQL function's value from a single result row.  This is used
954  * both for scalar (non-set) functions and for each row of a lazy-eval set
955  * result.
956  */
957 static Datum
958 postquel_get_single_result(TupleTableSlot *slot,
959 						   FunctionCallInfo fcinfo,
960 						   SQLFunctionCachePtr fcache,
961 						   MemoryContext resultcontext)
962 {
963 	Datum		value;
964 	MemoryContext oldcontext;
965 
966 	/*
967 	 * Set up to return the function value.  For pass-by-reference datatypes,
968 	 * be sure to allocate the result in resultcontext, not the current memory
969 	 * context (which has query lifespan).  We can't leave the data in the
970 	 * TupleTableSlot because we intend to clear the slot before returning.
971 	 */
972 	oldcontext = MemoryContextSwitchTo(resultcontext);
973 
974 	if (fcache->returnsTuple)
975 	{
976 		/* We must return the whole tuple as a Datum. */
977 		fcinfo->isnull = false;
978 		value = ExecFetchSlotHeapTupleDatum(slot);
979 	}
980 	else
981 	{
982 		/*
983 		 * Returning a scalar, which we have to extract from the first column
984 		 * of the SELECT result, and then copy into result context if needed.
985 		 */
986 		value = slot_getattr(slot, 1, &(fcinfo->isnull));
987 
988 		if (!fcinfo->isnull)
989 			value = datumCopy(value, fcache->typbyval, fcache->typlen);
990 	}
991 
992 	MemoryContextSwitchTo(oldcontext);
993 
994 	return value;
995 }
996 
997 /*
998  * fmgr_sql: function call manager for SQL functions
999  */
1000 Datum
1001 fmgr_sql(PG_FUNCTION_ARGS)
1002 {
1003 	SQLFunctionCachePtr fcache;
1004 	ErrorContextCallback sqlerrcontext;
1005 	MemoryContext oldcontext;
1006 	bool		randomAccess;
1007 	bool		lazyEvalOK;
1008 	bool		is_first;
1009 	bool		pushed_snapshot;
1010 	execution_state *es;
1011 	TupleTableSlot *slot;
1012 	Datum		result;
1013 	List	   *eslist;
1014 	ListCell   *eslc;
1015 
1016 	/*
1017 	 * Setup error traceback support for ereport()
1018 	 */
1019 	sqlerrcontext.callback = sql_exec_error_callback;
1020 	sqlerrcontext.arg = fcinfo->flinfo;
1021 	sqlerrcontext.previous = error_context_stack;
1022 	error_context_stack = &sqlerrcontext;
1023 
1024 	/* Check call context */
1025 	if (fcinfo->flinfo->fn_retset)
1026 	{
1027 		ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1028 
1029 		/*
1030 		 * For simplicity, we require callers to support both set eval modes.
1031 		 * There are cases where we must use one or must use the other, and
1032 		 * it's not really worthwhile to postpone the check till we know. But
1033 		 * note we do not require caller to provide an expectedDesc.
1034 		 */
1035 		if (!rsi || !IsA(rsi, ReturnSetInfo) ||
1036 			(rsi->allowedModes & SFRM_ValuePerCall) == 0 ||
1037 			(rsi->allowedModes & SFRM_Materialize) == 0)
1038 			ereport(ERROR,
1039 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1040 					 errmsg("set-valued function called in context that cannot accept a set")));
1041 		randomAccess = rsi->allowedModes & SFRM_Materialize_Random;
1042 		lazyEvalOK = !(rsi->allowedModes & SFRM_Materialize_Preferred);
1043 	}
1044 	else
1045 	{
1046 		randomAccess = false;
1047 		lazyEvalOK = true;
1048 	}
1049 
1050 	/*
1051 	 * Initialize fcache (build plans) if first time through; or re-initialize
1052 	 * if the cache is stale.
1053 	 */
1054 	fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
1055 
1056 	if (fcache != NULL)
1057 	{
1058 		if (fcache->lxid != MyProc->lxid ||
1059 			!SubTransactionIsActive(fcache->subxid))
1060 		{
1061 			/* It's stale; unlink and delete */
1062 			fcinfo->flinfo->fn_extra = NULL;
1063 			MemoryContextDelete(fcache->fcontext);
1064 			fcache = NULL;
1065 		}
1066 	}
1067 
1068 	if (fcache == NULL)
1069 	{
1070 		init_sql_fcache(fcinfo, PG_GET_COLLATION(), lazyEvalOK);
1071 		fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
1072 	}
1073 
1074 	/*
1075 	 * Switch to context in which the fcache lives.  This ensures that our
1076 	 * tuplestore etc will have sufficient lifetime.  The sub-executor is
1077 	 * responsible for deleting per-tuple information.  (XXX in the case of a
1078 	 * long-lived FmgrInfo, this policy represents more memory leakage, but
1079 	 * it's not entirely clear where to keep stuff instead.)
1080 	 */
1081 	oldcontext = MemoryContextSwitchTo(fcache->fcontext);
1082 
1083 	/*
1084 	 * Find first unfinished query in function, and note whether it's the
1085 	 * first query.
1086 	 */
1087 	eslist = fcache->func_state;
1088 	es = NULL;
1089 	is_first = true;
1090 	foreach(eslc, eslist)
1091 	{
1092 		es = (execution_state *) lfirst(eslc);
1093 
1094 		while (es && es->status == F_EXEC_DONE)
1095 		{
1096 			is_first = false;
1097 			es = es->next;
1098 		}
1099 
1100 		if (es)
1101 			break;
1102 	}
1103 
1104 	/*
1105 	 * Convert params to appropriate format if starting a fresh execution. (If
1106 	 * continuing execution, we can re-use prior params.)
1107 	 */
1108 	if (is_first && es && es->status == F_EXEC_START)
1109 		postquel_sub_params(fcache, fcinfo);
1110 
1111 	/*
MakeTupleTableSlot(TupleDesc tupleDesc,const TupleTableSlotOps * tts_ops)1112 	 * Build tuplestore to hold results, if we don't have one already. Note
1113 	 * it's in the query-lifespan context.
1114 	 */
1115 	if (!fcache->tstore)
1116 		fcache->tstore = tuplestore_begin_heap(randomAccess, false, work_mem);
1117 
1118 	/*
1119 	 * Execute each command in the function one after another until we either
1120 	 * run out of commands or get a result row from a lazily-evaluated SELECT.
1121 	 *
1122 	 * Notes about snapshot management:
1123 	 *
1124 	 * In a read-only function, we just use the surrounding query's snapshot.
1125 	 *
1126 	 * In a non-read-only function, we rely on the fact that we'll never
1127 	 * suspend execution between queries of the function: the only reason to
1128 	 * suspend execution before completion is if we are returning a row from a
1129 	 * lazily-evaluated SELECT.  So, when first entering this loop, we'll
1130 	 * either start a new query (and push a fresh snapshot) or re-establish
1131 	 * the active snapshot from the existing query descriptor.  If we need to
1132 	 * start a new query in a subsequent execution of the loop, either we need
1133 	 * a fresh snapshot (and pushed_snapshot is false) or the existing
1134 	 * snapshot is on the active stack and we can just bump its command ID.
1135 	 */
1136 	pushed_snapshot = false;
1137 	while (es)
1138 	{
1139 		bool		completed;
1140 
1141 		if (es->status == F_EXEC_START)
1142 		{
1143 			/*
1144 			 * If not read-only, be sure to advance the command counter for
1145 			 * each command, so that all work to date in this transaction is
1146 			 * visible.  Take a new snapshot if we don't have one yet,
1147 			 * otherwise just bump the command ID in the existing snapshot.
1148 			 */
1149 			if (!fcache->readonly_func)
1150 			{
1151 				CommandCounterIncrement();
1152 				if (!pushed_snapshot)
1153 				{
1154 					PushActiveSnapshot(GetTransactionSnapshot());
1155 					pushed_snapshot = true;
1156 				}
1157 				else
1158 					UpdateActiveSnapshotCommandId();
1159 			}
1160 
1161 			postquel_start(es, fcache);
1162 		}
1163 		else if (!fcache->readonly_func && !pushed_snapshot)
1164 		{
1165 			/* Re-establish active snapshot when re-entering function */
1166 			PushActiveSnapshot(es->qd->snapshot);
1167 			pushed_snapshot = true;
1168 		}
1169 
1170 		completed = postquel_getnext(es, fcache);
ExecAllocTableSlot(List ** tupleTable,TupleDesc desc,const TupleTableSlotOps * tts_ops)1171 
1172 		/*
1173 		 * If we ran the command to completion, we can shut it down now. Any
1174 		 * row(s) we need to return are safely stashed in the tuplestore, and
1175 		 * we want to be sure that, for example, AFTER triggers get fired
1176 		 * before we return anything.  Also, if the function doesn't return
1177 		 * set, we can shut it down anyway because it must be a SELECT and we
1178 		 * don't care about fetching any more result rows.
1179 		 */
1180 		if (completed || !fcache->returnsSet)
1181 			postquel_end(es);
1182 
1183 		/*
1184 		 * Break from loop if we didn't shut down (implying we got a
1185 		 * lazily-evaluated row).  Otherwise we'll press on till the whole
1186 		 * function is done, relying on the tuplestore to keep hold of the
1187 		 * data to eventually be returned.  This is necessary since an
1188 		 * INSERT/UPDATE/DELETE RETURNING that sets the result might be
1189 		 * followed by additional rule-inserted commands, and we want to
1190 		 * finish doing all those commands before we return anything.
ExecResetTupleTable(List * tupleTable,bool shouldFree)1191 		 */
1192 		if (es->status != F_EXEC_DONE)
1193 			break;
1194 
1195 		/*
1196 		 * Advance to next execution_state, which might be in the next list.
1197 		 */
1198 		es = es->next;
1199 		while (!es)
1200 		{
1201 			eslc = lnext(eslist, eslc);
1202 			if (!eslc)
1203 				break;			/* end of function */
1204 
1205 			es = (execution_state *) lfirst(eslc);
1206 
1207 			/*
1208 			 * Flush the current snapshot so that we will take a new one for
1209 			 * the new query list.  This ensures that new snaps are taken at
1210 			 * original-query boundaries, matching the behavior of interactive
1211 			 * execution.
1212 			 */
1213 			if (pushed_snapshot)
1214 			{
1215 				PopActiveSnapshot();
1216 				pushed_snapshot = false;
1217 			}
1218 		}
1219 	}
1220 
1221 	/*
1222 	 * The tuplestore now contains whatever row(s) we are supposed to return.
1223 	 */
1224 	if (fcache->returnsSet)
1225 	{
1226 		ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1227 
1228 		if (es)
1229 		{
1230 			/*
1231 			 * If we stopped short of being done, we must have a lazy-eval
1232 			 * row.
1233 			 */
1234 			Assert(es->lazyEval);
1235 			/* Re-use the junkfilter's output slot to fetch back the tuple */
1236 			Assert(fcache->junkFilter);
1237 			slot = fcache->junkFilter->jf_resultSlot;
MakeSingleTupleTableSlot(TupleDesc tupdesc,const TupleTableSlotOps * tts_ops)1238 			if (!tuplestore_gettupleslot(fcache->tstore, true, false, slot))
1239 				elog(ERROR, "failed to fetch lazy-eval tuple");
1240 			/* Extract the result as a datum, and copy out from the slot */
1241 			result = postquel_get_single_result(slot, fcinfo,
1242 												fcache, oldcontext);
1243 			/* Clear the tuplestore, but keep it for next time */
1244 			/* NB: this might delete the slot's content, but we don't care */
1245 			tuplestore_clear(fcache->tstore);
1246 
1247 			/*
1248 			 * Let caller know we're not finished.
1249 			 */
1250 			rsi->isDone = ExprMultipleResult;
1251 
1252 			/*
1253 			 * Ensure we will get shut down cleanly if the exprcontext is not
ExecDropSingleTupleTableSlot(TupleTableSlot * slot)1254 			 * run to completion.
1255 			 */
1256 			if (!fcache->shutdown_reg)
1257 			{
1258 				RegisterExprContextCallback(rsi->econtext,
1259 											ShutdownSQLFunction,
1260 											PointerGetDatum(fcache));
1261 				fcache->shutdown_reg = true;
1262 			}
1263 		}
1264 		else if (fcache->lazyEval)
1265 		{
1266 			/*
1267 			 * We are done with a lazy evaluation.  Clean up.
1268 			 */
1269 			tuplestore_clear(fcache->tstore);
1270 
1271 			/*
1272 			 * Let caller know we're finished.
1273 			 */
1274 			rsi->isDone = ExprEndResult;
1275 
1276 			fcinfo->isnull = true;
1277 			result = (Datum) 0;
1278 
1279 			/* Deregister shutdown callback, if we made one */
1280 			if (fcache->shutdown_reg)
1281 			{
1282 				UnregisterExprContextCallback(rsi->econtext,
1283 											  ShutdownSQLFunction,
1284 											  PointerGetDatum(fcache));
1285 				fcache->shutdown_reg = false;
1286 			}
1287 		}
1288 		else
ExecSetSlotDescriptor(TupleTableSlot * slot,TupleDesc tupdesc)1289 		{
1290 			/*
1291 			 * We are done with a non-lazy evaluation.  Return whatever is in
1292 			 * the tuplestore.  (It is now caller's responsibility to free the
1293 			 * tuplestore when done.)
1294 			 */
1295 			rsi->returnMode = SFRM_Materialize;
1296 			rsi->setResult = fcache->tstore;
1297 			fcache->tstore = NULL;
1298 			/* must copy desc because execSRF.c will free it */
1299 			if (fcache->junkFilter)
1300 				rsi->setDesc = CreateTupleDescCopy(fcache->junkFilter->jf_cleanTupType);
1301 
1302 			fcinfo->isnull = true;
1303 			result = (Datum) 0;
1304 
1305 			/* Deregister shutdown callback, if we made one */
1306 			if (fcache->shutdown_reg)
1307 			{
1308 				UnregisterExprContextCallback(rsi->econtext,
1309 											  ShutdownSQLFunction,
1310 											  PointerGetDatum(fcache));
1311 				fcache->shutdown_reg = false;
1312 			}
1313 		}
1314 	}
1315 	else
1316 	{
1317 		/*
1318 		 * Non-set function.  If we got a row, return it; else return NULL.
1319 		 */
1320 		if (fcache->junkFilter)
1321 		{
1322 			/* Re-use the junkfilter's output slot to fetch back the tuple */
1323 			slot = fcache->junkFilter->jf_resultSlot;
1324 			if (tuplestore_gettupleslot(fcache->tstore, true, false, slot))
1325 				result = postquel_get_single_result(slot, fcinfo,
1326 													fcache, oldcontext);
1327 			else
1328 			{
1329 				fcinfo->isnull = true;
1330 				result = (Datum) 0;
1331 			}
1332 		}
1333 		else
1334 		{
1335 			/* Should only get here for VOID functions and procedures */
1336 			Assert(fcache->rettype == VOIDOID);
1337 			fcinfo->isnull = true;
1338 			result = (Datum) 0;
1339 		}
1340 
1341 		/* Clear the tuplestore, but keep it for next time */
1342 		tuplestore_clear(fcache->tstore);
1343 	}
1344 
1345 	/* Pop snapshot if we have pushed one */
1346 	if (pushed_snapshot)
1347 		PopActiveSnapshot();
1348 
1349 	/*
1350 	 * If we've gone through every command in the function, we are done. Reset
1351 	 * the execution states to start over again on next call.
ExecStoreHeapTuple(HeapTuple tuple,TupleTableSlot * slot,bool shouldFree)1352 	 */
1353 	if (es == NULL)
1354 	{
1355 		foreach(eslc, fcache->func_state)
1356 		{
1357 			es = (execution_state *) lfirst(eslc);
1358 			while (es)
1359 			{
1360 				es->status = F_EXEC_START;
1361 				es = es->next;
1362 			}
1363 		}
1364 	}
1365 
1366 	error_context_stack = sqlerrcontext.previous;
1367 
1368 	MemoryContextSwitchTo(oldcontext);
1369 
1370 	return result;
1371 }
1372 
1373 
1374 /*
1375  * error context callback to let us supply a call-stack traceback
1376  */
1377 static void
1378 sql_exec_error_callback(void *arg)
1379 {
1380 	FmgrInfo   *flinfo = (FmgrInfo *) arg;
1381 	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) flinfo->fn_extra;
1382 	int			syntaxerrposition;
1383 
1384 	/*
1385 	 * We can do nothing useful if init_sql_fcache() didn't get as far as
1386 	 * saving the function name
1387 	 */
1388 	if (fcache == NULL || fcache->fname == NULL)
1389 		return;
1390 
1391 	/*
ExecStoreBufferHeapTuple(HeapTuple tuple,TupleTableSlot * slot,Buffer buffer)1392 	 * If there is a syntax error position, convert to internal syntax error
1393 	 */
1394 	syntaxerrposition = geterrposition();
1395 	if (syntaxerrposition > 0 && fcache->src != NULL)
1396 	{
1397 		errposition(0);
1398 		internalerrposition(syntaxerrposition);
1399 		internalerrquery(fcache->src);
1400 	}
1401 
1402 	/*
1403 	 * Try to determine where in the function we failed.  If there is a query
1404 	 * with non-null QueryDesc, finger it.  (We check this rather than looking
1405 	 * for F_EXEC_RUN state, so that errors during ExecutorStart or
1406 	 * ExecutorEnd are blamed on the appropriate query; see postquel_start and
1407 	 * postquel_end.)
1408 	 */
1409 	if (fcache->func_state)
1410 	{
1411 		execution_state *es;
1412 		int			query_num;
1413 		ListCell   *lc;
1414 
1415 		es = NULL;
1416 		query_num = 1;
1417 		foreach(lc, fcache->func_state)
ExecStorePinnedBufferHeapTuple(HeapTuple tuple,TupleTableSlot * slot,Buffer buffer)1418 		{
1419 			es = (execution_state *) lfirst(lc);
1420 			while (es)
1421 			{
1422 				if (es->qd)
1423 				{
1424 					errcontext("SQL function \"%s\" statement %d",
1425 							   fcache->fname, query_num);
1426 					break;
1427 				}
1428 				es = es->next;
1429 			}
1430 			if (es)
1431 				break;
1432 			query_num++;
1433 		}
1434 		if (es == NULL)
1435 		{
1436 			/*
1437 			 * couldn't identify a running query; might be function entry,
1438 			 * function exit, or between queries.
1439 			 */
1440 			errcontext("SQL function \"%s\"", fcache->fname);
1441 		}
1442 	}
1443 	else
1444 	{
1445 		/*
ExecStoreMinimalTuple(MinimalTuple mtup,TupleTableSlot * slot,bool shouldFree)1446 		 * Assume we failed during init_sql_fcache().  (It's possible that the
1447 		 * function actually has an empty body, but in that case we may as
1448 		 * well report all errors as being "during startup".)
1449 		 */
1450 		errcontext("SQL function \"%s\" during startup", fcache->fname);
1451 	}
1452 }
1453 
1454 
1455 /*
1456  * callback function in case a function-returning-set needs to be shut down
1457  * before it has been run to completion
1458  */
1459 static void
1460 ShutdownSQLFunction(Datum arg)
1461 {
1462 	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) DatumGetPointer(arg);
1463 	execution_state *es;
1464 	ListCell   *lc;
1465 
1466 	foreach(lc, fcache->func_state)
1467 	{
1468 		es = (execution_state *) lfirst(lc);
ExecForceStoreHeapTuple(HeapTuple tuple,TupleTableSlot * slot,bool shouldFree)1469 		while (es)
1470 		{
1471 			/* Shut down anything still running */
1472 			if (es->status == F_EXEC_RUN)
1473 			{
1474 				/* Re-establish active snapshot for any called functions */
1475 				if (!fcache->readonly_func)
1476 					PushActiveSnapshot(es->qd->snapshot);
1477 
1478 				postquel_end(es);
1479 
1480 				if (!fcache->readonly_func)
1481 					PopActiveSnapshot();
1482 			}
1483 
1484 			/* Reset states to START in case we're called again */
1485 			es->status = F_EXEC_START;
1486 			es = es->next;
1487 		}
1488 	}
1489 
1490 	/* Release tuplestore if we have one */
1491 	if (fcache->tstore)
1492 		tuplestore_end(fcache->tstore);
1493 	fcache->tstore = NULL;
1494 
1495 	/* execUtils will deregister the callback... */
1496 	fcache->shutdown_reg = false;
1497 }
1498 
1499 /*
1500  * check_sql_fn_statements
1501  *
1502  * Check statements in an SQL function.  Error out if there is anything that
1503  * is not acceptable.
1504  */
1505 void
1506 check_sql_fn_statements(List *queryTreeLists)
1507 {
1508 	ListCell   *lc;
1509 
1510 	/* We are given a list of sublists of Queries */
1511 	foreach(lc, queryTreeLists)
ExecForceStoreMinimalTuple(MinimalTuple mtup,TupleTableSlot * slot,bool shouldFree)1512 	{
1513 		List	   *sublist = lfirst_node(List, lc);
1514 		ListCell   *lc2;
1515 
1516 		foreach(lc2, sublist)
1517 		{
1518 			Query	   *query = lfirst_node(Query, lc2);
1519 
1520 			/*
1521 			 * Disallow procedures with output arguments.  The current
1522 			 * implementation would just throw the output values away, unless
1523 			 * the statement is the last one.  Per SQL standard, we should
1524 			 * assign the output values by name.  By disallowing this here, we
1525 			 * preserve an opportunity for future improvement.
1526 			 */
1527 			if (query->commandType == CMD_UTILITY &&
1528 				IsA(query->utilityStmt, CallStmt))
1529 			{
1530 				CallStmt   *stmt = castNode(CallStmt, query->utilityStmt);
1531 				HeapTuple	tuple;
1532 				int			numargs;
1533 				Oid		   *argtypes;
1534 				char	  **argnames;
1535 				char	   *argmodes;
1536 				int			i;
1537 
1538 				tuple = SearchSysCache1(PROCOID,
1539 										ObjectIdGetDatum(stmt->funcexpr->funcid));
1540 				if (!HeapTupleIsValid(tuple))
1541 					elog(ERROR, "cache lookup failed for function %u",
1542 						 stmt->funcexpr->funcid);
1543 				numargs = get_func_arg_info(tuple,
1544 											&argtypes, &argnames, &argmodes);
1545 				ReleaseSysCache(tuple);
1546 
1547 				for (i = 0; i < numargs; i++)
1548 				{
1549 					if (argmodes && (argmodes[i] == PROARGMODE_INOUT ||
1550 									 argmodes[i] == PROARGMODE_OUT))
1551 						ereport(ERROR,
1552 								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1553 								 errmsg("calling procedures with output arguments is not supported in SQL functions")));
1554 				}
1555 			}
1556 		}
1557 	}
1558 }
1559 
1560 /*
1561  * check_sql_fn_retval()
1562  *		Check return value of a list of lists of sql parse trees.
1563  *
1564  * The return value of a sql function is the value returned by the last
1565  * canSetTag query in the function.  We do some ad-hoc type checking and
1566  * coercion here to ensure that the function returns what it's supposed to.
1567  * Note that we may actually modify the last query to make it match!
1568  *
1569  * This function returns true if the sql function returns the entire tuple
1570  * result of its final statement, or false if it returns just the first column
1571  * result of that statement.  It throws an error if the final statement doesn't
1572  * return the right type at all.
1573  *
1574  * Note that because we allow "SELECT rowtype_expression", the result can be
1575  * false even when the declared function return type is a rowtype.
ExecStoreAllNullTuple(TupleTableSlot * slot)1576  *
1577  * For a polymorphic function the passed rettype must be the actual resolved
1578  * output type of the function.  (This means we can't check the type during
1579  * function definition of a polymorphic function.)  If we do see a polymorphic
1580  * rettype we'll throw an error, saying it is not a supported rettype.
1581  *
1582  * If the function returns composite, the passed rettupdesc should describe
1583  * the expected output.  If rettupdesc is NULL, we can't verify that the
1584  * output matches; that should only happen in fmgr_sql_validator(), or when
1585  * the function returns RECORD and the caller doesn't actually care which
1586  * composite type it is.
1587  *
1588  * (Typically, rettype and rettupdesc are computed by get_call_result_type
1589  * or a sibling function.)
1590  *
1591  * In addition to coercing individual output columns, we can modify the
1592  * output to include dummy NULL columns for any dropped columns appearing
1593  * in rettupdesc.  This is done only if the caller asks for it.
1594  *
1595  * If resultTargetList isn't NULL, then *resultTargetList is set to the
1596  * targetlist that defines the final statement's result.  Exception: if the
1597  * function is defined to return VOID then *resultTargetList is set to NIL.
1598  */
1599 bool
1600 check_sql_fn_retval(List *queryTreeLists,
1601 					Oid rettype, TupleDesc rettupdesc,
1602 					bool insertDroppedCols,
1603 					List **resultTargetList)
1604 {
1605 	bool		is_tuple_result = false;
1606 	Query	   *parse;
1607 	ListCell   *parse_cell;
1608 	List	   *tlist;
1609 	int			tlistlen;
1610 	bool		tlist_is_modifiable;
1611 	char		fn_typtype;
1612 	List	   *upper_tlist = NIL;
1613 	bool		upper_tlist_nontrivial = false;
1614 	ListCell   *lc;
1615 
1616 	if (resultTargetList)
1617 		*resultTargetList = NIL;	/* initialize in case of VOID result */
1618 
1619 	/*
1620 	 * If it's declared to return VOID, we don't care what's in the function.
1621 	 * (This takes care of the procedure case, as well.)
1622 	 */
1623 	if (rettype == VOIDOID)
1624 		return false;
1625 
1626 	/*
1627 	 * Find the last canSetTag query in the function body (which is presented
1628 	 * to us as a list of sublists of Query nodes).  This isn't necessarily
1629 	 * the last parsetree, because rule rewriting can insert queries after
1630 	 * what the user wrote.  Note that it might not even be in the last
1631 	 * sublist, for example if the last query rewrites to DO INSTEAD NOTHING.
1632 	 * (It might not be unreasonable to throw an error in such a case, but
1633 	 * this is the historical behavior and it doesn't seem worth changing.)
1634 	 */
1635 	parse = NULL;
1636 	parse_cell = NULL;
1637 	foreach(lc, queryTreeLists)
1638 	{
1639 		List	   *sublist = lfirst_node(List, lc);
1640 		ListCell   *lc2;
1641 
1642 		foreach(lc2, sublist)
1643 		{
1644 			Query	   *q = lfirst_node(Query, lc2);
1645 
1646 			if (q->canSetTag)
1647 			{
1648 				parse = q;
1649 				parse_cell = lc2;
1650 			}
1651 		}
1652 	}
1653 
1654 	/*
1655 	 * If it's a plain SELECT, it returns whatever the targetlist says.
1656 	 * Otherwise, if it's INSERT/UPDATE/DELETE with RETURNING, it returns
1657 	 * that. Otherwise, the function return type must be VOID.
1658 	 *
1659 	 * Note: eventually replace this test with QueryReturnsTuples?	We'd need
1660 	 * a more general method of determining the output type, though.  Also, it
1661 	 * seems too dangerous to consider FETCH or EXECUTE as returning a
1662 	 * determinable rowtype, since they depend on relatively short-lived
1663 	 * entities.
1664 	 */
1665 	if (parse &&
1666 		parse->commandType == CMD_SELECT)
1667 	{
1668 		tlist = parse->targetList;
1669 		/* tlist is modifiable unless it's a dummy in a setop query */
1670 		tlist_is_modifiable = (parse->setOperations == NULL);
1671 	}
1672 	else if (parse &&
1673 			 (parse->commandType == CMD_INSERT ||
1674 			  parse->commandType == CMD_UPDATE ||
1675 			  parse->commandType == CMD_DELETE) &&
1676 			 parse->returningList)
1677 	{
1678 		tlist = parse->returningList;
1679 		/* returningList can always be modified */
1680 		tlist_is_modifiable = true;
1681 	}
1682 	else
1683 	{
1684 		/* Empty function body, or last statement is a utility command */
1685 		ereport(ERROR,
1686 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1687 				 errmsg("return type mismatch in function declared to return %s",
1688 						format_type_be(rettype)),
1689 				 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.")));
1690 		return false;			/* keep compiler quiet */
1691 	}
1692 
1693 	/*
1694 	 * OK, check that the targetlist returns something matching the declared
1695 	 * type, and modify it if necessary.  If possible, we insert any coercion
1696 	 * steps right into the final statement's targetlist.  However, that might
1697 	 * risk changes in the statement's semantics --- we can't safely change
1698 	 * the output type of a grouping column, for instance.  In such cases we
1699 	 * handle coercions by inserting an extra level of Query that effectively
1700 	 * just does a projection.
1701 	 */
1702 
1703 	/*
1704 	 * Count the non-junk entries in the result targetlist.
1705 	 */
1706 	tlistlen = ExecCleanTargetListLength(tlist);
1707 
1708 	fn_typtype = get_typtype(rettype);
1709 
1710 	if (fn_typtype == TYPTYPE_BASE ||
1711 		fn_typtype == TYPTYPE_DOMAIN ||
1712 		fn_typtype == TYPTYPE_ENUM ||
1713 		fn_typtype == TYPTYPE_RANGE)
1714 	{
1715 		/*
1716 		 * For scalar-type returns, the target list must have exactly one
1717 		 * non-junk entry, and its type must be coercible to rettype.
1718 		 */
1719 		TargetEntry *tle;
1720 
1721 		if (tlistlen != 1)
1722 			ereport(ERROR,
1723 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1724 					 errmsg("return type mismatch in function declared to return %s",
1725 							format_type_be(rettype)),
1726 					 errdetail("Final statement must return exactly one column.")));
1727 
1728 		/* We assume here that non-junk TLEs must come first in tlists */
1729 		tle = (TargetEntry *) linitial(tlist);
1730 		Assert(!tle->resjunk);
1731 
1732 		if (!coerce_fn_result_column(tle, rettype, -1,
1733 									 tlist_is_modifiable,
1734 									 &upper_tlist,
1735 									 &upper_tlist_nontrivial))
1736 			ereport(ERROR,
1737 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1738 					 errmsg("return type mismatch in function declared to return %s",
1739 							format_type_be(rettype)),
1740 					 errdetail("Actual return type is %s.",
1741 							   format_type_be(exprType((Node *) tle->expr)))));
1742 	}
1743 	else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
1744 	{
1745 		/*
1746 		 * Returns a rowtype.
1747 		 *
1748 		 * Note that we will not consider a domain over composite to be a
1749 		 * "rowtype" return type; it goes through the scalar case above.  This
1750 		 * is because we only provide column-by-column implicit casting, and
1751 		 * will not cast the complete record result.  So the only way to
1752 		 * produce a domain-over-composite result is to compute it as an
1753 		 * explicit single-column result.  The single-composite-column code
1754 		 * path just below could handle such cases, but it won't be reached.
1755 		 */
1756 		int			tupnatts;	/* physical number of columns in tuple */
1757 		int			tuplogcols; /* # of nondeleted columns in tuple */
1758 		int			colindex;	/* physical column index */
1759 
1760 		/*
1761 		 * If the target list has one non-junk entry, and that expression has
1762 		 * or can be coerced to the declared return type, take it as the
1763 		 * result.  This allows, for example, 'SELECT func2()', where func2
1764 		 * has the same composite return type as the function that's calling
1765 		 * it.  This provision creates some ambiguity --- maybe the expression
1766 		 * was meant to be the lone field of the composite result --- but it
1767 		 * works well enough as long as we don't get too enthusiastic about
1768 		 * inventing coercions from scalar to composite types.
1769 		 *
1770 		 * XXX Note that if rettype is RECORD and the expression is of a named
1771 		 * composite type, or vice versa, this coercion will succeed, whether
1772 		 * or not the record type really matches.  For the moment we rely on
1773 		 * runtime type checking to catch any discrepancy, but it'd be nice to
1774 		 * do better at parse time.
1775 		 */
1776 		if (tlistlen == 1)
1777 		{
1778 			TargetEntry *tle = (TargetEntry *) linitial(tlist);
1779 
1780 			Assert(!tle->resjunk);
1781 			if (coerce_fn_result_column(tle, rettype, -1,
1782 										tlist_is_modifiable,
1783 										&upper_tlist,
1784 										&upper_tlist_nontrivial))
1785 			{
1786 				/* Note that we're NOT setting is_tuple_result */
1787 				goto tlist_coercion_finished;
1788 			}
1789 		}
1790 
1791 		/*
1792 		 * If the caller didn't provide an expected tupdesc, we can't do any
1793 		 * further checking.  Assume we're returning the whole tuple.
1794 		 */
1795 		if (rettupdesc == NULL)
1796 		{
1797 			/* Return tlist if requested */
1798 			if (resultTargetList)
1799 				*resultTargetList = tlist;
1800 			return true;
1801 		}
1802 
1803 		/*
1804 		 * Verify that the targetlist matches the return tuple type.  We scan
1805 		 * the non-resjunk columns, and coerce them if necessary to match the
1806 		 * datatypes of the non-deleted attributes.  For deleted attributes,
1807 		 * insert NULL result columns if the caller asked for that.
1808 		 */
1809 		tupnatts = rettupdesc->natts;
1810 		tuplogcols = 0;			/* we'll count nondeleted cols as we go */
1811 		colindex = 0;
1812 
1813 		foreach(lc, tlist)
1814 		{
1815 			TargetEntry *tle = (TargetEntry *) lfirst(lc);
1816 			Form_pg_attribute attr;
1817 
1818 			/* resjunk columns can simply be ignored */
1819 			if (tle->resjunk)
1820 				continue;
1821 
1822 			do
1823 			{
1824 				colindex++;
1825 				if (colindex > tupnatts)
1826 					ereport(ERROR,
1827 							(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1828 							 errmsg("return type mismatch in function declared to return %s",
1829 									format_type_be(rettype)),
1830 							 errdetail("Final statement returns too many columns.")));
1831 				attr = TupleDescAttr(rettupdesc, colindex - 1);
1832 				if (attr->attisdropped && insertDroppedCols)
1833 				{
1834 					Expr	   *null_expr;
1835 
1836 					/* The type of the null we insert isn't important */
1837 					null_expr = (Expr *) makeConst(INT4OID,
1838 												   -1,
1839 												   InvalidOid,
1840 												   sizeof(int32),
1841 												   (Datum) 0,
1842 												   true,	/* isnull */
1843 												   true /* byval */ );
1844 					upper_tlist = lappend(upper_tlist,
1845 										  makeTargetEntry(null_expr,
1846 														  list_length(upper_tlist) + 1,
1847 														  NULL,
1848 														  false));
1849 					upper_tlist_nontrivial = true;
1850 				}
1851 			} while (attr->attisdropped);
1852 			tuplogcols++;
1853 
1854 			if (!coerce_fn_result_column(tle,
1855 										 attr->atttypid, attr->atttypmod,
1856 										 tlist_is_modifiable,
1857 										 &upper_tlist,
1858 										 &upper_tlist_nontrivial))
1859 				ereport(ERROR,
1860 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1861 						 errmsg("return type mismatch in function declared to return %s",
1862 								format_type_be(rettype)),
1863 						 errdetail("Final statement returns %s instead of %s at column %d.",
1864 								   format_type_be(exprType((Node *) tle->expr)),
1865 								   format_type_be(attr->atttypid),
1866 								   tuplogcols)));
1867 		}
1868 
1869 		/* remaining columns in rettupdesc had better all be dropped */
1870 		for (colindex++; colindex <= tupnatts; colindex++)
1871 		{
1872 			if (!TupleDescAttr(rettupdesc, colindex - 1)->attisdropped)
1873 				ereport(ERROR,
1874 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1875 						 errmsg("return type mismatch in function declared to return %s",
1876 								format_type_be(rettype)),
1877 						 errdetail("Final statement returns too few columns.")));
1878 			if (insertDroppedCols)
1879 			{
1880 				Expr	   *null_expr;
1881 
1882 				/* The type of the null we insert isn't important */
1883 				null_expr = (Expr *) makeConst(INT4OID,
1884 											   -1,
1885 											   InvalidOid,
1886 											   sizeof(int32),
1887 											   (Datum) 0,
1888 											   true,	/* isnull */
1889 											   true /* byval */ );
1890 				upper_tlist = lappend(upper_tlist,
1891 									  makeTargetEntry(null_expr,
1892 													  list_length(upper_tlist) + 1,
1893 													  NULL,
1894 													  false));
1895 				upper_tlist_nontrivial = true;
1896 			}
1897 		}
1898 
1899 		/* Report that we are returning entire tuple result */
1900 		is_tuple_result = true;
1901 	}
1902 	else
1903 		ereport(ERROR,
1904 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1905 				 errmsg("return type %s is not supported for SQL functions",
1906 						format_type_be(rettype))));
1907 
1908 tlist_coercion_finished:
1909 
1910 	/*
1911 	 * If necessary, modify the final Query by injecting an extra Query level
1912 	 * that just performs a projection.  (It'd be dubious to do this to a
1913 	 * non-SELECT query, but we never have to; RETURNING lists can always be
1914 	 * modified in-place.)
1915 	 */
1916 	if (upper_tlist_nontrivial)
1917 	{
1918 		Query	   *newquery;
1919 		List	   *colnames;
1920 		RangeTblEntry *rte;
1921 		RangeTblRef *rtr;
1922 
1923 		Assert(parse->commandType == CMD_SELECT);
1924 
1925 		/* Most of the upper Query struct can be left as zeroes/nulls */
1926 		newquery = makeNode(Query);
1927 		newquery->commandType = CMD_SELECT;
1928 		newquery->querySource = parse->querySource;
1929 		newquery->canSetTag = true;
1930 		newquery->targetList = upper_tlist;
1931 
1932 		/* We need a moderately realistic colnames list for the subquery RTE */
1933 		colnames = NIL;
1934 		foreach(lc, parse->targetList)
1935 		{
1936 			TargetEntry *tle = (TargetEntry *) lfirst(lc);
1937 
1938 			if (tle->resjunk)
1939 				continue;
1940 			colnames = lappend(colnames,
1941 							   makeString(tle->resname ? tle->resname : ""));
1942 		}
1943 
1944 		/* Build a suitable RTE for the subquery */
1945 		rte = makeNode(RangeTblEntry);
1946 		rte->rtekind = RTE_SUBQUERY;
1947 		rte->subquery = parse;
1948 		rte->eref = rte->alias = makeAlias("*SELECT*", colnames);
1949 		rte->lateral = false;
1950 		rte->inh = false;
1951 		rte->inFromCl = true;
1952 		newquery->rtable = list_make1(rte);
1953 
1954 		rtr = makeNode(RangeTblRef);
1955 		rtr->rtindex = 1;
1956 		newquery->jointree = makeFromExpr(list_make1(rtr), NULL);
1957 
1958 		/* Replace original query in the correct element of the query list */
1959 		lfirst(parse_cell) = newquery;
1960 	}
1961 
1962 	/* Return tlist (possibly modified) if requested */
1963 	if (resultTargetList)
1964 		*resultTargetList = upper_tlist;
1965 
1966 	return is_tuple_result;
1967 }
1968 
1969 /*
1970  * Process one function result column for check_sql_fn_retval
1971  *
1972  * Coerce the output value to the required type/typmod, and add a column
1973  * to *upper_tlist for it.  Set *upper_tlist_nontrivial to true if we
1974  * add an upper tlist item that's not just a Var.
1975  *
1976  * Returns true if OK, false if could not coerce to required type
1977  * (in which case, no changes have been made)
1978  */
1979 static bool
1980 coerce_fn_result_column(TargetEntry *src_tle,
1981 						Oid res_type,
1982 						int32 res_typmod,
1983 						bool tlist_is_modifiable,
1984 						List **upper_tlist,
1985 						bool *upper_tlist_nontrivial)
1986 {
1987 	TargetEntry *new_tle;
1988 	Expr	   *new_tle_expr;
1989 	Node	   *cast_result;
1990 
1991 	/*
1992 	 * If the TLE has a sortgroupref marking, don't change it, as it probably
1993 	 * is referenced by ORDER BY, DISTINCT, etc, and changing its type would
1994 	 * break query semantics.  Otherwise, it's safe to modify in-place unless
1995 	 * the query as a whole has issues with that.
1996 	 */
ExecTypeFromExprList(List * exprList)1997 	if (tlist_is_modifiable && src_tle->ressortgroupref == 0)
1998 	{
1999 		/* OK to modify src_tle in place, if necessary */
2000 		cast_result = coerce_to_target_type(NULL,
2001 											(Node *) src_tle->expr,
2002 											exprType((Node *) src_tle->expr),
2003 											res_type, res_typmod,
2004 											COERCION_ASSIGNMENT,
2005 											COERCE_IMPLICIT_CAST,
2006 											-1);
2007 		if (cast_result == NULL)
2008 			return false;
2009 		assign_expr_collations(NULL, cast_result);
2010 		src_tle->expr = (Expr *) cast_result;
2011 		/* Make a Var referencing the possibly-modified TLE */
2012 		new_tle_expr = (Expr *) makeVarFromTargetEntry(1, src_tle);
2013 	}
2014 	else
2015 	{
2016 		/* Any casting must happen in the upper tlist */
2017 		Var		   *var = makeVarFromTargetEntry(1, src_tle);
2018 
2019 		cast_result = coerce_to_target_type(NULL,
2020 											(Node *) var,
2021 											var->vartype,
2022 											res_type, res_typmod,
2023 											COERCION_ASSIGNMENT,
2024 											COERCE_IMPLICIT_CAST,
2025 											-1);
2026 		if (cast_result == NULL)
2027 			return false;
2028 		assign_expr_collations(NULL, cast_result);
2029 		/* Did the coercion actually do anything? */
2030 		if (cast_result != (Node *) var)
2031 			*upper_tlist_nontrivial = true;
2032 		new_tle_expr = (Expr *) cast_result;
2033 	}
2034 	new_tle = makeTargetEntry(new_tle_expr,
2035 							  list_length(*upper_tlist) + 1,
ExecTypeSetColNames(TupleDesc typeInfo,List * namesList)2036 							  src_tle->resname, false);
2037 	*upper_tlist = lappend(*upper_tlist, new_tle);
2038 	return true;
2039 }
2040 
2041 
2042 /*
2043  * CreateSQLFunctionDestReceiver -- create a suitable DestReceiver object
2044  */
2045 DestReceiver *
2046 CreateSQLFunctionDestReceiver(void)
2047 {
2048 	DR_sqlfunction *self = (DR_sqlfunction *) palloc0(sizeof(DR_sqlfunction));
2049 
2050 	self->pub.receiveSlot = sqlfunction_receive;
2051 	self->pub.rStartup = sqlfunction_startup;
2052 	self->pub.rShutdown = sqlfunction_shutdown;
2053 	self->pub.rDestroy = sqlfunction_destroy;
2054 	self->pub.mydest = DestSQLFunction;
2055 
2056 	/* private fields will be set by postquel_start */
2057 
2058 	return (DestReceiver *) self;
2059 }
2060 
2061 /*
2062  * sqlfunction_startup --- executor startup
2063  */
2064 static void
2065 sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
2066 {
2067 	/* no-op */
2068 }
2069 
2070 /*
2071  * sqlfunction_receive --- receive one tuple
2072  */
2073 static bool
2074 sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
2075 {
2076 	DR_sqlfunction *myState = (DR_sqlfunction *) self;
2077 
2078 	/* Filter tuple as needed */
2079 	slot = ExecFilterJunk(myState->filter, slot);
2080 
2081 	/* Store the filtered tuple into the tuplestore */
BlessTupleDesc(TupleDesc tupdesc)2082 	tuplestore_puttupleslot(myState->tstore, slot);
2083 
2084 	return true;
2085 }
2086 
2087 /*
2088  * sqlfunction_shutdown --- executor end
2089  */
2090 static void
2091 sqlfunction_shutdown(DestReceiver *self)
2092 {
2093 	/* no-op */
2094 }
2095 
2096 /*
TupleDescGetAttInMetadata(TupleDesc tupdesc)2097  * sqlfunction_destroy --- release DestReceiver object
2098  */
2099 static void
2100 sqlfunction_destroy(DestReceiver *self)
2101 {
2102 	pfree(self);
2103 }
2104