* ExecMakeTableFunctionResult * * Evaluate a table function, producing a materialized result in a Tuplestore * object. * * This is used by nodeFunctionscan.c. */
| 98 | * This is used by nodeFunctionscan.c. |
| 99 | */ |
| 100 | Tuplestorestate * |
| 101 | ExecMakeTableFunctionResult(SetExprState *setexpr, |
| 102 | ExprContext *econtext, |
| 103 | MemoryContext argContext, |
| 104 | TupleDesc expectedDesc, |
| 105 | bool randomAccess, |
| 106 | uint64 operatorMemKB) |
| 107 | { |
| 108 | Tuplestorestate *tupstore = NULL; |
| 109 | TupleDesc tupdesc = NULL; |
| 110 | Oid funcrettype; |
| 111 | bool returnsTuple; |
| 112 | bool returnsSet = false; |
| 113 | FunctionCallInfo fcinfo; |
| 114 | PgStat_FunctionCallUsage fcusage; |
| 115 | ReturnSetInfo rsinfo; |
| 116 | HeapTupleData tmptup; |
| 117 | MemoryContext callerContext; |
| 118 | bool first_time = true; |
| 119 | |
| 120 | /* |
| 121 | * Execute per-tablefunc actions in appropriate context. |
| 122 | * |
| 123 | * The FunctionCallInfo needs to live across all the calls to a |
| 124 | * ValuePerCall function, so it can't be allocated in the per-tuple |
| 125 | * context. Similarly, the function arguments need to be evaluated in a |
| 126 | * context that is longer lived than the per-tuple context: The argument |
| 127 | * values would otherwise disappear when we reset that context in the |
| 128 | * inner loop. As the caller's CurrentMemoryContext is typically a |
| 129 | * query-lifespan context, we don't want to leak memory there. We require |
| 130 | * the caller to pass a separate memory context that can be used for this, |
| 131 | * and can be reset each time through to avoid bloat. |
| 132 | */ |
| 133 | MemoryContextReset(argContext); |
| 134 | callerContext = MemoryContextSwitchTo(argContext); |
| 135 | |
| 136 | funcrettype = exprType((Node *) setexpr->expr); |
| 137 | |
| 138 | returnsTuple = type_is_rowtype(funcrettype); |
| 139 | |
| 140 | /* |
| 141 | * Prepare a resultinfo node for communication. We always do this even if |
| 142 | * not expecting a set result, so that we can pass expectedDesc. In the |
| 143 | * generic-expression case, the expression doesn't actually get to see the |
| 144 | * resultinfo, but set it up anyway because we use some of the fields as |
| 145 | * our own state variables. |
| 146 | */ |
| 147 | rsinfo.type = T_ReturnSetInfo; |
| 148 | rsinfo.econtext = econtext; |
| 149 | rsinfo.expectedDesc = expectedDesc; |
| 150 | rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred); |
| 151 | if (randomAccess) |
| 152 | rsinfo.allowedModes |= (int) SFRM_Materialize_Random; |
| 153 | rsinfo.returnMode = SFRM_ValuePerCall; |
| 154 | /* isDone is filled below */ |
| 155 | rsinfo.setResult = NULL; |
| 156 | rsinfo.setDesc = NULL; |
| 157 |
no test coverage detected