3
3
* procedural language
4
4
*
5
5
* IDENTIFICATION
6
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.144 2005/06/14 06:43:14 neilc Exp $
6
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.145 2005/06/20 20:44:44 tgl Exp $
7
7
*
8
8
* This software is copyrighted by Jan Wieck - Hamburg.
9
9
*
@@ -182,6 +182,7 @@ static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2);
182
182
static void exec_set_found (PLpgSQL_execstate * estate , bool state );
183
183
static void free_var (PLpgSQL_var * var );
184
184
185
+
185
186
/* ----------
186
187
* plpgsql_exec_function Called by the call handler for
187
188
* function execution.
@@ -874,13 +875,15 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
874
875
PLpgSQL_var * state_var ;
875
876
PLpgSQL_var * errm_var ;
876
877
877
- state_var = (PLpgSQL_var * ) (estate -> datums [block -> exceptions -> sqlstate_varno ]);
878
+ state_var = (PLpgSQL_var * )
879
+ estate -> datums [block -> exceptions -> sqlstate_varno ];
878
880
state_var -> value = DirectFunctionCall1 (textin ,
879
881
CStringGetDatum (unpack_sql_state (edata -> sqlerrcode )));
880
882
state_var -> freeval = true;
881
883
state_var -> isnull = false;
882
884
883
- errm_var = (PLpgSQL_var * ) (estate -> datums [block -> exceptions -> sqlerrm_varno ]);
885
+ errm_var = (PLpgSQL_var * )
886
+ estate -> datums [block -> exceptions -> sqlerrm_varno ];
884
887
errm_var -> value = DirectFunctionCall1 (textin ,
885
888
CStringGetDatum (edata -> message ));
886
889
errm_var -> freeval = true;
@@ -2862,8 +2865,6 @@ exec_assign_value(PLpgSQL_execstate *estate,
2862
2865
errmsg ("NULL cannot be assigned to variable \"%s\" declared NOT NULL" ,
2863
2866
var -> refname )));
2864
2867
2865
- free_var (var );
2866
-
2867
2868
/*
2868
2869
* If type is by-reference, make sure we have a freshly
2869
2870
* palloc'd copy; the originally passed value may not live
@@ -2874,16 +2875,24 @@ exec_assign_value(PLpgSQL_execstate *estate,
2874
2875
if (!var -> datatype -> typbyval && !* isNull )
2875
2876
{
2876
2877
if (newvalue == value )
2877
- var -> value = datumCopy (newvalue ,
2878
- false,
2879
- var -> datatype -> typlen );
2880
- else
2881
- var -> value = newvalue ;
2882
- var -> freeval = true;
2878
+ newvalue = datumCopy (newvalue ,
2879
+ false,
2880
+ var -> datatype -> typlen );
2883
2881
}
2884
- else
2885
- var -> value = newvalue ;
2882
+
2883
+ /*
2884
+ * Now free the old value. (We can't do this any earlier
2885
+ * because of the possibility that we are assigning the
2886
+ * var's old value to it, eg "foo := foo". We could optimize
2887
+ * out the assignment altogether in such cases, but it's too
2888
+ * infrequent to be worth testing for.)
2889
+ */
2890
+ free_var (var );
2891
+
2892
+ var -> value = newvalue ;
2886
2893
var -> isnull = * isNull ;
2894
+ if (!var -> datatype -> typbyval && !* isNull )
2895
+ var -> freeval = true;
2887
2896
break ;
2888
2897
}
2889
2898
@@ -3740,6 +3749,14 @@ exec_move_row(PLpgSQL_execstate *estate,
3740
3749
*/
3741
3750
if (rec != NULL )
3742
3751
{
3752
+ /*
3753
+ * copy input first, just in case it is pointing at variable's value
3754
+ */
3755
+ if (HeapTupleIsValid (tup ))
3756
+ tup = heap_copytuple (tup );
3757
+ if (tupdesc )
3758
+ tupdesc = CreateTupleDescCopy (tupdesc );
3759
+
3743
3760
if (rec -> freetup )
3744
3761
{
3745
3762
heap_freetuple (rec -> tup );
@@ -3753,7 +3770,7 @@ exec_move_row(PLpgSQL_execstate *estate,
3753
3770
3754
3771
if (HeapTupleIsValid (tup ))
3755
3772
{
3756
- rec -> tup = heap_copytuple ( tup ) ;
3773
+ rec -> tup = tup ;
3757
3774
rec -> freetup = true;
3758
3775
}
3759
3776
else if (tupdesc )
@@ -3774,7 +3791,7 @@ exec_move_row(PLpgSQL_execstate *estate,
3774
3791
3775
3792
if (tupdesc )
3776
3793
{
3777
- rec -> tupdesc = CreateTupleDescCopy ( tupdesc ) ;
3794
+ rec -> tupdesc = tupdesc ;
3778
3795
rec -> freetupdesc = true;
3779
3796
}
3780
3797
else
0 commit comments