/*
* transformCallStmt -
* transform a call to a procedure or function
*
* If the call is to a procedure, we just translate the RPC request.
* If the call is to a function, we expect the result to be a scalar
* or row-expression, so we set up to capture the function result.
*/
CallStmt *
transformCallStmt(ParseState *pstate, CallStmt *stmt)
{
List *tlist;
ListCell *lc;
Node *rowresult;
CoercionContext ccontext;
List *fargs;
Node *call;
/*
* Transform the call.
*/
call = transformExpr(pstate, (Node *) stmt->funcexpr, EXPR_KIND_CALL_OF_PROC);
/*
* Separate out the expression's arguments from the proc-call's arguments.
* We don't need to worry about deparsing the procedure name here, since
* it's not actually used in the transformation or later processing.
*/
fargs = transformExpressionList(pstate, stmt->args, EXPR_KIND_CALL_ARGUMENT);
/*
* If we are processing a function call, set up for a possible set result.
* We do this now so that we can throw an error with the correct function
* name for functions that have disallowed set results.
*/
if (stmt->funcexpr->func->funcresulttype == RECORDOID)
{
/*
* Make a tlist for the function's results. No need to worry about
* naming the tlist entries; transformExpr() doesn't pay attention to
* tlists for function calls.
*/
tlist = NIL;
ccontext = COERCION_DOMAIN; /* don't coerce to or from RECORD */
rowresult = transformExpr(pstate, (Node *) stmt->funcexpr,
EXPR_KIND_SELECT_INTO);
foreach(lc, pstate->p_target_list)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
tlist = lappend(tlist,
makeTargetEntry(tle->expr,
tle->resno,
NULL,
false));
}
/* ... and coerce the result to the call's declared type */
rowresult = coerce_to_target_type(pstate, rowresult,
EXPR_KIND_SELECT_INTO,
exprType(rowresult),
stmt->funcexpr->funcresulttype,
-1,
COERCION_EXPLICIT,
COERCE_PLACEHOLDER,
false);
stmt->funcexpr = makeFuncExpr(stmt->funcexpr->func->funcid,
评论已关闭