1 /*-------------------------------------------------------------------------
4 * Execution of SQL-language functions
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.122 2008/03/25 22:42:43 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "access/xact.h"
18 #include "catalog/pg_proc.h"
19 #include "catalog/pg_type.h"
20 #include "commands/trigger.h"
21 #include "executor/functions.h"
23 #include "nodes/makefuncs.h"
24 #include "parser/parse_coerce.h"
25 #include "parser/parse_expr.h"
26 #include "tcop/tcopprot.h"
27 #include "tcop/utility.h"
28 #include "utils/builtins.h"
29 #include "utils/datum.h"
30 #include "utils/lsyscache.h"
31 #include "utils/syscache.h"
32 #include "utils/typcache.h"
36 * We have an execution_state record for each query in a function. Each
37 * record contains a plantree for its query. If the query is currently in
38 * F_EXEC_RUN state then there's a QueryDesc too.
42 F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE
45 typedef struct local_es
47 struct local_es *next;
49 Node *stmt; /* PlannedStmt or utility statement */
50 QueryDesc *qd; /* null unless status == RUN */
53 #define LAST_POSTQUEL_COMMAND(es) ((es)->next == NULL)
57 * An SQLFunctionCache record is built during the first call,
58 * and linked to from the fn_extra field of the FmgrInfo struct.
62 char *src; /* function body text (for error msgs) */
64 Oid *argtypes; /* resolved types of arguments */
65 Oid rettype; /* actual return type */
66 int16 typlen; /* length of the return type */
67 bool typbyval; /* true if return type is pass by value */
68 bool returnsTuple; /* true if returning whole tuple result */
69 bool shutdown_reg; /* true if registered shutdown callback */
70 bool readonly_func; /* true to run in "read only" mode */
72 ParamListInfo paramLI; /* Param list representing current args */
74 JunkFilter *junkFilter; /* used only if returnsTuple */
76 /* head of linked list of execution_state records */
77 execution_state *func_state;
80 typedef SQLFunctionCache *SQLFunctionCachePtr;
83 /* non-export function prototypes */
84 static execution_state *init_execution_state(List *queryTree_list,
86 static void init_sql_fcache(FmgrInfo *finfo);
87 static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
88 static TupleTableSlot *postquel_getnext(execution_state *es,
89 SQLFunctionCachePtr fcache);
90 static void postquel_end(execution_state *es);
91 static void postquel_sub_params(SQLFunctionCachePtr fcache,
92 FunctionCallInfo fcinfo);
93 static Datum postquel_execute(execution_state *es,
94 FunctionCallInfo fcinfo,
95 SQLFunctionCachePtr fcache,
96 MemoryContext resultcontext);
97 static void sql_exec_error_callback(void *arg);
98 static void ShutdownSQLFunction(Datum arg);
101 static execution_state *
102 init_execution_state(List *queryTree_list, bool readonly_func)
104 execution_state *firstes = NULL;
105 execution_state *preves = NULL;
108 foreach(qtl_item, queryTree_list)
110 Query *queryTree = lfirst(qtl_item);
112 execution_state *newes;
114 Assert(IsA(queryTree, Query));
116 if (queryTree->commandType == CMD_UTILITY)
117 stmt = queryTree->utilityStmt;
119 stmt = (Node *) pg_plan_query(queryTree, 0, NULL);
121 /* Precheck all commands for validity in a function */
122 if (IsA(stmt, TransactionStmt))
124 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
125 /* translator: %s is a SQL statement name */
126 errmsg("%s is not allowed in a SQL function",
127 CreateCommandTag(stmt))));
129 if (readonly_func && !CommandIsReadOnly(stmt))
131 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
132 /* translator: %s is a SQL statement name */
133 errmsg("%s is not allowed in a non-volatile function",
134 CreateCommandTag(stmt))));
136 newes = (execution_state *) palloc(sizeof(execution_state));
138 preves->next = newes;
143 newes->status = F_EXEC_START;
155 init_sql_fcache(FmgrInfo *finfo)
157 Oid foid = finfo->fn_oid;
159 HeapTuple procedureTuple;
160 Form_pg_proc procedureStruct;
161 SQLFunctionCachePtr fcache;
164 List *queryTree_list;
168 fcache = (SQLFunctionCachePtr) palloc0(sizeof(SQLFunctionCache));
171 * get the procedure tuple corresponding to the given function Oid
173 procedureTuple = SearchSysCache(PROCOID,
174 ObjectIdGetDatum(foid),
176 if (!HeapTupleIsValid(procedureTuple))
177 elog(ERROR, "cache lookup failed for function %u", foid);
178 procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
181 * get the result type from the procedure tuple, and check for polymorphic
182 * result type; if so, find out the actual result type.
184 rettype = procedureStruct->prorettype;
186 if (IsPolymorphicType(rettype))
188 rettype = get_fn_expr_rettype(finfo);
189 if (rettype == InvalidOid) /* this probably should not happen */
191 (errcode(ERRCODE_DATATYPE_MISMATCH),
192 errmsg("could not determine actual result type for function declared to return type %s",
193 format_type_be(procedureStruct->prorettype))));
196 fcache->rettype = rettype;
198 /* Fetch the typlen and byval info for the result type */
199 get_typlenbyval(rettype, &fcache->typlen, &fcache->typbyval);
201 /* Remember if function is STABLE/IMMUTABLE */
202 fcache->readonly_func =
203 (procedureStruct->provolatile != PROVOLATILE_VOLATILE);
206 * We need the actual argument types to pass to the parser.
208 nargs = procedureStruct->pronargs;
213 argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
215 procedureStruct->proargtypes.values,
216 nargs * sizeof(Oid));
217 /* Resolve any polymorphic argument types */
218 for (argnum = 0; argnum < nargs; argnum++)
220 Oid argtype = argOidVect[argnum];
222 if (IsPolymorphicType(argtype))
224 argtype = get_fn_expr_argtype(finfo, argnum);
225 if (argtype == InvalidOid)
227 (errcode(ERRCODE_DATATYPE_MISMATCH),
228 errmsg("could not determine actual type of argument declared %s",
229 format_type_be(argOidVect[argnum]))));
230 argOidVect[argnum] = argtype;
236 fcache->argtypes = argOidVect;
239 * And of course we need the function body text.
241 tmp = SysCacheGetAttr(PROCOID,
246 elog(ERROR, "null prosrc for function %u", foid);
247 fcache->src = TextDatumGetCString(tmp);
250 * Parse and rewrite the queries in the function text.
252 queryTree_list = pg_parse_and_rewrite(fcache->src, argOidVect, nargs);
255 * Check that the function returns the type it claims to. Although in
256 * simple cases this was already done when the function was defined, we
257 * have to recheck because database objects used in the function's queries
258 * might have changed type. We'd have to do it anyway if the function had
259 * any polymorphic arguments.
261 * Note: we set fcache->returnsTuple according to whether we are returning
262 * the whole tuple result or just a single column. In the latter case we
263 * clear returnsTuple because we need not act different from the scalar
264 * result case, even if it's a rowtype column.
266 * In the returnsTuple case, check_sql_fn_retval will also construct a
267 * JunkFilter we can use to coerce the returned rowtype to the desired
270 fcache->returnsTuple = check_sql_fn_retval(foid,
274 &fcache->junkFilter);
276 /* Finally, plan the queries */
277 fcache->func_state = init_execution_state(queryTree_list,
278 fcache->readonly_func);
280 ReleaseSysCache(procedureTuple);
282 finfo->fn_extra = (void *) fcache;
287 postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
291 Assert(es->qd == NULL);
294 * In a read-only function, use the surrounding query's snapshot;
295 * otherwise take a new snapshot for each query. The snapshot should
296 * include a fresh command ID so that all work to date in this transaction
297 * is visible. We copy in both cases so that postquel_end can
298 * unconditionally do FreeSnapshot.
300 if (fcache->readonly_func)
301 snapshot = CopySnapshot(ActiveSnapshot);
304 CommandCounterIncrement();
305 snapshot = CopySnapshot(GetTransactionSnapshot());
308 if (IsA(es->stmt, PlannedStmt))
309 es->qd = CreateQueryDesc((PlannedStmt *) es->stmt,
310 snapshot, InvalidSnapshot,
312 fcache->paramLI, false);
314 es->qd = CreateUtilityQueryDesc(es->stmt,
319 /* We assume we don't need to set up ActiveSnapshot for ExecutorStart */
321 /* Utility commands don't need Executor. */
322 if (es->qd->utilitystmt == NULL)
325 * Only set up to collect queued triggers if it's not a SELECT. This
326 * isn't just an optimization, but is necessary in case a SELECT
327 * returns multiple rows to caller --- we mustn't exit from the
328 * function execution with a stacked AfterTrigger level still active.
330 if (es->qd->operation != CMD_SELECT)
331 AfterTriggerBeginQuery();
332 ExecutorStart(es->qd, 0);
335 es->status = F_EXEC_RUN;
338 static TupleTableSlot *
339 postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
341 TupleTableSlot *result;
342 Snapshot saveActiveSnapshot;
345 /* Make our snapshot the active one for any called functions */
346 saveActiveSnapshot = ActiveSnapshot;
349 ActiveSnapshot = es->qd->snapshot;
351 if (es->qd->utilitystmt)
353 /* ProcessUtility needs the PlannedStmt for DECLARE CURSOR */
354 ProcessUtility((es->qd->plannedstmt ?
355 (Node *) es->qd->plannedstmt :
356 es->qd->utilitystmt),
359 false, /* not top level */
367 * If it's the function's last command, and it's a SELECT, fetch
368 * one row at a time so we can return the results. Otherwise just
369 * run it to completion. (If we run to completion then
370 * ExecutorRun is guaranteed to return NULL.)
372 if (LAST_POSTQUEL_COMMAND(es) &&
373 es->qd->operation == CMD_SELECT &&
374 es->qd->plannedstmt->utilityStmt == NULL &&
375 es->qd->plannedstmt->intoClause == NULL)
380 result = ExecutorRun(es->qd, ForwardScanDirection, count);
385 /* Restore global vars and propagate error */
386 ActiveSnapshot = saveActiveSnapshot;
391 ActiveSnapshot = saveActiveSnapshot;
397 postquel_end(execution_state *es)
399 Snapshot saveActiveSnapshot;
401 /* mark status done to ensure we don't do ExecutorEnd twice */
402 es->status = F_EXEC_DONE;
404 /* Utility commands don't need Executor. */
405 if (es->qd->utilitystmt == NULL)
407 /* Make our snapshot the active one for any called functions */
408 saveActiveSnapshot = ActiveSnapshot;
411 ActiveSnapshot = es->qd->snapshot;
413 if (es->qd->operation != CMD_SELECT)
414 AfterTriggerEndQuery(es->qd->estate);
419 /* Restore global vars and propagate error */
420 ActiveSnapshot = saveActiveSnapshot;
424 ActiveSnapshot = saveActiveSnapshot;
427 FreeSnapshot(es->qd->snapshot);
428 FreeQueryDesc(es->qd);
432 /* Build ParamListInfo array representing current arguments */
434 postquel_sub_params(SQLFunctionCachePtr fcache,
435 FunctionCallInfo fcinfo)
437 ParamListInfo paramLI;
438 int nargs = fcinfo->nargs;
444 /* sizeof(ParamListInfoData) includes the first array element */
445 paramLI = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
446 (nargs - 1) *sizeof(ParamExternData));
447 paramLI->numParams = nargs;
449 for (i = 0; i < nargs; i++)
451 ParamExternData *prm = ¶mLI->params[i];
453 prm->value = fcinfo->arg[i];
454 prm->isnull = fcinfo->argnull[i];
456 prm->ptype = fcache->argtypes[i];
463 pfree(fcache->paramLI);
465 fcache->paramLI = paramLI;
469 postquel_execute(execution_state *es,
470 FunctionCallInfo fcinfo,
471 SQLFunctionCachePtr fcache,
472 MemoryContext resultcontext)
474 TupleTableSlot *slot;
476 MemoryContext oldcontext;
478 if (es->status == F_EXEC_START)
479 postquel_start(es, fcache);
481 slot = postquel_getnext(es, fcache);
486 * We fall out here for all cases except where we have obtained a row
487 * from a function's final SELECT.
490 fcinfo->isnull = true;
495 * If we got a row from a command within the function it has to be the
496 * final command. All others shouldn't be returning anything.
498 Assert(LAST_POSTQUEL_COMMAND(es));
501 * Set up to return the function value. For pass-by-reference datatypes,
502 * be sure to allocate the result in resultcontext, not the current memory
503 * context (which has query lifespan).
505 oldcontext = MemoryContextSwitchTo(resultcontext);
507 if (fcache->returnsTuple)
510 * We are returning the whole tuple, so filter it and apply the proper
511 * labeling to make it a valid Datum. There are several reasons why
514 * 1. To copy the tuple out of the child execution context and into
515 * the desired result context.
517 * 2. To remove any junk attributes present in the raw subselect
518 * result. (This is probably not absolutely necessary, but it seems
521 * 3. To insert dummy null columns if the declared result type has any
522 * attisdropped columns.
525 HeapTupleHeader dtup;
530 newtup = ExecRemoveJunk(fcache->junkFilter, slot);
533 * Compress out the HeapTuple header data. We assume that
534 * heap_form_tuple made the tuple with header and body in one palloc'd
535 * chunk. We want to return a pointer to the chunk start so that it
536 * will work if someone tries to free it.
538 t_len = newtup->t_len;
539 dtup = (HeapTupleHeader) newtup;
540 memmove((char *) dtup, (char *) newtup->t_data, t_len);
543 * Use the declared return type if it's not RECORD; else take the type
544 * from the computed result, making sure a typmod has been assigned.
546 if (fcache->rettype != RECORDOID)
548 /* function has a named composite return type */
549 dtuptype = fcache->rettype;
554 /* function is declared to return RECORD */
555 TupleDesc tupDesc = fcache->junkFilter->jf_cleanTupType;
557 if (tupDesc->tdtypeid == RECORDOID &&
558 tupDesc->tdtypmod < 0)
559 assign_record_type_typmod(tupDesc);
560 dtuptype = tupDesc->tdtypeid;
561 dtuptypmod = tupDesc->tdtypmod;
564 HeapTupleHeaderSetDatumLength(dtup, t_len);
565 HeapTupleHeaderSetTypeId(dtup, dtuptype);
566 HeapTupleHeaderSetTypMod(dtup, dtuptypmod);
568 value = PointerGetDatum(dtup);
569 fcinfo->isnull = false;
574 * Returning a scalar, which we have to extract from the first column
575 * of the SELECT result, and then copy into result context if needed.
577 value = slot_getattr(slot, 1, &(fcinfo->isnull));
580 value = datumCopy(value, fcache->typbyval, fcache->typlen);
583 MemoryContextSwitchTo(oldcontext);
586 * If this is a single valued function we have to end the function
589 if (!fcinfo->flinfo->fn_retset)
596 fmgr_sql(PG_FUNCTION_ARGS)
598 MemoryContext oldcontext;
599 SQLFunctionCachePtr fcache;
600 ErrorContextCallback sqlerrcontext;
605 * Switch to context in which the fcache lives. This ensures that
606 * parsetrees, plans, etc, will have sufficient lifetime. The
607 * sub-executor is responsible for deleting per-tuple information.
609 oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
612 * Setup error traceback support for ereport()
614 sqlerrcontext.callback = sql_exec_error_callback;
615 sqlerrcontext.arg = fcinfo->flinfo;
616 sqlerrcontext.previous = error_context_stack;
617 error_context_stack = &sqlerrcontext;
620 * Initialize fcache (build plans) if first time through.
622 fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
625 init_sql_fcache(fcinfo->flinfo);
626 fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
628 es = fcache->func_state;
631 * Convert params to appropriate format if starting a fresh execution. (If
632 * continuing execution, we can re-use prior params.)
634 if (es && es->status == F_EXEC_START)
635 postquel_sub_params(fcache, fcinfo);
638 * Find first unfinished query in function.
640 while (es && es->status == F_EXEC_DONE)
644 * Execute each command in the function one after another until we're
645 * executing the final command and get a result or we run out of commands.
649 result = postquel_execute(es, fcinfo, fcache, oldcontext);
650 if (es->status != F_EXEC_DONE)
656 * If we've gone through every command in this function, we are done.
661 * Reset the execution states to start over again on next call.
663 es = fcache->func_state;
666 es->status = F_EXEC_START;
671 * Let caller know we're finished.
673 if (fcinfo->flinfo->fn_retset)
675 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
677 if (rsi && IsA(rsi, ReturnSetInfo))
678 rsi->isDone = ExprEndResult;
681 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
682 errmsg("set-valued function called in context that cannot accept a set")));
683 fcinfo->isnull = true;
686 /* Deregister shutdown callback, if we made one */
687 if (fcache->shutdown_reg)
689 UnregisterExprContextCallback(rsi->econtext,
691 PointerGetDatum(fcache));
692 fcache->shutdown_reg = false;
696 error_context_stack = sqlerrcontext.previous;
698 MemoryContextSwitchTo(oldcontext);
704 * If we got a result from a command within the function it has to be the
705 * final command. All others shouldn't be returning anything.
707 Assert(LAST_POSTQUEL_COMMAND(es));
710 * Let caller know we're not finished.
712 if (fcinfo->flinfo->fn_retset)
714 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
716 if (rsi && IsA(rsi, ReturnSetInfo))
717 rsi->isDone = ExprMultipleResult;
720 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
721 errmsg("set-valued function called in context that cannot accept a set")));
724 * Ensure we will get shut down cleanly if the exprcontext is not run
727 if (!fcache->shutdown_reg)
729 RegisterExprContextCallback(rsi->econtext,
731 PointerGetDatum(fcache));
732 fcache->shutdown_reg = true;
736 error_context_stack = sqlerrcontext.previous;
738 MemoryContextSwitchTo(oldcontext);
745 * error context callback to let us supply a call-stack traceback
748 sql_exec_error_callback(void *arg)
750 FmgrInfo *flinfo = (FmgrInfo *) arg;
751 SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) flinfo->fn_extra;
752 HeapTuple func_tuple;
753 Form_pg_proc functup;
755 int syntaxerrposition;
757 /* Need access to function's pg_proc tuple */
758 func_tuple = SearchSysCache(PROCOID,
759 ObjectIdGetDatum(flinfo->fn_oid),
761 if (!HeapTupleIsValid(func_tuple))
762 return; /* shouldn't happen */
763 functup = (Form_pg_proc) GETSTRUCT(func_tuple);
764 fn_name = NameStr(functup->proname);
767 * If there is a syntax error position, convert to internal syntax error
769 syntaxerrposition = geterrposition();
770 if (syntaxerrposition > 0)
776 tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosrc,
779 elog(ERROR, "null prosrc");
780 prosrc = TextDatumGetCString(tmp);
782 internalerrposition(syntaxerrposition);
783 internalerrquery(prosrc);
788 * Try to determine where in the function we failed. If there is a query
789 * with non-null QueryDesc, finger it. (We check this rather than looking
790 * for F_EXEC_RUN state, so that errors during ExecutorStart or
791 * ExecutorEnd are blamed on the appropriate query; see postquel_start and
799 es = fcache->func_state;
805 errcontext("SQL function \"%s\" statement %d",
815 * couldn't identify a running query; might be function entry,
816 * function exit, or between queries.
818 errcontext("SQL function \"%s\"", fn_name);
823 /* must have failed during init_sql_fcache() */
824 errcontext("SQL function \"%s\" during startup", fn_name);
827 ReleaseSysCache(func_tuple);
832 * callback function in case a function-returning-set needs to be shut down
833 * before it has been run to completion
836 ShutdownSQLFunction(Datum arg)
838 SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) DatumGetPointer(arg);
839 execution_state *es = fcache->func_state;
843 /* Shut down anything still running */
844 if (es->status == F_EXEC_RUN)
846 /* Reset states to START in case we're called again */
847 es->status = F_EXEC_START;
851 /* execUtils will deregister the callback... */
852 fcache->shutdown_reg = false;
857 * check_sql_fn_retval() -- check return value of a list of sql parse trees.
859 * The return value of a sql function is the value returned by
860 * the final query in the function. We do some ad-hoc type checking here
861 * to be sure that the user is returning the type he claims. There are
862 * also a couple of strange-looking features to assist callers in dealing
863 * with allowed special cases, such as binary-compatible result types.
865 * For a polymorphic function the passed rettype must be the actual resolved
866 * output type of the function; we should never see a polymorphic pseudotype
867 * such as ANYELEMENT as rettype. (This means we can't check the type during
868 * function definition of a polymorphic function.)
870 * This function returns true if the sql function returns the entire tuple
871 * result of its final SELECT, and false otherwise. Note that because we
872 * allow "SELECT rowtype_expression", this may be false even when the declared
873 * function return type is a rowtype.
875 * If insertRelabels is true, then binary-compatible cases are dealt with
876 * by actually inserting RelabelType nodes into the final SELECT; obviously
877 * the caller must pass a parsetree that it's okay to modify in this case.
879 * If junkFilter isn't NULL, then *junkFilter is set to a JunkFilter defined
880 * to convert the function's tuple result to the correct output tuple type.
881 * Whenever the result value is false (ie, the function isn't returning a
882 * tuple result), *junkFilter is set to NULL.
885 check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
887 JunkFilter **junkFilter)
896 AssertArg(!IsPolymorphicType(rettype));
899 *junkFilter = NULL; /* default result */
901 /* guard against empty function body; OK only if void return type */
902 if (queryTreeList == NIL)
904 if (rettype != VOIDOID)
906 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
907 errmsg("return type mismatch in function declared to return %s",
908 format_type_be(rettype)),
909 errdetail("Function's final statement must be a SELECT.")));
913 /* find the final query */
914 parse = (Query *) lfirst(list_tail(queryTreeList));
917 * If the last query isn't a SELECT, the return type must be VOID.
919 * Note: eventually replace this test with QueryReturnsTuples? We'd need
920 * a more general method of determining the output type, though.
922 if (!(parse->commandType == CMD_SELECT &&
923 parse->utilityStmt == NULL &&
924 parse->intoClause == NULL))
926 if (rettype != VOIDOID)
928 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
929 errmsg("return type mismatch in function declared to return %s",
930 format_type_be(rettype)),
931 errdetail("Function's final statement must be a SELECT.")));
936 * OK, it's a SELECT, so it must return something matching the declared
937 * type. (We used to insist that the declared type not be VOID in this
938 * case, but that makes it hard to write a void function that exits after
939 * calling another void function. Instead, we insist that the SELECT
940 * return void ... so void is treated as if it were a scalar type below.)
944 * Count the non-junk entries in the result targetlist.
946 tlist = parse->targetList;
947 tlistlen = ExecCleanTargetListLength(tlist);
949 fn_typtype = get_typtype(rettype);
951 if (fn_typtype == TYPTYPE_BASE ||
952 fn_typtype == TYPTYPE_DOMAIN ||
953 fn_typtype == TYPTYPE_ENUM ||
957 * For scalar-type returns, the target list must have exactly one
958 * non-junk entry, and its type must agree with what the user
959 * declared; except we allow binary-compatible types too.
965 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
966 errmsg("return type mismatch in function declared to return %s",
967 format_type_be(rettype)),
968 errdetail("Final SELECT must return exactly one column.")));
970 /* We assume here that non-junk TLEs must come first in tlists */
971 tle = (TargetEntry *) linitial(tlist);
972 Assert(!tle->resjunk);
974 restype = exprType((Node *) tle->expr);
975 if (!IsBinaryCoercible(restype, rettype))
977 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
978 errmsg("return type mismatch in function declared to return %s",
979 format_type_be(rettype)),
980 errdetail("Actual return type is %s.",
981 format_type_be(restype))));
982 if (insertRelabels && restype != rettype)
983 tle->expr = (Expr *) makeRelabelType(tle->expr,
988 else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
990 /* Returns a rowtype */
992 int tupnatts; /* physical number of columns in tuple */
993 int tuplogcols; /* # of nondeleted columns in tuple */
994 int colindex; /* physical column index */
997 * If the target list is of length 1, and the type of the varnode in
998 * the target list matches the declared return type, this is okay.
999 * This can happen, for example, where the body of the function is
1000 * 'SELECT func2()', where func2 has the same composite return type
1001 * as the function that's calling it.
1005 TargetEntry *tle = (TargetEntry *) linitial(tlist);
1007 Assert(!tle->resjunk);
1008 restype = exprType((Node *) tle->expr);
1009 if (IsBinaryCoercible(restype, rettype))
1011 if (insertRelabels && restype != rettype)
1012 tle->expr = (Expr *) makeRelabelType(tle->expr,
1016 return false; /* NOT returning whole tuple */
1020 /* Is the rowtype fixed, or determined only at runtime? */
1021 if (get_func_result_type(func_id, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1024 * Assume we are returning the whole tuple. Crosschecking against
1025 * what the caller expects will happen at runtime.
1028 *junkFilter = ExecInitJunkFilter(tlist, false, NULL);
1034 * Verify that the targetlist matches the return tuple type. We scan
1035 * the non-deleted attributes to ensure that they match the datatypes
1036 * of the non-resjunk columns.
1038 tupnatts = tupdesc->natts;
1039 tuplogcols = 0; /* we'll count nondeleted cols as we go */
1042 foreach(tlistitem, tlist)
1044 TargetEntry *tle = (TargetEntry *) lfirst(tlistitem);
1045 Form_pg_attribute attr;
1055 if (colindex > tupnatts)
1057 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1058 errmsg("return type mismatch in function declared to return %s",
1059 format_type_be(rettype)),
1060 errdetail("Final SELECT returns too many columns.")));
1061 attr = tupdesc->attrs[colindex - 1];
1062 } while (attr->attisdropped);
1065 tletype = exprType((Node *) tle->expr);
1066 atttype = attr->atttypid;
1067 if (!IsBinaryCoercible(tletype, atttype))
1069 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1070 errmsg("return type mismatch in function declared to return %s",
1071 format_type_be(rettype)),
1072 errdetail("Final SELECT returns %s instead of %s at column %d.",
1073 format_type_be(tletype),
1074 format_type_be(atttype),
1076 if (insertRelabels && tletype != atttype)
1077 tle->expr = (Expr *) makeRelabelType(tle->expr,
1086 if (colindex > tupnatts)
1088 if (!tupdesc->attrs[colindex - 1]->attisdropped)
1092 if (tlistlen != tuplogcols)
1094 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1095 errmsg("return type mismatch in function declared to return %s",
1096 format_type_be(rettype)),
1097 errdetail("Final SELECT returns too few columns.")));
1099 /* Set up junk filter if needed */
1101 *junkFilter = ExecInitJunkFilterConversion(tlist,
1102 CreateTupleDescCopy(tupdesc),
1105 /* Report that we are returning entire tuple result */
1110 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1111 errmsg("return type %s is not supported for SQL functions",
1112 format_type_be(rettype))));