88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.239 2009/04/02 20:16:30 tgl Exp $
11+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.240 2009/04/09 02:57:53 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
2424#include "funcapi.h"
2525#include "nodes/nodeFuncs.h"
2626#include "parser/scansup.h"
27+ #include "storage/proc.h"
2728#include "tcop/tcopprot.h"
2829#include "utils/array.h"
2930#include "utils/builtins.h"
@@ -51,27 +52,26 @@ typedef struct
5152 * creates its own "eval_econtext" ExprContext within this estate for
5253 * per-evaluation workspace. eval_econtext is freed at normal function exit,
5354 * and the EState is freed at transaction end (in case of error, we assume
54- * that the abort mechanisms clean it all up).In order to be sure
55- *ExprContext callbacks are handled properly, each subtransaction has to have
56- *its own such EState; hence weneed a stack.We use a simple counter to
57- *distinguish different instantiations of the EState, so that we can tell
58- *whether we have a current copy of a prepared expression .
55+ * that the abort mechanisms clean it all up). Furthermore, any exception
56+ *block within a function has to have its own eval_econtext separate from
57+ *the containing function's, so that wecan clean up ExprContext callbacks
58+ *properly at subtransaction exit. We maintain a stack that tracks the
59+ *individual econtexts so that we can clean up correctly at subxact exit .
5960 *
6061 * This arrangement is a bit tedious to maintain, but it's worth the trouble
6162 * so that we don't have to re-prepare simple expressions on each trip through
6263 * a function.(We assume the case to optimize is many repetitions of a
6364 * function within a transaction.)
6465 */
65- typedef struct SimpleEstateStackEntry
66+ typedef struct SimpleEcontextStackEntry
6667{
67- EState * xact_eval_estate ;/* EState for current xact level */
68- longint xact_estate_simple_id ;/* ID for xact_eval_estate */
69- SubTransactionId xact_subxid ;/* ID for current subxact */
70- struct SimpleEstateStackEntry * next ;/* next stack entry up */
71- }SimpleEstateStackEntry ;
68+ ExprContext * stack_econtext ;/* a stacked econtext */
69+ SubTransactionId xact_subxid ;/* ID for current subxact */
70+ struct SimpleEcontextStackEntry * next ;/* next stack entry up */
71+ }SimpleEcontextStackEntry ;
7272
73- static SimpleEstateStackEntry * simple_estate_stack = NULL ;
74- static long int simple_estate_id_counter = 0 ;
73+ static EState * simple_eval_estate = NULL ;
74+ static SimpleEcontextStackEntry * simple_econtext_stack = NULL ;
7575
7676/************************************************************
7777 * Local function forward declarations
@@ -193,6 +193,7 @@ static void validate_tupdesc_compat(TupleDesc expected, TupleDesc returned,
193193const char * msg );
194194static void exec_set_found (PLpgSQL_execstate * estate ,bool state );
195195static void plpgsql_create_econtext (PLpgSQL_execstate * estate );
196+ static void plpgsql_destroy_econtext (PLpgSQL_execstate * estate );
196197static void free_var (PLpgSQL_var * var );
197198static void assign_text_var (PLpgSQL_var * var ,const char * str );
198199static PreparedParamsData * exec_eval_using_params (PLpgSQL_execstate * estate ,
@@ -452,8 +453,7 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
452453((* plugin_ptr )-> func_end ) (& estate ,func );
453454
454455/* Clean up any leftover temporary memory */
455- FreeExprContext (estate .eval_econtext );
456- estate .eval_econtext = NULL ;
456+ plpgsql_destroy_econtext (& estate );
457457exec_eval_cleanup (& estate );
458458
459459/*
@@ -718,8 +718,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
718718((* plugin_ptr )-> func_end ) (& estate ,func );
719719
720720/* Clean up any leftover temporary memory */
721- FreeExprContext (estate .eval_econtext );
722- estate .eval_econtext = NULL ;
721+ plpgsql_destroy_econtext (& estate );
723722exec_eval_cleanup (& estate );
724723
725724/*
@@ -984,8 +983,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
984983MemoryContext oldcontext = CurrentMemoryContext ;
985984ResourceOwner oldowner = CurrentResourceOwner ;
986985ExprContext * old_eval_econtext = estate -> eval_econtext ;
987- EState * old_eval_estate = estate -> eval_estate ;
988- longint old_eval_estate_simple_id = estate -> eval_estate_simple_id ;
989986
990987estate -> err_text = gettext_noop ("during statement block entry" );
991988
@@ -1034,10 +1031,11 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
10341031MemoryContextSwitchTo (oldcontext );
10351032CurrentResourceOwner = oldowner ;
10361033
1037- /* Revert to outer eval_econtext */
1034+ /*
1035+ * Revert to outer eval_econtext. (The inner one was automatically
1036+ * cleaned up during subxact exit.)
1037+ */
10381038estate -> eval_econtext = old_eval_econtext ;
1039- estate -> eval_estate = old_eval_estate ;
1040- estate -> eval_estate_simple_id = old_eval_estate_simple_id ;
10411039
10421040/*
10431041 * AtEOSubXact_SPI() should not have popped any SPI context, but
@@ -1064,8 +1062,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
10641062
10651063/* Revert to outer eval_econtext */
10661064estate -> eval_econtext = old_eval_econtext ;
1067- estate -> eval_estate = old_eval_estate ;
1068- estate -> eval_estate_simple_id = old_eval_estate_simple_id ;
10691065
10701066/*
10711067 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it
@@ -4333,6 +4329,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
43334329Oid * rettype )
43344330{
43354331ExprContext * econtext = estate -> eval_econtext ;
4332+ LocalTransactionId curlxid = MyProc -> lxid ;
43364333CachedPlanSource * plansource ;
43374334CachedPlan * cplan ;
43384335ParamListInfo paramLI ;
@@ -4373,14 +4370,14 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
43734370
43744371/*
43754372 * Prepare the expression for execution, if it's not been done already in
4376- * the currenteval_estate . (This will be forced to happen if we called
4373+ * the currenttransaction . (This will be forced to happen if we called
43774374 * exec_simple_check_plan above.)
43784375 */
4379- if (expr -> expr_simple_id != estate -> eval_estate_simple_id )
4376+ if (expr -> expr_simple_lxid != curlxid )
43804377{
43814378expr -> expr_simple_state = ExecPrepareExpr (expr -> expr_simple_expr ,
4382- estate -> eval_estate );
4383- expr -> expr_simple_id = estate -> eval_estate_simple_id ;
4379+ simple_eval_estate );
4380+ expr -> expr_simple_lxid = curlxid ;
43844381}
43854382
43864383/*
@@ -5103,7 +5100,7 @@ exec_simple_check_plan(PLpgSQL_expr *expr)
51035100 */
51045101expr -> expr_simple_expr = tle -> expr ;
51055102expr -> expr_simple_state = NULL ;
5106- expr -> expr_simple_id = -1 ;
5103+ expr -> expr_simple_lxid = InvalidLocalTransactionId ;
51075104/* Also stash away the expression result type */
51085105expr -> expr_simple_type = exprType ((Node * )tle -> expr );
51095106}
@@ -5165,46 +5162,69 @@ exec_set_found(PLpgSQL_execstate *estate, bool state)
51655162/*
51665163 * plpgsql_create_econtext --- create an eval_econtext for the current function
51675164 *
5168- * We may need to create a neweval_estate too, if there's not one already
5169- * for the current (sub) transaction. The EState will be cleaned up at
5170- *(sub) transaction end.
5165+ * We may need to create a newsimple_eval_estate too, if there's not one
5166+ *already for the current transaction. The EState will be cleaned up at
5167+ * transaction end.
51715168 */
51725169static void
51735170plpgsql_create_econtext (PLpgSQL_execstate * estate )
51745171{
5175- SubTransactionId my_subxid = GetCurrentSubTransactionId ();
5176- SimpleEstateStackEntry * entry = simple_estate_stack ;
5172+ SimpleEcontextStackEntry * entry ;
51775173
5178- /* Create new EState if not one for current subxact */
5179- if (entry == NULL ||
5180- entry -> xact_subxid != my_subxid )
5174+ /*
5175+ * Create an EState for evaluation of simple expressions, if there's not
5176+ * one already in the current transaction.The EState is made a child of
5177+ * TopTransactionContext so it will have the right lifespan.
5178+ */
5179+ if (simple_eval_estate == NULL )
51815180{
51825181MemoryContext oldcontext ;
51835182
5184- /* Stack entries are kept in TopTransactionContext for simplicity */
5185- entry = (SimpleEstateStackEntry * )
5186- MemoryContextAlloc (TopTransactionContext ,
5187- sizeof (SimpleEstateStackEntry ));
5188-
5189- /* But each EState should be a child of its CurTransactionContext */
5190- oldcontext = MemoryContextSwitchTo (CurTransactionContext );
5191- entry -> xact_eval_estate = CreateExecutorState ();
5183+ oldcontext = MemoryContextSwitchTo (TopTransactionContext );
5184+ simple_eval_estate = CreateExecutorState ();
51925185MemoryContextSwitchTo (oldcontext );
5186+ }
51935187
5194- /* Assign a reasonably-unique ID to this EState */
5195- entry -> xact_estate_simple_id = simple_estate_id_counter ++ ;
5196- entry -> xact_subxid = my_subxid ;
5188+ /*
5189+ * Create a child econtext for the current function.
5190+ */
5191+ estate -> eval_econtext = CreateExprContext (simple_eval_estate );
51975192
5198- entry -> next = simple_estate_stack ;
5199- simple_estate_stack = entry ;
5200- }
5193+ /*
5194+ * Make a stack entry so we can clean up the econtext at subxact end.
5195+ * Stack entries are kept in TopTransactionContext for simplicity.
5196+ */
5197+ entry = (SimpleEcontextStackEntry * )
5198+ MemoryContextAlloc (TopTransactionContext ,
5199+ sizeof (SimpleEcontextStackEntry ));
52015200
5202- /* Link plpgsql estate to it */
5203- estate -> eval_estate = entry -> xact_eval_estate ;
5204- estate -> eval_estate_simple_id = entry -> xact_estate_simple_id ;
5201+ entry -> stack_econtext = estate -> eval_econtext ;
5202+ entry -> xact_subxid = GetCurrentSubTransactionId ();
52055203
5206- /* And create a child econtext for the current function */
5207- estate -> eval_econtext = CreateExprContext (estate -> eval_estate );
5204+ entry -> next = simple_econtext_stack ;
5205+ simple_econtext_stack = entry ;
5206+ }
5207+
5208+ /*
5209+ * plpgsql_destroy_econtext --- destroy function's econtext
5210+ *
5211+ * We check that it matches the top stack entry, and destroy the stack
5212+ * entry along with the context.
5213+ */
5214+ static void
5215+ plpgsql_destroy_econtext (PLpgSQL_execstate * estate )
5216+ {
5217+ SimpleEcontextStackEntry * next ;
5218+
5219+ Assert (simple_econtext_stack != NULL );
5220+ Assert (simple_econtext_stack -> stack_econtext == estate -> eval_econtext );
5221+
5222+ next = simple_econtext_stack -> next ;
5223+ pfree (simple_econtext_stack );
5224+ simple_econtext_stack = next ;
5225+
5226+ FreeExprContext (estate -> eval_econtext );
5227+ estate -> eval_econtext = NULL ;
52085228}
52095229
52105230/*
@@ -5220,29 +5240,31 @@ plpgsql_xact_cb(XactEvent event, void *arg)
52205240 * If we are doing a clean transaction shutdown, free the EState (so that
52215241 * any remaining resources will be released correctly). In an abort, we
52225242 * expect the regular abort recovery procedures to release everything of
5223- * interest. We don't need to free the individual stack entries since
5224- * TopTransactionContext is about to go away anyway.
5225- *
5226- * Note: if plpgsql_subxact_cb is doing its job, there should be at most
5227- * one stack entry, but we may as well code this as a loop.
5243+ * interest.
52285244 */
52295245if (event != XACT_EVENT_ABORT )
52305246{
5231- while (simple_estate_stack != NULL )
5232- {
5233- FreeExecutorState (simple_estate_stack -> xact_eval_estate );
5234- simple_estate_stack = simple_estate_stack -> next ;
5235- }
5247+ /* Shouldn't be any econtext stack entries left at commit */
5248+ Assert (simple_econtext_stack == NULL );
5249+
5250+ if (simple_eval_estate )
5251+ FreeExecutorState (simple_eval_estate );
5252+ simple_eval_estate = NULL ;
52365253}
52375254else
5238- simple_estate_stack = NULL ;
5255+ {
5256+ simple_econtext_stack = NULL ;
5257+ simple_eval_estate = NULL ;
5258+ }
52395259}
52405260
52415261/*
52425262 * plpgsql_subxact_cb --- post-subtransaction-commit-or-abort cleanup
52435263 *
5244- * If a simple-expression EState was created in the current subtransaction,
5245- * it has to be cleaned up.
5264+ * Make sure any simple-expression econtexts created in the current
5265+ * subtransaction get cleaned up. We have to do this explicitly because
5266+ * no other code knows which child econtexts of simple_eval_estate belong
5267+ * to which level of subxact.
52465268 */
52475269void
52485270plpgsql_subxact_cb (SubXactEvent event ,SubTransactionId mySubid ,
@@ -5251,16 +5273,15 @@ plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
52515273if (event == SUBXACT_EVENT_START_SUB )
52525274return ;
52535275
5254- if ( simple_estate_stack != NULL &&
5255- simple_estate_stack -> xact_subxid == mySubid )
5276+ while ( simple_econtext_stack != NULL &&
5277+ simple_econtext_stack -> xact_subxid == mySubid )
52565278{
5257- SimpleEstateStackEntry * next ;
5279+ SimpleEcontextStackEntry * next ;
52585280
5259- if (event == SUBXACT_EVENT_COMMIT_SUB )
5260- FreeExecutorState (simple_estate_stack -> xact_eval_estate );
5261- next = simple_estate_stack -> next ;
5262- pfree (simple_estate_stack );
5263- simple_estate_stack = next ;
5281+ FreeExprContext (simple_econtext_stack -> stack_econtext );
5282+ next = simple_econtext_stack -> next ;
5283+ pfree (simple_econtext_stack );
5284+ simple_econtext_stack = next ;
52645285}
52655286}
52665287