88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.218 2008/08/29 13:02 :33petere Exp $
11+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.219 2008/09/01 22:30 :33tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -4513,13 +4513,27 @@ exec_move_row(PLpgSQL_execstate *estate,
45134513if (rec != NULL )
45144514{
45154515/*
4516- *copy input first, just in case it is pointing at variable's value
4516+ *Copy input first, just in case it is pointing at variable's value
45174517 */
45184518if (HeapTupleIsValid (tup ))
45194519tup = heap_copytuple (tup );
4520+ else if (tupdesc )
4521+ {
4522+ /* If we have a tupdesc but no data, form an all-nulls tuple */
4523+ char * nulls ;
4524+
4525+ nulls = (char * )palloc (tupdesc -> natts * sizeof (char ));
4526+ memset (nulls ,'n' ,tupdesc -> natts * sizeof (char ));
4527+
4528+ tup = heap_formtuple (tupdesc ,NULL ,nulls );
4529+
4530+ pfree (nulls );
4531+ }
4532+
45204533if (tupdesc )
45214534tupdesc = CreateTupleDescCopy (tupdesc );
45224535
4536+ /* Free the old value ... */
45234537if (rec -> freetup )
45244538{
45254539heap_freetuple (rec -> tup );
@@ -4531,24 +4545,12 @@ exec_move_row(PLpgSQL_execstate *estate,
45314545rec -> freetupdesc = false;
45324546}
45334547
4548+ /* ... and install the new */
45344549if (HeapTupleIsValid (tup ))
45354550{
45364551rec -> tup = tup ;
45374552rec -> freetup = true;
45384553}
4539- else if (tupdesc )
4540- {
4541- /* If we have a tupdesc but no data, form an all-nulls tuple */
4542- char * nulls ;
4543-
4544- nulls = (char * )palloc (tupdesc -> natts * sizeof (char ));
4545- memset (nulls ,'n' ,tupdesc -> natts * sizeof (char ));
4546-
4547- rec -> tup = heap_formtuple (tupdesc ,NULL ,nulls );
4548- rec -> freetup = true;
4549-
4550- pfree (nulls );
4551- }
45524554else
45534555rec -> tup = NULL ;
45544556
@@ -4568,7 +4570,7 @@ exec_move_row(PLpgSQL_execstate *estate,
45684570 * attributes of the tuple to the variables the row points to.
45694571 *
45704572 * NOTE: this code used to demand row->nfields ==
4571- * HeapTupleHeaderGetNatts(tup->t_data, but that's wrong. The tuple might
4573+ * HeapTupleHeaderGetNatts(tup->t_data) , but that's wrong. The tuple might
45724574 * have more fields than we expected if it's from an inheritance-child
45734575 * table of the current table, or it might have fewer if the table has had
45744576 * columns added by ALTER TABLE. Ignore extra columns and assume NULL for
@@ -4580,6 +4582,7 @@ exec_move_row(PLpgSQL_execstate *estate,
45804582 */
45814583if (row != NULL )
45824584{
4585+ int td_natts = tupdesc ?tupdesc -> natts :0 ;
45834586int t_natts ;
45844587int fnum ;
45854588int anum ;
@@ -4602,12 +4605,18 @@ exec_move_row(PLpgSQL_execstate *estate,
46024605
46034606var = (PLpgSQL_var * ) (estate -> datums [row -> varnos [fnum ]]);
46044607
4605- while (anum < t_natts && tupdesc -> attrs [anum ]-> attisdropped )
4608+ while (anum < td_natts && tupdesc -> attrs [anum ]-> attisdropped )
46064609anum ++ ;/* skip dropped column in tuple */
46074610
4608- if (anum < t_natts )
4611+ if (anum < td_natts )
46094612{
4610- value = SPI_getbinval (tup ,tupdesc ,anum + 1 ,& isnull );
4613+ if (anum < t_natts )
4614+ value = SPI_getbinval (tup ,tupdesc ,anum + 1 ,& isnull );
4615+ else
4616+ {
4617+ value = (Datum )0 ;
4618+ isnull = true;
4619+ }
46114620valtype = SPI_gettypeid (tupdesc ,anum + 1 );
46124621anum ++ ;
46134622}