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