From cf88f005f2662fd1dec2206d0ce1f3ab316c54e0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 18 Dec 2003 22:23:55 +0000 Subject: [PATCH] Use a shutdown callback to clear setArgsValid in a FuncExprState that is evaluating a set-valued function. This fixes some additional problems with rescanning partially-evaluated SRFs. --- src/backend/executor/execQual.c | 27 ++++++++++++++++++++++++++- src/include/nodes/execnodes.h | 9 ++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 1ee41ddb8ce..0484fd4d583 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.150 2003/10/13 22:47:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.150.2.1 2003/12/18 22:23:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -636,9 +636,26 @@ init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt) /* Initialize additional info */ fcache->setArgsValid = false; + fcache->shutdown_reg = false; fcache->func.fn_expr = (Node *) fcache->xprstate.expr; } +/* + * callback function in case a FuncExpr returning a set needs to be shut down + * before it has been run to completion + */ +static void +ShutdownFuncExpr(Datum arg) +{ + FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg); + + /* Clear any active set-argument state */ + fcache->setArgsValid = false; + + /* execUtils will deregister the callback... */ + fcache->shutdown_reg = false; +} + /* * Evaluate arguments for a function. */ @@ -827,6 +844,14 @@ ExecMakeFunctionResult(FuncExprState *fcache, memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo)); fcache->setHasSetArg = hasSetArg; fcache->setArgsValid = true; + /* Register cleanup callback if we didn't already */ + if (!fcache->shutdown_reg) + { + RegisterExprContextCallback(econtext, + ShutdownFuncExpr, + PointerGetDatum(fcache)); + fcache->shutdown_reg = true; + } } /* diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 4112cd49de6..fea27f9df20 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: execnodes.h,v 1.107 2003/10/01 21:30:52 tgl Exp $ + * $Id: execnodes.h,v 1.107.2.1 2003/12/18 22:23:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -481,6 +481,13 @@ typedef struct FuncExprState */ bool setHasSetArg; /* some argument returns a set */ + /* + * Flag to remember whether we have registered a shutdown callback for + * this FuncExprState. We do so only if setArgsValid has been true at + * least once (since all the callback is for is to clear setArgsValid). + */ + bool shutdown_reg; /* a shutdown callback is registered */ + /* * Current argument data for a set-valued function; contains valid * data only if setArgsValid is true.