提交 edc7f146 编写于 作者: J Joe Conway

Use a shutdown callback to ensure proper clean up when rescanning

partially-evaluated SRFs. Per report found here:
http://archives.postgresql.org/pgsql-general/2003-12/msg00851.php
上级 e0cd1752
......@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.12 2003/11/29 19:52:01 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.13 2003/12/19 00:02:11 joe Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,6 +17,7 @@
#include "catalog/pg_type.h"
#include "utils/syscache.h"
static void shutdown_MultiFuncCall(Datum arg);
/*
* init_MultiFuncCall
......@@ -41,7 +42,10 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
{
/*
* First call
*
*/
ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
/*
* Allocate suitably long-lived space and zero it
*/
retval = (FuncCallContext *)
......@@ -63,6 +67,14 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
* 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,8 +120,29 @@ per_MultiFuncCall(PG_FUNCTION_ARGS)
void
end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
{
/* unbind from fcinfo */
fcinfo->flinfo->fn_extra = NULL;
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册