1 /*-------------------------------------------------------------------------
2  *
3  * functions.c
4  *	  Execution of SQL-language functions
5  *
6  * Portions Copyright (c) 1996-2017, 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 								  cref->location);
394 	}
395 
396 	return param;
397 }
398 
399 /*
400  * sql_fn_param_ref		parser callback for ParamRefs ($n symbols)
401  */
402 static Node *
sql_fn_param_ref(ParseState * pstate,ParamRef * pref)403 sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
404 {
405 	SQLFunctionParseInfoPtr pinfo = (SQLFunctionParseInfoPtr) pstate->p_ref_hook_state;
406 	int			paramno = pref->number;
407 
408 	/* Check parameter number is valid */
409 	if (paramno <= 0 || paramno > pinfo->nargs)
410 		return NULL;			/* unknown parameter number */
411 
412 	return sql_fn_make_param(pinfo, paramno, pref->location);
413 }
414 
415 /*
416  * sql_fn_make_param		construct a Param node for the given paramno
417  */
418 static Node *
sql_fn_make_param(SQLFunctionParseInfoPtr pinfo,int paramno,int location)419 sql_fn_make_param(SQLFunctionParseInfoPtr pinfo,
420 				  int paramno, int location)
421 {
422 	Param	   *param;
423 
424 	param = makeNode(Param);
425 	param->paramkind = PARAM_EXTERN;
426 	param->paramid = paramno;
427 	param->paramtype = pinfo->argtypes[paramno - 1];
428 	param->paramtypmod = -1;
429 	param->paramcollid = get_typcollation(param->paramtype);
430 	param->location = location;
431 
432 	/*
433 	 * If we have a function input collation, allow it to override the
434 	 * type-derived collation for parameter symbols.  (XXX perhaps this should
435 	 * not happen if the type collation is not default?)
436 	 */
437 	if (OidIsValid(pinfo->collation) && OidIsValid(param->paramcollid))
438 		param->paramcollid = pinfo->collation;
439 
440 	return (Node *) param;
441 }
442 
443 /*
444  * Search for a function parameter of the given name; if there is one,
445  * construct and return a Param node for it.  If not, return NULL.
446  * Helper function for sql_fn_post_column_ref.
447  */
448 static Node *
sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo,const char * paramname,int location)449 sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo,
450 						  const char *paramname, int location)
451 {
452 	int			i;
453 
454 	if (pinfo->argnames == NULL)
455 		return NULL;
456 
457 	for (i = 0; i < pinfo->nargs; i++)
458 	{
459 		if (pinfo->argnames[i] && strcmp(pinfo->argnames[i], paramname) == 0)
460 			return sql_fn_make_param(pinfo, i + 1, location);
461 	}
462 
463 	return NULL;
464 }
465 
466 /*
467  * Set up the per-query execution_state records for a SQL function.
468  *
469  * The input is a List of Lists of parsed and rewritten, but not planned,
470  * querytrees.  The sublist structure denotes the original query boundaries.
471  */
472 static List *
init_execution_state(List * queryTree_list,SQLFunctionCachePtr fcache,bool lazyEvalOK)473 init_execution_state(List *queryTree_list,
474 					 SQLFunctionCachePtr fcache,
475 					 bool lazyEvalOK)
476 {
477 	List	   *eslist = NIL;
478 	execution_state *lasttages = NULL;
479 	ListCell   *lc1;
480 
481 	foreach(lc1, queryTree_list)
482 	{
483 		List	   *qtlist = lfirst_node(List, lc1);
484 		execution_state *firstes = NULL;
485 		execution_state *preves = NULL;
486 		ListCell   *lc2;
487 
488 		foreach(lc2, qtlist)
489 		{
490 			Query	   *queryTree = lfirst_node(Query, lc2);
491 			PlannedStmt *stmt;
492 			execution_state *newes;
493 
494 			/* Plan the query if needed */
495 			if (queryTree->commandType == CMD_UTILITY)
496 			{
497 				/* Utility commands require no planning. */
498 				stmt = makeNode(PlannedStmt);
499 				stmt->commandType = CMD_UTILITY;
500 				stmt->canSetTag = queryTree->canSetTag;
501 				stmt->utilityStmt = queryTree->utilityStmt;
502 				stmt->stmt_location = queryTree->stmt_location;
503 				stmt->stmt_len = queryTree->stmt_len;
504 			}
505 			else
506 				stmt = pg_plan_query(queryTree,
507 									 CURSOR_OPT_PARALLEL_OK,
508 									 NULL);
509 
510 			/*
511 			 * Precheck all commands for validity in a function.  This should
512 			 * generally match the restrictions spi.c applies.
513 			 */
514 			if (stmt->commandType == CMD_UTILITY)
515 			{
516 				if (IsA(stmt->utilityStmt, CopyStmt) &&
517 					((CopyStmt *) stmt->utilityStmt)->filename == NULL)
518 					ereport(ERROR,
519 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
520 							 errmsg("cannot COPY to/from client in a SQL function")));
521 
522 				if (IsA(stmt->utilityStmt, TransactionStmt))
523 					ereport(ERROR,
524 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
525 					/* translator: %s is a SQL statement name */
526 							 errmsg("%s is not allowed in a SQL function",
527 									CreateCommandTag(stmt->utilityStmt))));
528 			}
529 
530 			if (fcache->readonly_func && !CommandIsReadOnly(stmt))
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 non-volatile function",
535 								CreateCommandTag((Node *) stmt))));
536 
537 			if (IsInParallelMode() && !CommandIsReadOnly(stmt))
538 				PreventCommandIfParallelMode(CreateCommandTag((Node *) stmt));
539 
540 			/* OK, build the execution_state for this query */
541 			newes = (execution_state *) palloc(sizeof(execution_state));
542 			if (preves)
543 				preves->next = newes;
544 			else
545 				firstes = newes;
546 
547 			newes->next = NULL;
548 			newes->status = F_EXEC_START;
549 			newes->setsResult = false;	/* might change below */
550 			newes->lazyEval = false;	/* might change below */
551 			newes->stmt = stmt;
552 			newes->qd = NULL;
553 
554 			if (queryTree->canSetTag)
555 				lasttages = newes;
556 
557 			preves = newes;
558 		}
559 
560 		eslist = lappend(eslist, firstes);
561 	}
562 
563 	/*
564 	 * Mark the last canSetTag query as delivering the function result; then,
565 	 * if it is a plain SELECT, mark it for lazy evaluation. If it's not a
566 	 * SELECT we must always run it to completion.
567 	 *
568 	 * Note: at some point we might add additional criteria for whether to use
569 	 * lazy eval.  However, we should prefer to use it whenever the function
570 	 * doesn't return set, since fetching more than one row is useless in that
571 	 * case.
572 	 *
573 	 * Note: don't set setsResult if the function returns VOID, as evidenced
574 	 * by not having made a junkfilter.  This ensures we'll throw away any
575 	 * output from a utility statement that check_sql_fn_retval deemed to not
576 	 * have output.
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 data",
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
639 	 */
640 	fcache->fname = pstrdup(NameStr(procedureStruct->proname));
641 
642 	/*
643 	 * get the result type from the procedure tuple, and check for polymorphic
644 	 * result type; if so, find out the actual result type.
645 	 */
646 	rettype = procedureStruct->prorettype;
647 
648 	if (IsPolymorphicType(rettype))
649 	{
650 		rettype = get_fn_expr_rettype(finfo);
651 		if (rettype == InvalidOid)	/* this probably should not happen */
652 			ereport(ERROR,
653 					(errcode(ERRCODE_DATATYPE_MISMATCH),
654 					 errmsg("could not determine actual result type for function declared to return type %s",
655 							format_type_be(procedureStruct->prorettype))));
656 	}
657 
658 	fcache->rettype = rettype;
659 
660 	/* Fetch the typlen and byval info for the result type */
661 	get_typlenbyval(rettype, &fcache->typlen, &fcache->typbyval);
662 
663 	/* Remember whether we're returning setof something */
664 	fcache->returnsSet = procedureStruct->proretset;
665 
666 	/* Remember if function is STABLE/IMMUTABLE */
667 	fcache->readonly_func =
668 		(procedureStruct->provolatile != PROVOLATILE_VOLATILE);
669 
670 	/*
671 	 * We need the actual argument types to pass to the parser.  Also make
672 	 * sure that parameter symbols are considered to have the function's
673 	 * resolved input collation.
674 	 */
675 	fcache->pinfo = prepare_sql_fn_parse_info(procedureTuple,
676 											  finfo->fn_expr,
677 											  collation);
678 
679 	/*
680 	 * And of course we need the function body text.
681 	 */
682 	tmp = SysCacheGetAttr(PROCOID,
683 						  procedureTuple,
684 						  Anum_pg_proc_prosrc,
685 						  &isNull);
686 	if (isNull)
687 		elog(ERROR, "null prosrc for function %u", foid);
688 	fcache->src = TextDatumGetCString(tmp);
689 
690 	/*
691 	 * Parse and rewrite the queries in the function text.  Use sublists to
692 	 * keep track of the original query boundaries.  But we also build a
693 	 * "flat" list of the rewritten queries to pass to check_sql_fn_retval.
694 	 * This is because the last canSetTag query determines the result type
695 	 * independently of query boundaries --- and it might not be in the last
696 	 * sublist, for example if the last query rewrites to DO INSTEAD NOTHING.
697 	 * (It might not be unreasonable to throw an error in such a case, but
698 	 * this is the historical behavior and it doesn't seem worth changing.)
699 	 *
700 	 * Note: since parsing and planning is done in fcontext, we will generate
701 	 * a lot of cruft that lives as long as the fcache does.  This is annoying
702 	 * but we'll not worry about it until the module is rewritten to use
703 	 * plancache.c.
704 	 */
705 	raw_parsetree_list = pg_parse_query(fcache->src);
706 
707 	queryTree_list = NIL;
708 	flat_query_list = NIL;
709 	foreach(lc, raw_parsetree_list)
710 	{
711 		RawStmt    *parsetree = lfirst_node(RawStmt, lc);
712 		List	   *queryTree_sublist;
713 
714 		queryTree_sublist = pg_analyze_and_rewrite_params(parsetree,
715 														  fcache->src,
716 														  (ParserSetupHook) sql_fn_parser_setup,
717 														  fcache->pinfo,
718 														  NULL);
719 		queryTree_list = lappend(queryTree_list, queryTree_sublist);
720 		flat_query_list = list_concat(flat_query_list,
721 									  list_copy(queryTree_sublist));
722 	}
723 
724 	/*
725 	 * Check that the function returns the type it claims to.  Although in
726 	 * simple cases this was already done when the function was defined, we
727 	 * have to recheck because database objects used in the function's queries
728 	 * might have changed type.  We'd have to do it anyway if the function had
729 	 * any polymorphic arguments.
730 	 *
731 	 * Note: we set fcache->returnsTuple according to whether we are returning
732 	 * the whole tuple result or just a single column.  In the latter case we
733 	 * clear returnsTuple because we need not act different from the scalar
734 	 * result case, even if it's a rowtype column.  (However, we have to force
735 	 * lazy eval mode in that case; otherwise we'd need extra code to expand
736 	 * the rowtype column into multiple columns, since we have no way to
737 	 * notify the caller that it should do that.)
738 	 *
739 	 * check_sql_fn_retval will also construct a JunkFilter we can use to
740 	 * coerce the returned rowtype to the desired form (unless the result type
741 	 * is VOID, in which case there's nothing to coerce to).
742 	 */
743 	fcache->returnsTuple = check_sql_fn_retval(foid,
744 											   rettype,
745 											   flat_query_list,
746 											   NULL,
747 											   &fcache->junkFilter);
748 
749 	if (fcache->returnsTuple)
750 	{
751 		/* Make sure output rowtype is properly blessed */
752 		BlessTupleDesc(fcache->junkFilter->jf_resultSlot->tts_tupleDescriptor);
753 	}
754 	else if (fcache->returnsSet && type_is_rowtype(fcache->rettype))
755 	{
756 		/*
757 		 * Returning rowtype as if it were scalar --- materialize won't work.
758 		 * Right now it's sufficient to override any caller preference for
759 		 * materialize mode, but to add more smarts in init_execution_state
760 		 * about this, we'd probably need a three-way flag instead of bool.
761 		 */
762 		lazyEvalOK = true;
763 	}
764 
765 	/* Finally, plan the queries */
766 	fcache->func_state = init_execution_state(queryTree_list,
767 											  fcache,
768 											  lazyEvalOK);
769 
770 	/* Mark fcache with time of creation to show it's valid */
771 	fcache->lxid = MyProc->lxid;
772 	fcache->subxid = GetCurrentSubTransactionId();
773 
774 	ReleaseSysCache(procedureTuple);
775 
776 	MemoryContextSwitchTo(oldcontext);
777 }
778 
779 /* Start up execution of one execution_state node */
780 static void
postquel_start(execution_state * es,SQLFunctionCachePtr fcache)781 postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
782 {
783 	DestReceiver *dest;
784 
785 	Assert(es->qd == NULL);
786 
787 	/* Caller should have ensured a suitable snapshot is active */
788 	Assert(ActiveSnapshotSet());
789 
790 	/*
791 	 * If this query produces the function result, send its output to the
792 	 * tuplestore; else discard any output.
793 	 */
794 	if (es->setsResult)
795 	{
796 		DR_sqlfunction *myState;
797 
798 		dest = CreateDestReceiver(DestSQLFunction);
799 		/* pass down the needed info to the dest receiver routines */
800 		myState = (DR_sqlfunction *) dest;
801 		Assert(myState->pub.mydest == DestSQLFunction);
802 		myState->tstore = fcache->tstore;
803 		myState->cxt = CurrentMemoryContext;
804 		myState->filter = fcache->junkFilter;
805 	}
806 	else
807 		dest = None_Receiver;
808 
809 	es->qd = CreateQueryDesc(es->stmt,
810 							 fcache->src,
811 							 GetActiveSnapshot(),
812 							 InvalidSnapshot,
813 							 dest,
814 							 fcache->paramLI,
815 							 es->qd ? es->qd->queryEnv : NULL,
816 							 0);
817 
818 	/* Utility commands don't need Executor. */
819 	if (es->qd->operation != CMD_UTILITY)
820 	{
821 		/*
822 		 * In lazyEval mode, do not let the executor set up an AfterTrigger
823 		 * context.  This is necessary not just an optimization, because we
824 		 * mustn't exit from the function execution with a stacked
825 		 * AfterTrigger level still active.  We are careful not to select
826 		 * lazyEval mode for any statement that could possibly queue triggers.
827 		 */
828 		int			eflags;
829 
830 		if (es->lazyEval)
831 			eflags = EXEC_FLAG_SKIP_TRIGGERS;
832 		else
833 			eflags = 0;			/* default run-to-completion flags */
834 		ExecutorStart(es->qd, eflags);
835 	}
836 
837 	es->status = F_EXEC_RUN;
838 }
839 
840 /* Run one execution_state; either to completion or to first result row */
841 /* Returns true if we ran to completion */
842 static bool
postquel_getnext(execution_state * es,SQLFunctionCachePtr fcache)843 postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
844 {
845 	bool		result;
846 
847 	if (es->qd->operation == CMD_UTILITY)
848 	{
849 		ProcessUtility(es->qd->plannedstmt,
850 					   fcache->src,
851 					   PROCESS_UTILITY_QUERY,
852 					   es->qd->params,
853 					   es->qd->queryEnv,
854 					   es->qd->dest,
855 					   NULL);
856 		result = true;			/* never stops early */
857 	}
858 	else
859 	{
860 		/* Run regular commands to completion unless lazyEval */
861 		uint64		count = (es->lazyEval) ? 1 : 0;
862 
863 		ExecutorRun(es->qd, ForwardScanDirection, count, !fcache->returnsSet || !es->lazyEval);
864 
865 		/*
866 		 * If we requested run to completion OR there was no tuple returned,
867 		 * command must be complete.
868 		 */
869 		result = (count == 0 || es->qd->estate->es_processed == 0);
870 	}
871 
872 	return result;
873 }
874 
875 /* Shut down execution of one execution_state node */
876 static void
postquel_end(execution_state * es)877 postquel_end(execution_state *es)
878 {
879 	/* mark status done to ensure we don't do ExecutorEnd twice */
880 	es->status = F_EXEC_DONE;
881 
882 	/* Utility commands don't need Executor. */
883 	if (es->qd->operation != CMD_UTILITY)
884 	{
885 		ExecutorFinish(es->qd);
886 		ExecutorEnd(es->qd);
887 	}
888 
889 	(*es->qd->dest->rDestroy) (es->qd->dest);
890 
891 	FreeQueryDesc(es->qd);
892 	es->qd = NULL;
893 }
894 
895 /* Build ParamListInfo array representing current arguments */
896 static void
postquel_sub_params(SQLFunctionCachePtr fcache,FunctionCallInfo fcinfo)897 postquel_sub_params(SQLFunctionCachePtr fcache,
898 					FunctionCallInfo fcinfo)
899 {
900 	int			nargs = fcinfo->nargs;
901 
902 	if (nargs > 0)
903 	{
904 		ParamListInfo paramLI;
905 		int			i;
906 
907 		if (fcache->paramLI == NULL)
908 		{
909 			paramLI = (ParamListInfo)
910 				palloc(offsetof(ParamListInfoData, params) +
911 					   nargs * sizeof(ParamExternData));
912 			/* we have static list of params, so no hooks needed */
913 			paramLI->paramFetch = NULL;
914 			paramLI->paramFetchArg = NULL;
915 			paramLI->parserSetup = NULL;
916 			paramLI->parserSetupArg = NULL;
917 			paramLI->numParams = nargs;
918 			paramLI->paramMask = NULL;
919 			fcache->paramLI = paramLI;
920 		}
921 		else
922 		{
923 			paramLI = fcache->paramLI;
924 			Assert(paramLI->numParams == nargs);
925 		}
926 
927 		for (i = 0; i < nargs; i++)
928 		{
929 			ParamExternData *prm = &paramLI->params[i];
930 
931 			prm->value = fcinfo->arg[i];
932 			prm->isnull = fcinfo->argnull[i];
933 			prm->pflags = 0;
934 			prm->ptype = fcache->pinfo->argtypes[i];
935 		}
936 	}
937 	else
938 		fcache->paramLI = NULL;
939 }
940 
941 /*
942  * Extract the SQL function's value from a single result row.  This is used
943  * both for scalar (non-set) functions and for each row of a lazy-eval set
944  * result.
945  */
946 static Datum
postquel_get_single_result(TupleTableSlot * slot,FunctionCallInfo fcinfo,SQLFunctionCachePtr fcache,MemoryContext resultcontext)947 postquel_get_single_result(TupleTableSlot *slot,
948 						   FunctionCallInfo fcinfo,
949 						   SQLFunctionCachePtr fcache,
950 						   MemoryContext resultcontext)
951 {
952 	Datum		value;
953 	MemoryContext oldcontext;
954 
955 	/*
956 	 * Set up to return the function value.  For pass-by-reference datatypes,
957 	 * be sure to allocate the result in resultcontext, not the current memory
958 	 * context (which has query lifespan).  We can't leave the data in the
959 	 * TupleTableSlot because we intend to clear the slot before returning.
960 	 */
961 	oldcontext = MemoryContextSwitchTo(resultcontext);
962 
963 	if (fcache->returnsTuple)
964 	{
965 		/* We must return the whole tuple as a Datum. */
966 		fcinfo->isnull = false;
967 		value = ExecFetchSlotTupleDatum(slot);
968 	}
969 	else
970 	{
971 		/*
972 		 * Returning a scalar, which we have to extract from the first column
973 		 * of the SELECT result, and then copy into result context if needed.
974 		 */
975 		value = slot_getattr(slot, 1, &(fcinfo->isnull));
976 
977 		if (!fcinfo->isnull)
978 			value = datumCopy(value, fcache->typbyval, fcache->typlen);
979 	}
980 
981 	MemoryContextSwitchTo(oldcontext);
982 
983 	return value;
984 }
985 
986 /*
987  * fmgr_sql: function call manager for SQL functions
988  */
989 Datum
fmgr_sql(PG_FUNCTION_ARGS)990 fmgr_sql(PG_FUNCTION_ARGS)
991 {
992 	SQLFunctionCachePtr fcache;
993 	ErrorContextCallback sqlerrcontext;
994 	MemoryContext oldcontext;
995 	bool		randomAccess;
996 	bool		lazyEvalOK;
997 	bool		is_first;
998 	bool		pushed_snapshot;
999 	execution_state *es;
1000 	TupleTableSlot *slot;
1001 	Datum		result;
1002 	List	   *eslist;
1003 	ListCell   *eslc;
1004 
1005 	/*
1006 	 * Setup error traceback support for ereport()
1007 	 */
1008 	sqlerrcontext.callback = sql_exec_error_callback;
1009 	sqlerrcontext.arg = fcinfo->flinfo;
1010 	sqlerrcontext.previous = error_context_stack;
1011 	error_context_stack = &sqlerrcontext;
1012 
1013 	/* Check call context */
1014 	if (fcinfo->flinfo->fn_retset)
1015 	{
1016 		ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1017 
1018 		/*
1019 		 * For simplicity, we require callers to support both set eval modes.
1020 		 * There are cases where we must use one or must use the other, and
1021 		 * it's not really worthwhile to postpone the check till we know. But
1022 		 * note we do not require caller to provide an expectedDesc.
1023 		 */
1024 		if (!rsi || !IsA(rsi, ReturnSetInfo) ||
1025 			(rsi->allowedModes & SFRM_ValuePerCall) == 0 ||
1026 			(rsi->allowedModes & SFRM_Materialize) == 0)
1027 			ereport(ERROR,
1028 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1029 					 errmsg("set-valued function called in context that cannot accept a set")));
1030 		randomAccess = rsi->allowedModes & SFRM_Materialize_Random;
1031 		lazyEvalOK = !(rsi->allowedModes & SFRM_Materialize_Preferred);
1032 	}
1033 	else
1034 	{
1035 		randomAccess = false;
1036 		lazyEvalOK = true;
1037 	}
1038 
1039 	/*
1040 	 * Initialize fcache (build plans) if first time through; or re-initialize
1041 	 * if the cache is stale.
1042 	 */
1043 	fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
1044 
1045 	if (fcache != NULL)
1046 	{
1047 		if (fcache->lxid != MyProc->lxid ||
1048 			!SubTransactionIsActive(fcache->subxid))
1049 		{
1050 			/* It's stale; unlink and delete */
1051 			fcinfo->flinfo->fn_extra = NULL;
1052 			MemoryContextDelete(fcache->fcontext);
1053 			fcache = NULL;
1054 		}
1055 	}
1056 
1057 	if (fcache == NULL)
1058 	{
1059 		init_sql_fcache(fcinfo->flinfo, PG_GET_COLLATION(), lazyEvalOK);
1060 		fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
1061 	}
1062 
1063 	/*
1064 	 * Switch to context in which the fcache lives.  This ensures that our
1065 	 * tuplestore etc will have sufficient lifetime.  The sub-executor is
1066 	 * responsible for deleting per-tuple information.  (XXX in the case of a
1067 	 * long-lived FmgrInfo, this policy represents more memory leakage, but
1068 	 * it's not entirely clear where to keep stuff instead.)
1069 	 */
1070 	oldcontext = MemoryContextSwitchTo(fcache->fcontext);
1071 
1072 	/*
1073 	 * Find first unfinished query in function, and note whether it's the
1074 	 * first query.
1075 	 */
1076 	eslist = fcache->func_state;
1077 	es = NULL;
1078 	is_first = true;
1079 	foreach(eslc, eslist)
1080 	{
1081 		es = (execution_state *) lfirst(eslc);
1082 
1083 		while (es && es->status == F_EXEC_DONE)
1084 		{
1085 			is_first = false;
1086 			es = es->next;
1087 		}
1088 
1089 		if (es)
1090 			break;
1091 	}
1092 
1093 	/*
1094 	 * Convert params to appropriate format if starting a fresh execution. (If
1095 	 * continuing execution, we can re-use prior params.)
1096 	 */
1097 	if (is_first && es && es->status == F_EXEC_START)
1098 		postquel_sub_params(fcache, fcinfo);
1099 
1100 	/*
1101 	 * Build tuplestore to hold results, if we don't have one already. Note
1102 	 * it's in the query-lifespan context.
1103 	 */
1104 	if (!fcache->tstore)
1105 		fcache->tstore = tuplestore_begin_heap(randomAccess, false, work_mem);
1106 
1107 	/*
1108 	 * Execute each command in the function one after another until we either
1109 	 * run out of commands or get a result row from a lazily-evaluated SELECT.
1110 	 *
1111 	 * Notes about snapshot management:
1112 	 *
1113 	 * In a read-only function, we just use the surrounding query's snapshot.
1114 	 *
1115 	 * In a non-read-only function, we rely on the fact that we'll never
1116 	 * suspend execution between queries of the function: the only reason to
1117 	 * suspend execution before completion is if we are returning a row from a
1118 	 * lazily-evaluated SELECT.  So, when first entering this loop, we'll
1119 	 * either start a new query (and push a fresh snapshot) or re-establish
1120 	 * the active snapshot from the existing query descriptor.  If we need to
1121 	 * start a new query in a subsequent execution of the loop, either we need
1122 	 * a fresh snapshot (and pushed_snapshot is false) or the existing
1123 	 * snapshot is on the active stack and we can just bump its command ID.
1124 	 */
1125 	pushed_snapshot = false;
1126 	while (es)
1127 	{
1128 		bool		completed;
1129 
1130 		if (es->status == F_EXEC_START)
1131 		{
1132 			/*
1133 			 * If not read-only, be sure to advance the command counter for
1134 			 * each command, so that all work to date in this transaction is
1135 			 * visible.  Take a new snapshot if we don't have one yet,
1136 			 * otherwise just bump the command ID in the existing snapshot.
1137 			 */
1138 			if (!fcache->readonly_func)
1139 			{
1140 				CommandCounterIncrement();
1141 				if (!pushed_snapshot)
1142 				{
1143 					PushActiveSnapshot(GetTransactionSnapshot());
1144 					pushed_snapshot = true;
1145 				}
1146 				else
1147 					UpdateActiveSnapshotCommandId();
1148 			}
1149 
1150 			postquel_start(es, fcache);
1151 		}
1152 		else if (!fcache->readonly_func && !pushed_snapshot)
1153 		{
1154 			/* Re-establish active snapshot when re-entering function */
1155 			PushActiveSnapshot(es->qd->snapshot);
1156 			pushed_snapshot = true;
1157 		}
1158 
1159 		completed = postquel_getnext(es, fcache);
1160 
1161 		/*
1162 		 * If we ran the command to completion, we can shut it down now. Any
1163 		 * row(s) we need to return are safely stashed in the tuplestore, and
1164 		 * we want to be sure that, for example, AFTER triggers get fired
1165 		 * before we return anything.  Also, if the function doesn't return
1166 		 * set, we can shut it down anyway because it must be a SELECT and we
1167 		 * don't care about fetching any more result rows.
1168 		 */
1169 		if (completed || !fcache->returnsSet)
1170 			postquel_end(es);
1171 
1172 		/*
1173 		 * Break from loop if we didn't shut down (implying we got a
1174 		 * lazily-evaluated row).  Otherwise we'll press on till the whole
1175 		 * function is done, relying on the tuplestore to keep hold of the
1176 		 * data to eventually be returned.  This is necessary since an
1177 		 * INSERT/UPDATE/DELETE RETURNING that sets the result might be
1178 		 * followed by additional rule-inserted commands, and we want to
1179 		 * finish doing all those commands before we return anything.
1180 		 */
1181 		if (es->status != F_EXEC_DONE)
1182 			break;
1183 
1184 		/*
1185 		 * Advance to next execution_state, which might be in the next list.
1186 		 */
1187 		es = es->next;
1188 		while (!es)
1189 		{
1190 			eslc = lnext(eslc);
1191 			if (!eslc)
1192 				break;			/* end of function */
1193 
1194 			es = (execution_state *) lfirst(eslc);
1195 
1196 			/*
1197 			 * Flush the current snapshot so that we will take a new one for
1198 			 * the new query list.  This ensures that new snaps are taken at
1199 			 * original-query boundaries, matching the behavior of interactive
1200 			 * execution.
1201 			 */
1202 			if (pushed_snapshot)
1203 			{
1204 				PopActiveSnapshot();
1205 				pushed_snapshot = false;
1206 			}
1207 		}
1208 	}
1209 
1210 	/*
1211 	 * The tuplestore now contains whatever row(s) we are supposed to return.
1212 	 */
1213 	if (fcache->returnsSet)
1214 	{
1215 		ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1216 
1217 		if (es)
1218 		{
1219 			/*
1220 			 * If we stopped short of being done, we must have a lazy-eval
1221 			 * row.
1222 			 */
1223 			Assert(es->lazyEval);
1224 			/* Re-use the junkfilter's output slot to fetch back the tuple */
1225 			Assert(fcache->junkFilter);
1226 			slot = fcache->junkFilter->jf_resultSlot;
1227 			if (!tuplestore_gettupleslot(fcache->tstore, true, false, slot))
1228 				elog(ERROR, "failed to fetch lazy-eval tuple");
1229 			/* Extract the result as a datum, and copy out from the slot */
1230 			result = postquel_get_single_result(slot, fcinfo,
1231 												fcache, oldcontext);
1232 			/* Clear the tuplestore, but keep it for next time */
1233 			/* NB: this might delete the slot's content, but we don't care */
1234 			tuplestore_clear(fcache->tstore);
1235 
1236 			/*
1237 			 * Let caller know we're not finished.
1238 			 */
1239 			rsi->isDone = ExprMultipleResult;
1240 
1241 			/*
1242 			 * Ensure we will get shut down cleanly if the exprcontext is not
1243 			 * run to completion.
1244 			 */
1245 			if (!fcache->shutdown_reg)
1246 			{
1247 				RegisterExprContextCallback(rsi->econtext,
1248 											ShutdownSQLFunction,
1249 											PointerGetDatum(fcache));
1250 				fcache->shutdown_reg = true;
1251 			}
1252 		}
1253 		else if (fcache->lazyEval)
1254 		{
1255 			/*
1256 			 * We are done with a lazy evaluation.  Clean up.
1257 			 */
1258 			tuplestore_clear(fcache->tstore);
1259 
1260 			/*
1261 			 * Let caller know we're finished.
1262 			 */
1263 			rsi->isDone = ExprEndResult;
1264 
1265 			fcinfo->isnull = true;
1266 			result = (Datum) 0;
1267 
1268 			/* Deregister shutdown callback, if we made one */
1269 			if (fcache->shutdown_reg)
1270 			{
1271 				UnregisterExprContextCallback(rsi->econtext,
1272 											  ShutdownSQLFunction,
1273 											  PointerGetDatum(fcache));
1274 				fcache->shutdown_reg = false;
1275 			}
1276 		}
1277 		else
1278 		{
1279 			/*
1280 			 * We are done with a non-lazy evaluation.  Return whatever is in
1281 			 * the tuplestore.  (It is now caller's responsibility to free the
1282 			 * tuplestore when done.)
1283 			 */
1284 			rsi->returnMode = SFRM_Materialize;
1285 			rsi->setResult = fcache->tstore;
1286 			fcache->tstore = NULL;
1287 			/* must copy desc because execSRF.c will free it */
1288 			if (fcache->junkFilter)
1289 				rsi->setDesc = CreateTupleDescCopy(fcache->junkFilter->jf_cleanTupType);
1290 
1291 			fcinfo->isnull = true;
1292 			result = (Datum) 0;
1293 
1294 			/* Deregister shutdown callback, if we made one */
1295 			if (fcache->shutdown_reg)
1296 			{
1297 				UnregisterExprContextCallback(rsi->econtext,
1298 											  ShutdownSQLFunction,
1299 											  PointerGetDatum(fcache));
1300 				fcache->shutdown_reg = false;
1301 			}
1302 		}
1303 	}
1304 	else
1305 	{
1306 		/*
1307 		 * Non-set function.  If we got a row, return it; else return NULL.
1308 		 */
1309 		if (fcache->junkFilter)
1310 		{
1311 			/* Re-use the junkfilter's output slot to fetch back the tuple */
1312 			slot = fcache->junkFilter->jf_resultSlot;
1313 			if (tuplestore_gettupleslot(fcache->tstore, true, false, slot))
1314 				result = postquel_get_single_result(slot, fcinfo,
1315 													fcache, oldcontext);
1316 			else
1317 			{
1318 				fcinfo->isnull = true;
1319 				result = (Datum) 0;
1320 			}
1321 		}
1322 		else
1323 		{
1324 			/* Should only get here for VOID functions */
1325 			Assert(fcache->rettype == VOIDOID);
1326 			fcinfo->isnull = true;
1327 			result = (Datum) 0;
1328 		}
1329 
1330 		/* Clear the tuplestore, but keep it for next time */
1331 		tuplestore_clear(fcache->tstore);
1332 	}
1333 
1334 	/* Pop snapshot if we have pushed one */
1335 	if (pushed_snapshot)
1336 		PopActiveSnapshot();
1337 
1338 	/*
1339 	 * If we've gone through every command in the function, we are done. Reset
1340 	 * the execution states to start over again on next call.
1341 	 */
1342 	if (es == NULL)
1343 	{
1344 		foreach(eslc, fcache->func_state)
1345 		{
1346 			es = (execution_state *) lfirst(eslc);
1347 			while (es)
1348 			{
1349 				es->status = F_EXEC_START;
1350 				es = es->next;
1351 			}
1352 		}
1353 	}
1354 
1355 	error_context_stack = sqlerrcontext.previous;
1356 
1357 	MemoryContextSwitchTo(oldcontext);
1358 
1359 	return result;
1360 }
1361 
1362 
1363 /*
1364  * error context callback to let us supply a call-stack traceback
1365  */
1366 static void
sql_exec_error_callback(void * arg)1367 sql_exec_error_callback(void *arg)
1368 {
1369 	FmgrInfo   *flinfo = (FmgrInfo *) arg;
1370 	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) flinfo->fn_extra;
1371 	int			syntaxerrposition;
1372 
1373 	/*
1374 	 * We can do nothing useful if init_sql_fcache() didn't get as far as
1375 	 * saving the function name
1376 	 */
1377 	if (fcache == NULL || fcache->fname == NULL)
1378 		return;
1379 
1380 	/*
1381 	 * If there is a syntax error position, convert to internal syntax error
1382 	 */
1383 	syntaxerrposition = geterrposition();
1384 	if (syntaxerrposition > 0 && fcache->src != NULL)
1385 	{
1386 		errposition(0);
1387 		internalerrposition(syntaxerrposition);
1388 		internalerrquery(fcache->src);
1389 	}
1390 
1391 	/*
1392 	 * Try to determine where in the function we failed.  If there is a query
1393 	 * with non-null QueryDesc, finger it.  (We check this rather than looking
1394 	 * for F_EXEC_RUN state, so that errors during ExecutorStart or
1395 	 * ExecutorEnd are blamed on the appropriate query; see postquel_start and
1396 	 * postquel_end.)
1397 	 */
1398 	if (fcache->func_state)
1399 	{
1400 		execution_state *es;
1401 		int			query_num;
1402 		ListCell   *lc;
1403 
1404 		es = NULL;
1405 		query_num = 1;
1406 		foreach(lc, fcache->func_state)
1407 		{
1408 			es = (execution_state *) lfirst(lc);
1409 			while (es)
1410 			{
1411 				if (es->qd)
1412 				{
1413 					errcontext("SQL function \"%s\" statement %d",
1414 							   fcache->fname, query_num);
1415 					break;
1416 				}
1417 				es = es->next;
1418 			}
1419 			if (es)
1420 				break;
1421 			query_num++;
1422 		}
1423 		if (es == NULL)
1424 		{
1425 			/*
1426 			 * couldn't identify a running query; might be function entry,
1427 			 * function exit, or between queries.
1428 			 */
1429 			errcontext("SQL function \"%s\"", fcache->fname);
1430 		}
1431 	}
1432 	else
1433 	{
1434 		/*
1435 		 * Assume we failed during init_sql_fcache().  (It's possible that the
1436 		 * function actually has an empty body, but in that case we may as
1437 		 * well report all errors as being "during startup".)
1438 		 */
1439 		errcontext("SQL function \"%s\" during startup", fcache->fname);
1440 	}
1441 }
1442 
1443 
1444 /*
1445  * callback function in case a function-returning-set needs to be shut down
1446  * before it has been run to completion
1447  */
1448 static void
ShutdownSQLFunction(Datum arg)1449 ShutdownSQLFunction(Datum arg)
1450 {
1451 	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) DatumGetPointer(arg);
1452 	execution_state *es;
1453 	ListCell   *lc;
1454 
1455 	foreach(lc, fcache->func_state)
1456 	{
1457 		es = (execution_state *) lfirst(lc);
1458 		while (es)
1459 		{
1460 			/* Shut down anything still running */
1461 			if (es->status == F_EXEC_RUN)
1462 			{
1463 				/* Re-establish active snapshot for any called functions */
1464 				if (!fcache->readonly_func)
1465 					PushActiveSnapshot(es->qd->snapshot);
1466 
1467 				postquel_end(es);
1468 
1469 				if (!fcache->readonly_func)
1470 					PopActiveSnapshot();
1471 			}
1472 
1473 			/* Reset states to START in case we're called again */
1474 			es->status = F_EXEC_START;
1475 			es = es->next;
1476 		}
1477 	}
1478 
1479 	/* Release tuplestore if we have one */
1480 	if (fcache->tstore)
1481 		tuplestore_end(fcache->tstore);
1482 	fcache->tstore = NULL;
1483 
1484 	/* execUtils will deregister the callback... */
1485 	fcache->shutdown_reg = false;
1486 }
1487 
1488 
1489 /*
1490  * check_sql_fn_retval() -- check return value of a list of sql parse trees.
1491  *
1492  * The return value of a sql function is the value returned by the last
1493  * canSetTag query in the function.  We do some ad-hoc type checking here
1494  * to be sure that the user is returning the type he claims.  There are
1495  * also a couple of strange-looking features to assist callers in dealing
1496  * with allowed special cases, such as binary-compatible result types.
1497  *
1498  * For a polymorphic function the passed rettype must be the actual resolved
1499  * output type of the function; we should never see a polymorphic pseudotype
1500  * such as ANYELEMENT as rettype.  (This means we can't check the type during
1501  * function definition of a polymorphic function.)
1502  *
1503  * This function returns true if the sql function returns the entire tuple
1504  * result of its final statement, or false if it returns just the first column
1505  * result of that statement.  It throws an error if the final statement doesn't
1506  * return the right type at all.
1507  *
1508  * Note that because we allow "SELECT rowtype_expression", the result can be
1509  * false even when the declared function return type is a rowtype.
1510  *
1511  * If modifyTargetList isn't NULL, the function will modify the final
1512  * statement's targetlist in two cases:
1513  * (1) if the tlist returns values that are binary-coercible to the expected
1514  * type rather than being exactly the expected type.  RelabelType nodes will
1515  * be inserted to make the result types match exactly.
1516  * (2) if there are dropped columns in the declared result rowtype.  NULL
1517  * output columns will be inserted in the tlist to match them.
1518  * (Obviously the caller must pass a parsetree that is okay to modify when
1519  * using this flag.)  Note that this flag does not affect whether the tlist is
1520  * considered to be a legal match to the result type, only how we react to
1521  * allowed not-exact-match cases.  *modifyTargetList will be set true iff
1522  * we had to make any "dangerous" changes that could modify the semantics of
1523  * the statement.  If it is set true, the caller should not use the modified
1524  * statement, but for simplicity we apply the changes anyway.
1525  *
1526  * If junkFilter isn't NULL, then *junkFilter is set to a JunkFilter defined
1527  * to convert the function's tuple result to the correct output tuple type.
1528  * Exception: if the function is defined to return VOID then *junkFilter is
1529  * set to NULL.
1530  */
1531 bool
check_sql_fn_retval(Oid func_id,Oid rettype,List * queryTreeList,bool * modifyTargetList,JunkFilter ** junkFilter)1532 check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
1533 					bool *modifyTargetList,
1534 					JunkFilter **junkFilter)
1535 {
1536 	Query	   *parse;
1537 	List	  **tlist_ptr;
1538 	List	   *tlist;
1539 	int			tlistlen;
1540 	char		fn_typtype;
1541 	Oid			restype;
1542 	ListCell   *lc;
1543 
1544 	AssertArg(!IsPolymorphicType(rettype));
1545 
1546 	if (modifyTargetList)
1547 		*modifyTargetList = false;	/* initialize for no change */
1548 	if (junkFilter)
1549 		*junkFilter = NULL;		/* initialize in case of VOID result */
1550 
1551 	/*
1552 	 * Find the last canSetTag query in the list.  This isn't necessarily the
1553 	 * last parsetree, because rule rewriting can insert queries after what
1554 	 * the user wrote.
1555 	 */
1556 	parse = NULL;
1557 	foreach(lc, queryTreeList)
1558 	{
1559 		Query	   *q = lfirst_node(Query, lc);
1560 
1561 		if (q->canSetTag)
1562 			parse = q;
1563 	}
1564 
1565 	/*
1566 	 * If it's a plain SELECT, it returns whatever the targetlist says.
1567 	 * Otherwise, if it's INSERT/UPDATE/DELETE with RETURNING, it returns
1568 	 * that. Otherwise, the function return type must be VOID.
1569 	 *
1570 	 * Note: eventually replace this test with QueryReturnsTuples?	We'd need
1571 	 * a more general method of determining the output type, though.  Also, it
1572 	 * seems too dangerous to consider FETCH or EXECUTE as returning a
1573 	 * determinable rowtype, since they depend on relatively short-lived
1574 	 * entities.
1575 	 */
1576 	if (parse &&
1577 		parse->commandType == CMD_SELECT)
1578 	{
1579 		tlist_ptr = &parse->targetList;
1580 		tlist = parse->targetList;
1581 	}
1582 	else if (parse &&
1583 			 (parse->commandType == CMD_INSERT ||
1584 			  parse->commandType == CMD_UPDATE ||
1585 			  parse->commandType == CMD_DELETE) &&
1586 			 parse->returningList)
1587 	{
1588 		tlist_ptr = &parse->returningList;
1589 		tlist = parse->returningList;
1590 	}
1591 	else
1592 	{
1593 		/* Empty function body, or last statement is a utility command */
1594 		if (rettype != VOIDOID)
1595 			ereport(ERROR,
1596 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1597 					 errmsg("return type mismatch in function declared to return %s",
1598 							format_type_be(rettype)),
1599 					 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.")));
1600 		return false;
1601 	}
1602 
1603 	/*
1604 	 * OK, check that the targetlist returns something matching the declared
1605 	 * type.  (We used to insist that the declared type not be VOID in this
1606 	 * case, but that makes it hard to write a void function that exits after
1607 	 * calling another void function.  Instead, we insist that the tlist
1608 	 * return void ... so void is treated as if it were a scalar type below.)
1609 	 */
1610 
1611 	/*
1612 	 * Count the non-junk entries in the result targetlist.
1613 	 */
1614 	tlistlen = ExecCleanTargetListLength(tlist);
1615 
1616 	fn_typtype = get_typtype(rettype);
1617 
1618 	if (fn_typtype == TYPTYPE_BASE ||
1619 		fn_typtype == TYPTYPE_DOMAIN ||
1620 		fn_typtype == TYPTYPE_ENUM ||
1621 		fn_typtype == TYPTYPE_RANGE ||
1622 		rettype == VOIDOID)
1623 	{
1624 		/*
1625 		 * For scalar-type returns, the target list must have exactly one
1626 		 * non-junk entry, and its type must agree with what the user
1627 		 * declared; except we allow binary-compatible types too.
1628 		 */
1629 		TargetEntry *tle;
1630 
1631 		if (tlistlen != 1)
1632 			ereport(ERROR,
1633 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1634 					 errmsg("return type mismatch in function declared to return %s",
1635 							format_type_be(rettype)),
1636 					 errdetail("Final statement must return exactly one column.")));
1637 
1638 		/* We assume here that non-junk TLEs must come first in tlists */
1639 		tle = (TargetEntry *) linitial(tlist);
1640 		Assert(!tle->resjunk);
1641 
1642 		restype = exprType((Node *) tle->expr);
1643 		if (!IsBinaryCoercible(restype, rettype))
1644 			ereport(ERROR,
1645 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1646 					 errmsg("return type mismatch in function declared to return %s",
1647 							format_type_be(rettype)),
1648 					 errdetail("Actual return type is %s.",
1649 							   format_type_be(restype))));
1650 		if (modifyTargetList && restype != rettype)
1651 		{
1652 			tle->expr = (Expr *) makeRelabelType(tle->expr,
1653 												 rettype,
1654 												 -1,
1655 												 get_typcollation(rettype),
1656 												 COERCE_IMPLICIT_CAST);
1657 			/* Relabel is dangerous if TLE is a sort/group or setop column */
1658 			if (tle->ressortgroupref != 0 || parse->setOperations)
1659 				*modifyTargetList = true;
1660 		}
1661 
1662 		/* Set up junk filter if needed */
1663 		if (junkFilter)
1664 			*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
1665 	}
1666 	else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
1667 	{
1668 		/* Returns a rowtype */
1669 		TupleDesc	tupdesc;
1670 		int			tupnatts;	/* physical number of columns in tuple */
1671 		int			tuplogcols; /* # of nondeleted columns in tuple */
1672 		int			colindex;	/* physical column index */
1673 		List	   *newtlist;	/* new non-junk tlist entries */
1674 		List	   *junkattrs;	/* new junk tlist entries */
1675 
1676 		/*
1677 		 * If the target list is of length 1, and the type of the varnode in
1678 		 * the target list matches the declared return type, this is okay.
1679 		 * This can happen, for example, where the body of the function is
1680 		 * 'SELECT func2()', where func2 has the same composite return type as
1681 		 * the function that's calling it.
1682 		 *
1683 		 * XXX Note that if rettype is RECORD, the IsBinaryCoercible check
1684 		 * will succeed for any composite restype.  For the moment we rely on
1685 		 * runtime type checking to catch any discrepancy, but it'd be nice to
1686 		 * do better at parse time.
1687 		 */
1688 		if (tlistlen == 1)
1689 		{
1690 			TargetEntry *tle = (TargetEntry *) linitial(tlist);
1691 
1692 			Assert(!tle->resjunk);
1693 			restype = exprType((Node *) tle->expr);
1694 			if (IsBinaryCoercible(restype, rettype))
1695 			{
1696 				if (modifyTargetList && restype != rettype)
1697 				{
1698 					tle->expr = (Expr *) makeRelabelType(tle->expr,
1699 														 rettype,
1700 														 -1,
1701 														 get_typcollation(rettype),
1702 														 COERCE_IMPLICIT_CAST);
1703 					/* Relabel is dangerous if sort/group or setop column */
1704 					if (tle->ressortgroupref != 0 || parse->setOperations)
1705 						*modifyTargetList = true;
1706 				}
1707 				/* Set up junk filter if needed */
1708 				if (junkFilter)
1709 					*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
1710 				return false;	/* NOT returning whole tuple */
1711 			}
1712 		}
1713 
1714 		/* Is the rowtype fixed, or determined only at runtime? */
1715 		if (get_func_result_type(func_id, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1716 		{
1717 			/*
1718 			 * Assume we are returning the whole tuple. Crosschecking against
1719 			 * what the caller expects will happen at runtime.
1720 			 */
1721 			if (junkFilter)
1722 				*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
1723 			return true;
1724 		}
1725 		Assert(tupdesc);
1726 
1727 		/*
1728 		 * Verify that the targetlist matches the return tuple type. We scan
1729 		 * the non-deleted attributes to ensure that they match the datatypes
1730 		 * of the non-resjunk columns.  For deleted attributes, insert NULL
1731 		 * result columns if the caller asked for that.
1732 		 */
1733 		tupnatts = tupdesc->natts;
1734 		tuplogcols = 0;			/* we'll count nondeleted cols as we go */
1735 		colindex = 0;
1736 		newtlist = NIL;			/* these are only used if modifyTargetList */
1737 		junkattrs = NIL;
1738 
1739 		foreach(lc, tlist)
1740 		{
1741 			TargetEntry *tle = (TargetEntry *) lfirst(lc);
1742 			Form_pg_attribute attr;
1743 			Oid			tletype;
1744 			Oid			atttype;
1745 
1746 			if (tle->resjunk)
1747 			{
1748 				if (modifyTargetList)
1749 					junkattrs = lappend(junkattrs, tle);
1750 				continue;
1751 			}
1752 
1753 			do
1754 			{
1755 				colindex++;
1756 				if (colindex > tupnatts)
1757 					ereport(ERROR,
1758 							(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1759 							 errmsg("return type mismatch in function declared to return %s",
1760 									format_type_be(rettype)),
1761 							 errdetail("Final statement returns too many columns.")));
1762 				attr = tupdesc->attrs[colindex - 1];
1763 				if (attr->attisdropped && modifyTargetList)
1764 				{
1765 					Expr	   *null_expr;
1766 
1767 					/* The type of the null we insert isn't important */
1768 					null_expr = (Expr *) makeConst(INT4OID,
1769 												   -1,
1770 												   InvalidOid,
1771 												   sizeof(int32),
1772 												   (Datum) 0,
1773 												   true,	/* isnull */
1774 												   true /* byval */ );
1775 					newtlist = lappend(newtlist,
1776 									   makeTargetEntry(null_expr,
1777 													   colindex,
1778 													   NULL,
1779 													   false));
1780 					/* NULL insertion is dangerous in a setop */
1781 					if (parse->setOperations)
1782 						*modifyTargetList = true;
1783 				}
1784 			} while (attr->attisdropped);
1785 			tuplogcols++;
1786 
1787 			tletype = exprType((Node *) tle->expr);
1788 			atttype = attr->atttypid;
1789 			if (!IsBinaryCoercible(tletype, atttype))
1790 				ereport(ERROR,
1791 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1792 						 errmsg("return type mismatch in function declared to return %s",
1793 								format_type_be(rettype)),
1794 						 errdetail("Final statement returns %s instead of %s at column %d.",
1795 								   format_type_be(tletype),
1796 								   format_type_be(atttype),
1797 								   tuplogcols)));
1798 			if (modifyTargetList)
1799 			{
1800 				if (tletype != atttype)
1801 				{
1802 					tle->expr = (Expr *) makeRelabelType(tle->expr,
1803 														 atttype,
1804 														 -1,
1805 														 get_typcollation(atttype),
1806 														 COERCE_IMPLICIT_CAST);
1807 					/* Relabel is dangerous if sort/group or setop column */
1808 					if (tle->ressortgroupref != 0 || parse->setOperations)
1809 						*modifyTargetList = true;
1810 				}
1811 				tle->resno = colindex;
1812 				newtlist = lappend(newtlist, tle);
1813 			}
1814 		}
1815 
1816 		/* remaining columns in tupdesc had better all be dropped */
1817 		for (colindex++; colindex <= tupnatts; colindex++)
1818 		{
1819 			if (!tupdesc->attrs[colindex - 1]->attisdropped)
1820 				ereport(ERROR,
1821 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1822 						 errmsg("return type mismatch in function declared to return %s",
1823 								format_type_be(rettype)),
1824 						 errdetail("Final statement returns too few columns.")));
1825 			if (modifyTargetList)
1826 			{
1827 				Expr	   *null_expr;
1828 
1829 				/* The type of the null we insert isn't important */
1830 				null_expr = (Expr *) makeConst(INT4OID,
1831 											   -1,
1832 											   InvalidOid,
1833 											   sizeof(int32),
1834 											   (Datum) 0,
1835 											   true,	/* isnull */
1836 											   true /* byval */ );
1837 				newtlist = lappend(newtlist,
1838 								   makeTargetEntry(null_expr,
1839 												   colindex,
1840 												   NULL,
1841 												   false));
1842 				/* NULL insertion is dangerous in a setop */
1843 				if (parse->setOperations)
1844 					*modifyTargetList = true;
1845 			}
1846 		}
1847 
1848 		if (modifyTargetList)
1849 		{
1850 			/* ensure resjunk columns are numbered correctly */
1851 			foreach(lc, junkattrs)
1852 			{
1853 				TargetEntry *tle = (TargetEntry *) lfirst(lc);
1854 
1855 				tle->resno = colindex++;
1856 			}
1857 			/* replace the tlist with the modified one */
1858 			*tlist_ptr = list_concat(newtlist, junkattrs);
1859 		}
1860 
1861 		/* Set up junk filter if needed */
1862 		if (junkFilter)
1863 			*junkFilter = ExecInitJunkFilterConversion(tlist,
1864 													   CreateTupleDescCopy(tupdesc),
1865 													   NULL);
1866 
1867 		/* Report that we are returning entire tuple result */
1868 		return true;
1869 	}
1870 	else
1871 		ereport(ERROR,
1872 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1873 				 errmsg("return type %s is not supported for SQL functions",
1874 						format_type_be(rettype))));
1875 
1876 	return false;
1877 }
1878 
1879 
1880 /*
1881  * CreateSQLFunctionDestReceiver -- create a suitable DestReceiver object
1882  */
1883 DestReceiver *
CreateSQLFunctionDestReceiver(void)1884 CreateSQLFunctionDestReceiver(void)
1885 {
1886 	DR_sqlfunction *self = (DR_sqlfunction *) palloc0(sizeof(DR_sqlfunction));
1887 
1888 	self->pub.receiveSlot = sqlfunction_receive;
1889 	self->pub.rStartup = sqlfunction_startup;
1890 	self->pub.rShutdown = sqlfunction_shutdown;
1891 	self->pub.rDestroy = sqlfunction_destroy;
1892 	self->pub.mydest = DestSQLFunction;
1893 
1894 	/* private fields will be set by postquel_start */
1895 
1896 	return (DestReceiver *) self;
1897 }
1898 
1899 /*
1900  * sqlfunction_startup --- executor startup
1901  */
1902 static void
sqlfunction_startup(DestReceiver * self,int operation,TupleDesc typeinfo)1903 sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
1904 {
1905 	/* no-op */
1906 }
1907 
1908 /*
1909  * sqlfunction_receive --- receive one tuple
1910  */
1911 static bool
sqlfunction_receive(TupleTableSlot * slot,DestReceiver * self)1912 sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
1913 {
1914 	DR_sqlfunction *myState = (DR_sqlfunction *) self;
1915 
1916 	/* Filter tuple as needed */
1917 	slot = ExecFilterJunk(myState->filter, slot);
1918 
1919 	/* Store the filtered tuple into the tuplestore */
1920 	tuplestore_puttupleslot(myState->tstore, slot);
1921 
1922 	return true;
1923 }
1924 
1925 /*
1926  * sqlfunction_shutdown --- executor end
1927  */
1928 static void
sqlfunction_shutdown(DestReceiver * self)1929 sqlfunction_shutdown(DestReceiver *self)
1930 {
1931 	/* no-op */
1932 }
1933 
1934 /*
1935  * sqlfunction_destroy --- release DestReceiver object
1936  */
1937 static void
sqlfunction_destroy(DestReceiver * self)1938 sqlfunction_destroy(DestReceiver *self)
1939 {
1940 	pfree(self);
1941 }
1942