* Prepare function call in FROM (ROWS FROM) for execution. * * This is used by nodeFunctionscan.c. */
| 53 | * This is used by nodeFunctionscan.c. |
| 54 | */ |
| 55 | SetExprState * |
| 56 | ExecInitTableFunctionResult(Expr *expr, |
| 57 | ExprContext *econtext, PlanState *parent) |
| 58 | { |
| 59 | SetExprState *state = makeNode(SetExprState); |
| 60 | |
| 61 | state->funcReturnsSet = false; |
| 62 | state->expr = expr; |
| 63 | state->func.fn_oid = InvalidOid; |
| 64 | |
| 65 | /* |
| 66 | * Normally the passed expression tree will be a FuncExpr, since the |
| 67 | * grammar only allows a function call at the top level of a table |
| 68 | * function reference. However, if the function doesn't return set then |
| 69 | * the planner might have replaced the function call via constant-folding |
| 70 | * or inlining. So if we see any other kind of expression node, execute |
| 71 | * it via the general ExecEvalExpr() code. That code path will not |
| 72 | * support set-returning functions buried in the expression, though. |
| 73 | */ |
| 74 | if (IsA(expr, FuncExpr)) |
| 75 | { |
| 76 | FuncExpr *func = (FuncExpr *) expr; |
| 77 | |
| 78 | state->funcReturnsSet = func->funcretset; |
| 79 | state->args = ExecInitExprList(func->args, parent); |
| 80 | |
| 81 | init_sexpr(func->funcid, func->inputcollid, expr, state, parent, |
| 82 | econtext->ecxt_per_query_memory, func->funcretset, false); |
| 83 | } |
| 84 | else |
| 85 | { |
| 86 | state->elidedFuncState = ExecInitExpr(expr, parent); |
| 87 | } |
| 88 | |
| 89 | return state; |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | * ExecMakeTableFunctionResult |
no test coverage detected