aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorJoe Conway <mail@joeconway.com>2003-12-19 00:00:27 +0000
committerJoe Conway <mail@joeconway.com>2003-12-19 00:00:27 +0000
commitacae15faf3a4ef6e1195d4805acdda404f4e2860 (patch)
tree67238f0129979d9239f15c3ba3883560572e3f38 /src/backend/utils
parent7748c5ee2987e8ae9bfae448cefa9d2dfb7a79e3 (diff)
downloadpostgresql-acae15faf3a4ef6e1195d4805acdda404f4e2860.tar.gz
postgresql-acae15faf3a4ef6e1195d4805acdda404f4e2860.zip
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
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/fmgr/funcapi.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 53b8cc3a237..1f020b3720e 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/funcapi.c,v 1.11 2003/09/15 20:03:37 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/funcapi.c,v 1.11.2.1 2003/12/19 00:00:27 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