function subhandler */
| 52 | |
| 53 | /* function subhandler */ |
| 54 | Datum |
| 55 | PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc) |
| 56 | { |
| 57 | bool is_setof = proc->is_setof; |
| 58 | Datum rv; |
| 59 | PyObject *volatile plargs = NULL; |
| 60 | PyObject *volatile plrv = NULL; |
| 61 | FuncCallContext *volatile funcctx = NULL; |
| 62 | PLySRFState *volatile srfstate = NULL; |
| 63 | ErrorContextCallback plerrcontext; |
| 64 | |
| 65 | /* |
| 66 | * If the function is called recursively, we must push outer-level |
| 67 | * arguments into the stack. This must be immediately before the PG_TRY |
| 68 | * to ensure that the corresponding pop happens. |
| 69 | */ |
| 70 | PLy_global_args_push(proc); |
| 71 | |
| 72 | PG_TRY(); |
| 73 | { |
| 74 | if (is_setof) |
| 75 | { |
| 76 | /* First Call setup */ |
| 77 | if (SRF_IS_FIRSTCALL()) |
| 78 | { |
| 79 | funcctx = SRF_FIRSTCALL_INIT(); |
| 80 | srfstate = (PLySRFState *) |
| 81 | MemoryContextAllocZero(funcctx->multi_call_memory_ctx, |
| 82 | sizeof(PLySRFState)); |
| 83 | /* Immediately register cleanup callback */ |
| 84 | srfstate->callback.func = plpython_srf_cleanup_callback; |
| 85 | srfstate->callback.arg = (void *) srfstate; |
| 86 | MemoryContextRegisterResetCallback(funcctx->multi_call_memory_ctx, |
| 87 | &srfstate->callback); |
| 88 | funcctx->user_fctx = (void *) srfstate; |
| 89 | } |
| 90 | /* Every call setup */ |
| 91 | funcctx = SRF_PERCALL_SETUP(); |
| 92 | Assert(funcctx != NULL); |
| 93 | srfstate = (PLySRFState *) funcctx->user_fctx; |
| 94 | Assert(srfstate != NULL); |
| 95 | } |
| 96 | |
| 97 | if (srfstate == NULL || srfstate->iter == NULL) |
| 98 | { |
| 99 | /* |
| 100 | * Non-SETOF function or first time for SETOF function: build |
| 101 | * args, then actually execute the function. |
| 102 | */ |
| 103 | plargs = PLy_function_build_args(fcinfo, proc); |
| 104 | plrv = PLy_procedure_call(proc, "args", plargs); |
| 105 | Assert(plrv != NULL); |
| 106 | } |
| 107 | else |
| 108 | { |
| 109 | /* |
| 110 | * Second or later call for a SETOF function: restore arguments in |
| 111 | * globals dict to what they were when we left off. We must do |
no test coverage detected