@@ -66,6 +66,15 @@ typedef struct
66
66
* so that we don't have to re-prepare simple expressions on each trip through
67
67
* a function. (We assume the case to optimize is many repetitions of a
68
68
* function within a transaction.)
69
+ *
70
+ * However, there's no value in trying to amortize simple expression setup
71
+ * across multiple executions of a DO block (inline code block), since there
72
+ * can never be any. If we use the shared EState for a DO block, the expr
73
+ * state trees are effectively leaked till end of transaction, and that can
74
+ * add up if the user keeps on submitting DO blocks. Therefore, each DO block
75
+ * has its own simple-expression EState, which is cleaned up at exit from
76
+ * plpgsql_inline_handler(). DO blocks still use the simple_econtext_stack,
77
+ * though, so that subxact abort cleanup does the right thing.
69
78
*/
70
79
typedef struct SimpleEcontextStackEntry
71
80
{
@@ -74,7 +83,7 @@ typedef struct SimpleEcontextStackEntry
74
83
struct SimpleEcontextStackEntry * next ; /* next stack entry up */
75
84
} SimpleEcontextStackEntry ;
76
85
77
- static EState * simple_eval_estate = NULL ;
86
+ static EState * shared_simple_eval_estate = NULL ;
78
87
static SimpleEcontextStackEntry * simple_econtext_stack = NULL ;
79
88
80
89
/************************************************************
@@ -136,7 +145,8 @@ static int exec_stmt_dynfors(PLpgSQL_execstate *estate,
136
145
137
146
static void plpgsql_estate_setup (PLpgSQL_execstate * estate ,
138
147
PLpgSQL_function * func ,
139
- ReturnSetInfo * rsi );
148
+ ReturnSetInfo * rsi ,
149
+ EState * simple_eval_estate );
140
150
static void exec_eval_cleanup (PLpgSQL_execstate * estate );
141
151
142
152
static void exec_prepare_plan (PLpgSQL_execstate * estate ,
@@ -230,10 +240,17 @@ static char *format_preparedparamsdata(PLpgSQL_execstate *estate,
230
240
/* ----------
231
241
* plpgsql_exec_function Called by the call handler for
232
242
* function execution.
243
+ *
244
+ * This is also used to execute inline code blocks (DO blocks). The only
245
+ * difference that this code is aware of is that for a DO block, we want
246
+ * to use a private simple_eval_estate, which is created and passed in by
247
+ * the caller. For regular functions, pass NULL, which implies using
248
+ * shared_simple_eval_estate.
233
249
* ----------
234
250
*/
235
251
Datum
236
- plpgsql_exec_function (PLpgSQL_function * func , FunctionCallInfo fcinfo )
252
+ plpgsql_exec_function (PLpgSQL_function * func , FunctionCallInfo fcinfo ,
253
+ EState * simple_eval_estate )
237
254
{
238
255
PLpgSQL_execstate estate ;
239
256
ErrorContextCallback plerrcontext ;
@@ -243,7 +260,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
243
260
/*
244
261
* Setup the execution state
245
262
*/
246
- plpgsql_estate_setup (& estate , func , (ReturnSetInfo * ) fcinfo -> resultinfo );
263
+ plpgsql_estate_setup (& estate , func , (ReturnSetInfo * ) fcinfo -> resultinfo ,
264
+ simple_eval_estate );
247
265
248
266
/*
249
267
* Setup error traceback support for ereport()
@@ -503,7 +521,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
503
521
/*
504
522
* Setup the execution state
505
523
*/
506
- plpgsql_estate_setup (& estate , func , NULL );
524
+ plpgsql_estate_setup (& estate , func , NULL , NULL );
507
525
508
526
/*
509
527
* Setup error traceback support for ereport()
@@ -782,7 +800,7 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
782
800
/*
783
801
* Setup the execution state
784
802
*/
785
- plpgsql_estate_setup (& estate , func , NULL );
803
+ plpgsql_estate_setup (& estate , func , NULL , NULL );
786
804
787
805
/*
788
806
* Setup error traceback support for ereport()
@@ -3087,7 +3105,8 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
3087
3105
static void
3088
3106
plpgsql_estate_setup (PLpgSQL_execstate * estate ,
3089
3107
PLpgSQL_function * func ,
3090
- ReturnSetInfo * rsi )
3108
+ ReturnSetInfo * rsi ,
3109
+ EState * simple_eval_estate )
3091
3110
{
3092
3111
/* this link will be restored at exit from plpgsql_call_handler */
3093
3112
func -> cur_estate = estate ;
@@ -3126,6 +3145,12 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
3126
3145
estate -> datums = palloc (sizeof (PLpgSQL_datum * ) * estate -> ndatums );
3127
3146
/* caller is expected to fill the datums array */
3128
3147
3148
+ /* set up for use of appropriate simple-expression EState */
3149
+ if (simple_eval_estate )
3150
+ estate -> simple_eval_estate = simple_eval_estate ;
3151
+ else
3152
+ estate -> simple_eval_estate = shared_simple_eval_estate ;
3153
+
3129
3154
estate -> eval_tuptable = NULL ;
3130
3155
estate -> eval_processed = 0 ;
3131
3156
estate -> eval_lastoid = InvalidOid ;
@@ -5148,7 +5173,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
5148
5173
*/
5149
5174
if (expr -> expr_simple_lxid != curlxid )
5150
5175
{
5151
- oldcontext = MemoryContextSwitchTo (simple_eval_estate -> es_query_cxt );
5176
+ oldcontext = MemoryContextSwitchTo (estate -> simple_eval_estate -> es_query_cxt );
5152
5177
expr -> expr_simple_state = ExecInitExpr (expr -> expr_simple_expr , NULL );
5153
5178
expr -> expr_simple_in_use = false;
5154
5179
expr -> expr_simple_lxid = curlxid ;
@@ -6190,8 +6215,8 @@ exec_set_found(PLpgSQL_execstate *estate, bool state)
6190
6215
/*
6191
6216
* plpgsql_create_econtext --- create an eval_econtext for the current function
6192
6217
*
6193
- * We may need to create a new simple_eval_estate too, if there's not one
6194
- * already for the current transaction. The EState will be cleaned up at
6218
+ * We may need to create a new shared_simple_eval_estate too, if there's not
6219
+ * one already for the current transaction. The EState will be cleaned up at
6195
6220
* transaction end.
6196
6221
*/
6197
6222
static void
@@ -6203,20 +6228,25 @@ plpgsql_create_econtext(PLpgSQL_execstate *estate)
6203
6228
* Create an EState for evaluation of simple expressions, if there's not
6204
6229
* one already in the current transaction. The EState is made a child of
6205
6230
* TopTransactionContext so it will have the right lifespan.
6231
+ *
6232
+ * Note that this path is never taken when executing a DO block; the
6233
+ * required EState was already made by plpgsql_inline_handler.
6206
6234
*/
6207
- if (simple_eval_estate == NULL )
6235
+ if (estate -> simple_eval_estate == NULL )
6208
6236
{
6209
6237
MemoryContext oldcontext ;
6210
6238
6239
+ Assert (shared_simple_eval_estate == NULL );
6211
6240
oldcontext = MemoryContextSwitchTo (TopTransactionContext );
6212
- simple_eval_estate = CreateExecutorState ();
6241
+ shared_simple_eval_estate = CreateExecutorState ();
6242
+ estate -> simple_eval_estate = shared_simple_eval_estate ;
6213
6243
MemoryContextSwitchTo (oldcontext );
6214
6244
}
6215
6245
6216
6246
/*
6217
6247
* Create a child econtext for the current function.
6218
6248
*/
6219
- estate -> eval_econtext = CreateExprContext (simple_eval_estate );
6249
+ estate -> eval_econtext = CreateExprContext (estate -> simple_eval_estate );
6220
6250
6221
6251
/*
6222
6252
* Make a stack entry so we can clean up the econtext at subxact end.
@@ -6275,14 +6305,14 @@ plpgsql_xact_cb(XactEvent event, void *arg)
6275
6305
/* Shouldn't be any econtext stack entries left at commit */
6276
6306
Assert (simple_econtext_stack == NULL );
6277
6307
6278
- if (simple_eval_estate )
6279
- FreeExecutorState (simple_eval_estate );
6280
- simple_eval_estate = NULL ;
6308
+ if (shared_simple_eval_estate )
6309
+ FreeExecutorState (shared_simple_eval_estate );
6310
+ shared_simple_eval_estate = NULL ;
6281
6311
}
6282
6312
else if (event == XACT_EVENT_ABORT )
6283
6313
{
6284
6314
simple_econtext_stack = NULL ;
6285
- simple_eval_estate = NULL ;
6315
+ shared_simple_eval_estate = NULL ;
6286
6316
}
6287
6317
}
6288
6318
@@ -6291,8 +6321,7 @@ plpgsql_xact_cb(XactEvent event, void *arg)
6291
6321
*
6292
6322
* Make sure any simple-expression econtexts created in the current
6293
6323
* subtransaction get cleaned up. We have to do this explicitly because
6294
- * no other code knows which child econtexts of simple_eval_estate belong
6295
- * to which level of subxact.
6324
+ * no other code knows which econtexts belong to which level of subxact.
6296
6325
*/
6297
6326
void
6298
6327
plpgsql_subxact_cb (SubXactEvent event , SubTransactionId mySubid ,
0 commit comments