From 38423232a5c7689bf41a9ab47086fbd6edecfd73 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 18 Dec 2003 20:21:37 +0000 Subject: [PATCH] Ensure set-returning functions in the targetlist of a plan node will be shut down cleanly if the plan node is ReScanned before the SRFs are run to completion. This fixes the problem for SQL-language functions, but still need work on functions using the SRF_XXX() macros. --- src/backend/executor/execAmi.c | 26 +++++++++++++++++++------- src/backend/executor/execUtils.c | 21 ++++++++++++++++++++- src/include/executor/executor.h | 3 ++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 60a7d59bef8..d9a24a34484 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.76 2003/11/29 19:51:48 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.77 2003/12/18 20:21:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,13 +39,20 @@ #include "executor/nodeUnique.h" -/* ---------------------------------------------------------------- - * ExecReScan +/* + * ExecReScan + * Reset a plan node so that its output can be re-scanned. * - * takes the new expression context as an argument, so that - * index scans needn't have their scan keys updated separately - * - marcel 09/20/94 - * ---------------------------------------------------------------- + * Note that if the plan node has parameters that have changed value, + * the output might be different from last time. + * + * The second parameter is currently only used to pass a NestLoop plan's + * econtext down to its inner child plan, in case that is an indexscan that + * needs access to variables of the current outer tuple. (The handling of + * this parameter is currently pretty inconsistent: some callers pass NULL + * and some pass down their parent's value; so don't rely on it in other + * situations. It'd probably be better to remove the whole thing and use + * the generalized parameter mechanism instead.) */ void ExecReScan(PlanState *node, ExprContext *exprCtxt) @@ -85,6 +92,11 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt) UpdateChangedParamSet(node->righttree, node->chgParam); } + /* Shut down any SRFs in the plan node's targetlist */ + if (node->ps_ExprContext) + ReScanExprContext(node->ps_ExprContext); + + /* And do node-type-specific processing */ switch (nodeTag(node)) { case T_ResultState: diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 2de056e1df4..cb11f4fc367 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.107 2003/11/29 19:51:48 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.108 2003/12/18 20:21:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ * FreeExecutorState * CreateExprContext * FreeExprContext + * ReScanExprContext * * ExecAssignExprContext Common code for plan node init routines. * ExecAssignResultType @@ -352,6 +353,24 @@ FreeExprContext(ExprContext *econtext) pfree(econtext); } +/* + * ReScanExprContext + * + * Reset an expression context in preparation for a rescan of its + * plan node. This requires calling any registered shutdown callbacks, + * since any partially complete set-returning-functions must be canceled. + * + * Note we make no assumption about the caller's memory context. + */ +void +ReScanExprContext(ExprContext *econtext) +{ + /* Call any registered callbacks */ + ShutdownExprContext(econtext); + /* And clean up the memory used */ + MemoryContextReset(econtext->ecxt_per_tuple_memory); +} + /* * Build a per-output-tuple ExprContext for an EState. * diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 022b759c86e..8f1dc7fafaf 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.103 2003/11/29 22:41:01 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.104 2003/12/18 20:21:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -201,6 +201,7 @@ extern EState *CreateExecutorState(void); extern void FreeExecutorState(EState *estate); extern ExprContext *CreateExprContext(EState *estate); extern void FreeExprContext(ExprContext *econtext); +extern void ReScanExprContext(ExprContext *econtext); #define ResetExprContext(econtext) \ MemoryContextReset((econtext)->ecxt_per_tuple_memory)