* TableFunctionNext - ExecScan callback function for table function scans */
| 63 | * TableFunctionNext - ExecScan callback function for table function scans |
| 64 | */ |
| 65 | static TupleTableSlot * |
| 66 | TableFunctionNext(TableFunctionState *node) |
| 67 | { |
| 68 | MemoryContext oldcontext = NULL; |
| 69 | TupleTableSlot *slot = NULL; |
| 70 | ExprContext *econtext = node->ss.ps.ps_ExprContext; |
| 71 | bool returns_set = node->flinfo.fn_retset; |
| 72 | HeapTuple tuple = NULL; |
| 73 | TupleDesc resultdesc = node->resultdesc; |
| 74 | Datum user_result; |
| 75 | |
| 76 | /* Clean up any per-tuple memory */ |
| 77 | ResetExprContext(econtext); |
| 78 | |
| 79 | /* Setup arguments on the first call */ |
| 80 | if (node->is_firstcall) |
| 81 | { |
| 82 | int i = 0; |
| 83 | ListCell *lc; |
| 84 | |
| 85 | foreach(lc, node->args) |
| 86 | { |
| 87 | ExprState *argstate = (ExprState *) lfirst(lc); |
| 88 | |
| 89 | if (!argstate) |
| 90 | { |
| 91 | /* |
| 92 | * The ANYTABLE argument is represented as a NULL in the |
| 93 | * arguments list. |
| 94 | */ |
| 95 | node->fcinfo->args[i].value = AnyTableGetDatum(node->inputscan); |
| 96 | node->fcinfo->args[i].isnull = false; |
| 97 | } |
| 98 | else |
| 99 | node->fcinfo->args[i].value = ExecEvalExpr(argstate, |
| 100 | econtext, |
| 101 | &node->fcinfo->args[i].isnull); |
| 102 | i++; |
| 103 | } |
| 104 | node->is_firstcall = false; |
| 105 | } |
| 106 | |
| 107 | /* |
| 108 | * If all results have been returned by the callback function then |
| 109 | * we are done. |
| 110 | */ |
| 111 | if (node->rsinfo.isDone == ExprEndResult) |
| 112 | return slot; /* empty slot */ |
| 113 | |
| 114 | /* Invoke the user supplied function */ |
| 115 | node->fcinfo->isnull = false; |
| 116 | oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 117 | user_result = FunctionCallInvoke(node->fcinfo); |
| 118 | MemoryContextSwitchTo(oldcontext); |
| 119 | if (node->rsinfo.returnMode != SFRM_ValuePerCall) |
| 120 | { |
| 121 | /* FIXME: should support both protocols */ |
| 122 | ereport(ERROR, |
nothing calls this directly
no test coverage detected