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