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 по дате отправления:

Предыдущее
От: Reece Hart
Дата:
Сообщение: Re: md5 function
Следующее
От: Tom Lane
Дата:
Сообщение: Re: functions returning sets