33 * procedural language
44 *
55 * IDENTIFICATION
6- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.52.2.1 2002/03/25 07:41:21 tgl Exp $
6+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.52.2.2 2005/06/20 20:45:12 tgl Exp $
77 *
88 * This software is copyrighted by Jan Wieck - Hamburg.
99 *
@@ -2665,12 +2665,6 @@ exec_assign_value(PLpgSQL_execstate * estate,
26652665 */
26662666 var = (PLpgSQL_var * ) target ;
26672667
2668- if (var -> freeval )
2669- {
2670- pfree ((void * ) (var -> value ));
2671- var -> freeval = false;
2672- }
2673-
26742668 newvalue = exec_cast_value (value , valtype , var -> datatype -> typoid ,
26752669 & (var -> datatype -> typinput ),
26762670 var -> datatype -> typelem ,
@@ -2690,23 +2684,28 @@ exec_assign_value(PLpgSQL_execstate * estate,
26902684 if (!var -> datatype -> typbyval && !* isNull )
26912685 {
26922686 if (newvalue == value )
2693- {
2694- int len ;
2687+ newvalue = datumCopy (newvalue ,
2688+ false,
2689+ var -> datatype -> typlen );
2690+ }
26952691
2696- if (var -> datatype -> typlen < 0 )
2697- len = VARSIZE (newvalue );
2698- else
2699- len = var -> datatype -> typlen ;
2700- var -> value = (Datum ) palloc (len );
2701- memcpy ((void * ) (var -> value ), (void * ) newvalue , len );
2702- }
2703- else
2704- var -> value = newvalue ;
2705- var -> freeval = true;
2692+ /*
2693+ * Now free the old value. (We can't do this any earlier
2694+ * because of the possibility that we are assigning the
2695+ * var's old value to it, eg "foo := foo". We could optimize
2696+ * out the assignment altogether in such cases, but it's too
2697+ * infrequent to be worth testing for.)
2698+ */
2699+ if (var -> freeval )
2700+ {
2701+ pfree (DatumGetPointer (var -> value ));
2702+ var -> freeval = false;
27062703 }
2707- else
2708- var -> value = newvalue ;
2704+
2705+ var -> value = newvalue ;
27092706 var -> isnull = * isNull ;
2707+ if (!var -> datatype -> typbyval && !* isNull )
2708+ var -> freeval = true;
27102709 break ;
27112710
27122711 case PLPGSQL_DTYPE_RECFIELD :
@@ -3145,6 +3144,14 @@ exec_move_row(PLpgSQL_execstate * estate,
31453144 */
31463145 if (rec != NULL )
31473146 {
3147+ /*
3148+ * copy input first, just in case it is pointing at variable's value
3149+ */
3150+ if (HeapTupleIsValid (tup ))
3151+ tup = heap_copytuple (tup );
3152+ if (tupdesc )
3153+ tupdesc = CreateTupleDescCopy (tupdesc );
3154+
31483155 if (rec -> freetup )
31493156 {
31503157 heap_freetuple (rec -> tup );
@@ -3158,8 +3165,8 @@ exec_move_row(PLpgSQL_execstate * estate,
31583165
31593166 if (HeapTupleIsValid (tup ))
31603167 {
3161- rec -> tup = heap_copytuple ( tup ) ;
3162- rec -> tupdesc = CreateTupleDescCopy ( tupdesc ) ;
3168+ rec -> tup = tup ;
3169+ rec -> tupdesc = tupdesc ;
31633170 rec -> freetup = true;
31643171 rec -> freetupdesc = true;
31653172 }
0 commit comments