]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Ensure set-returning functions in the targetlist of a plan node will be
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 18 Dec 2003 20:21:53 +0000 (20:21 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 18 Dec 2003 20:21:53 +0000 (20:21 +0000)
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
src/backend/executor/execUtils.c
src/include/executor/executor.h

index a8eca13f1bc2300fda1a768c587f86392ddf8750..703709cee07823f5786f7a5fcd21cdc5fc71d1bc 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.75 2003/08/08 21:41:34 momjian Exp $
+ *     $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.75.4.1 2003/12/18 20:21:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "executor/nodeUnique.h"
 
 
-/* ----------------------------------------------------------------
- *             ExecReScan
+/*
+ * ExecReScan
+ *             Reset a plan node so that its output can be re-scanned.
+ *
+ * Note that if the plan node has parameters that have changed value,
+ * the output might be different from last time.
  *
- *             takes the new expression context as an argument, so that
- *             index scans needn't have their scan keys updated separately
- *             - marcel 09/20/94
- * ----------------------------------------------------------------
+ * 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:
index 1ee99cb359ec0792491886fe81081b9389d374da..540e52d4b766e500c5f807f8a864f0aec46070ba 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.106 2003/10/01 21:30:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.106.2.1 2003/12/18 20:21:53 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.
  *
index ad30681f1cdc59d79ec7c9a94fff29e59d1bbb4e..7403beffd263446c4ad9d68391f7c074eb9b51e3 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: executor.h,v 1.102 2003/10/01 21:30:52 tgl Exp $
+ * $Id: executor.h,v 1.102.2.1 2003/12/18 20:21:53 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)