3
3
* procedural language
4
4
*
5
5
* IDENTIFICATION
6
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.9 2010/07/05 09:27:49 heikki Exp $
6
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.10 2010/08/09 18:51:02 tgl Exp $
7
7
*
8
8
* This software is copyrighted by Jan Wieck - Hamburg.
9
9
*
@@ -970,6 +970,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
970
970
*/
971
971
SPI_restore_connection ();
972
972
973
+ /* Must clean up the econtext too */
974
+ exec_eval_cleanup (estate );
975
+
973
976
/* Look for a matching exception handler */
974
977
exceptions = block -> exceptions ;
975
978
for (j = 0 ; j < exceptions -> exceptions_used ; j ++ )
@@ -2067,6 +2070,9 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
2067
2070
*
2068
2071
* NB: the result of the evaluation is no longer valid after this is done,
2069
2072
* unless it is a pass-by-value datatype.
2073
+ *
2074
+ * NB: if you change this code, see also the hacks in exec_assign_value's
2075
+ * PLPGSQL_DTYPE_ARRAYELEM case.
2070
2076
* ----------
2071
2077
*/
2072
2078
static void
@@ -2866,6 +2872,10 @@ exec_assign_expr(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
2866
2872
2867
2873
/* ----------
2868
2874
* exec_assign_value Put a value into a target field
2875
+ *
2876
+ * Note: in some code paths, this may leak memory in the eval_econtext;
2877
+ * we assume that will be cleaned up later by exec_eval_cleanup. We cannot
2878
+ * call exec_eval_cleanup here for fear of destroying the input Datum value.
2869
2879
* ----------
2870
2880
*/
2871
2881
static void
@@ -3131,6 +3141,9 @@ exec_assign_value(PLpgSQL_execstate *estate,
3131
3141
3132
3142
case PLPGSQL_DTYPE_ARRAYELEM :
3133
3143
{
3144
+ /*
3145
+ * Target is an element of an array
3146
+ */
3134
3147
int nsubscripts ;
3135
3148
int i ;
3136
3149
PLpgSQL_expr * subscripts [MAXDIM ];
@@ -3147,10 +3160,19 @@ exec_assign_value(PLpgSQL_execstate *estate,
3147
3160
coerced_value ;
3148
3161
ArrayType * oldarrayval ;
3149
3162
ArrayType * newarrayval ;
3163
+ SPITupleTable * save_eval_tuptable ;
3164
+
3165
+ /*
3166
+ * We need to do subscript evaluation, which might require
3167
+ * evaluating general expressions; and the caller might have
3168
+ * done that too in order to prepare the input Datum. We
3169
+ * have to save and restore the caller's SPI_execute result,
3170
+ * if any.
3171
+ */
3172
+ save_eval_tuptable = estate -> eval_tuptable ;
3173
+ estate -> eval_tuptable = NULL ;
3150
3174
3151
3175
/*
3152
- * Target is an element of an array
3153
- *
3154
3176
* To handle constructs like x[1][2] := something, we have to
3155
3177
* be prepared to deal with a chain of arrayelem datums.
3156
3178
* Chase back to find the base array datum, and save the
@@ -3202,8 +3224,23 @@ exec_assign_value(PLpgSQL_execstate *estate,
3202
3224
subscripts [nsubscripts - 1 - i ],
3203
3225
& subisnull );
3204
3226
havenullsubscript |= subisnull ;
3227
+
3228
+ /*
3229
+ * Clean up in case the subscript expression wasn't simple.
3230
+ * We can't do exec_eval_cleanup, but we can do this much
3231
+ * (which is safe because the integer subscript value is
3232
+ * surely pass-by-value), and we must do it in case the
3233
+ * next subscript expression isn't simple either.
3234
+ */
3235
+ if (estate -> eval_tuptable != NULL )
3236
+ SPI_freetuptable (estate -> eval_tuptable );
3237
+ estate -> eval_tuptable = NULL ;
3205
3238
}
3206
3239
3240
+ /* Now we can restore caller's SPI_execute result if any. */
3241
+ Assert (estate -> eval_tuptable == NULL );
3242
+ estate -> eval_tuptable = save_eval_tuptable ;
3243
+
3207
3244
/*
3208
3245
* Skip the assignment if we have any nulls in the subscripts
3209
3246
* or the righthand side. This is pretty bogus but it
0 commit comments