Index: src/backend/utils/fmgr/funcapi.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/backend/utils/fmgr/funcapi.c,v retrieving revision 1.12 diff -c -r1.12 funcapi.c *** src/backend/utils/fmgr/funcapi.c 29 Nov 2003 19:52:01 -0000 1.12 --- src/backend/utils/fmgr/funcapi.c 18 Dec 2003 01:51:37 -0000 *************** *** 17,23 **** #include "catalog/pg_type.h" #include "utils/syscache.h" - /* * init_MultiFuncCall * Create an empty FuncCallContext data structure --- 17,22 ---- *************** *** 58,63 **** --- 57,64 ---- retval->user_fctx = NULL; retval->attinmeta = NULL; retval->multi_call_memory_ctx = fcinfo->flinfo->fn_mcxt; + retval->flinfo = fcinfo->flinfo; + retval->shutdown_reg = false; /* * save the pointer for cross-call use *************** *** 106,115 **** * Clean up after init_MultiFuncCall */ void ! end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx) { /* unbind from fcinfo */ ! fcinfo->flinfo->fn_extra = NULL; /* * Caller is responsible to free up memory for individual struct --- 107,119 ---- * Clean up after init_MultiFuncCall */ void ! end_MultiFuncCall(Datum arg) { + FuncCallContext *funcctx = (FuncCallContext *) DatumGetPointer(arg); + FmgrInfo *flinfo = funcctx->flinfo; + /* unbind from fcinfo */ ! flinfo->fn_extra = NULL; /* * Caller is responsible to free up memory for individual struct Index: src/include/funcapi.h =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/include/funcapi.h,v retrieving revision 1.10 diff -c -r1.10 funcapi.h *** src/include/funcapi.h 29 Nov 2003 22:40:53 -0000 1.10 --- src/include/funcapi.h 18 Dec 2003 20:17:07 -0000 *************** *** 111,116 **** --- 111,126 ---- */ MemoryContext multi_call_memory_ctx; + /* + * pointer to FmgrInfo needed for shutdown + */ + FmgrInfo *flinfo; + + /* + * true if registered shutdown callback + */ + bool shutdown_reg; + } FuncCallContext; /*---------- *************** *** 203,209 **** /* from funcapi.c */ extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS); ! extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL) --- 213,219 ---- /* from funcapi.c */ extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS); ! extern void end_MultiFuncCall(Datum arg); #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL) *************** *** 217,231 **** (_funcctx)->call_cntr++; \ rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ rsi->isDone = ExprMultipleResult; \ PG_RETURN_DATUM(_result); \ } while (0) #define SRF_RETURN_DONE(_funcctx) \ do { \ ReturnSetInfo *rsi; \ ! end_MultiFuncCall(fcinfo, _funcctx); \ rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ rsi->isDone = ExprEndResult; \ PG_RETURN_NULL(); \ } while (0) --- 227,252 ---- (_funcctx)->call_cntr++; \ rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ rsi->isDone = ExprMultipleResult; \ + if (!_funcctx->shutdown_reg) \ + { \ + RegisterExprContextCallback(rsi->econtext, \ + end_MultiFuncCall, \ + PointerGetDatum(_funcctx)); \ + _funcctx->shutdown_reg = true; \ + } \ PG_RETURN_DATUM(_result); \ } while (0) #define SRF_RETURN_DONE(_funcctx) \ do { \ ReturnSetInfo *rsi; \ ! end_MultiFuncCall(PointerGetDatum(_funcctx)); \ rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ rsi->isDone = ExprEndResult; \ + UnregisterExprContextCallback(rsi->econtext, \ + end_MultiFuncCall, \ + PointerGetDatum(_funcctx)); \ + _funcctx->shutdown_reg = false; \ PG_RETURN_NULL(); \ } while (0)