Re: functions returning sets
| От | Joe Conway |
|---|---|
| Тема | Re: functions returning sets |
| Дата | |
| Msg-id | 3FE23242.2020508@joeconway.com обсуждение исходный текст |
| Ответ на | Re: functions returning sets (Tom Lane <tgl@sss.pgh.pa.us>) |
| Ответы |
Re: functions returning sets
|
| Список | pgsql-general |
Tom Lane wrote:
>>You may not even need to add any fields to FuncCallContext --- consider
>>passing the fcinfo pointer to the callback, rather than passing the
>>FuncCallContext pointer.
>
> Dept. of second thoughts: better pass the flinfo pointer, instead.
> fcinfo might point to temporary space on the stack.
OK -- this one is a good bit simpler. Any more comments?
Joe
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 19 Dec 2003 00:01:46 -0000
***************
*** 17,22 ****
--- 17,23 ----
#include "catalog/pg_type.h"
#include "utils/syscache.h"
+ static void shutdown_MultiFuncCall(Datum arg);
/*
* init_MultiFuncCall
***************
*** 41,47 ****
{
/*
* First call
! *
* Allocate suitably long-lived space and zero it
*/
retval = (FuncCallContext *)
--- 42,51 ----
{
/*
* First call
! */
! ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
!
! /*
* Allocate suitably long-lived space and zero it
*/
retval = (FuncCallContext *)
***************
*** 63,68 ****
--- 67,80 ----
* save the pointer for cross-call use
*/
fcinfo->flinfo->fn_extra = retval;
+
+ /*
+ * Ensure we will get shut down cleanly if the exprcontext is not
+ * run to completion.
+ */
+ RegisterExprContextCallback(rsi->econtext,
+ shutdown_MultiFuncCall,
+ PointerGetDatum(fcinfo->flinfo));
}
else
{
***************
*** 108,115 ****
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
--- 120,148 ----
void
end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
{
! ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
!
! /* Deregister the shutdown callback */
! UnregisterExprContextCallback(rsi->econtext,
! shutdown_MultiFuncCall,
! PointerGetDatum(fcinfo->flinfo));
!
! /* But use it to do the real work */
! shutdown_MultiFuncCall(PointerGetDatum(fcinfo->flinfo));
! }
!
! /*
! * shutdown_MultiFuncCall
! * Shutdown function to clean up after init_MultiFuncCall
! */
! static void
! shutdown_MultiFuncCall(Datum arg)
! {
! FmgrInfo *flinfo = (FmgrInfo *) DatumGetPointer(arg);
! FuncCallContext *funcctx = (FuncCallContext *) flinfo->fn_extra;
!
! /* unbind from flinfo */
! flinfo->fn_extra = NULL;
/*
* Caller is responsible to free up memory for individual struct
В списке pgsql-general по дате отправления: