8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.218 2008/08/29 13:02 :33 petere Exp $
11
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.219 2008/09/01 22:30 :33 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -4513,13 +4513,27 @@ exec_move_row(PLpgSQL_execstate *estate,
4513
4513
if (rec != NULL )
4514
4514
{
4515
4515
/*
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
4517
4517
*/
4518
4518
if (HeapTupleIsValid (tup ))
4519
4519
tup = 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
+
4520
4533
if (tupdesc )
4521
4534
tupdesc = CreateTupleDescCopy (tupdesc );
4522
4535
4536
+ /* Free the old value ... */
4523
4537
if (rec -> freetup )
4524
4538
{
4525
4539
heap_freetuple (rec -> tup );
@@ -4531,24 +4545,12 @@ exec_move_row(PLpgSQL_execstate *estate,
4531
4545
rec -> freetupdesc = false;
4532
4546
}
4533
4547
4548
+ /* ... and install the new */
4534
4549
if (HeapTupleIsValid (tup ))
4535
4550
{
4536
4551
rec -> tup = tup ;
4537
4552
rec -> freetup = true;
4538
4553
}
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
- }
4552
4554
else
4553
4555
rec -> tup = NULL ;
4554
4556
@@ -4568,7 +4570,7 @@ exec_move_row(PLpgSQL_execstate *estate,
4568
4570
* attributes of the tuple to the variables the row points to.
4569
4571
*
4570
4572
* 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
4572
4574
* have more fields than we expected if it's from an inheritance-child
4573
4575
* table of the current table, or it might have fewer if the table has had
4574
4576
* columns added by ALTER TABLE. Ignore extra columns and assume NULL for
@@ -4580,6 +4582,7 @@ exec_move_row(PLpgSQL_execstate *estate,
4580
4582
*/
4581
4583
if (row != NULL )
4582
4584
{
4585
+ int td_natts = tupdesc ? tupdesc -> natts : 0 ;
4583
4586
int t_natts ;
4584
4587
int fnum ;
4585
4588
int anum ;
@@ -4602,12 +4605,18 @@ exec_move_row(PLpgSQL_execstate *estate,
4602
4605
4603
4606
var = (PLpgSQL_var * ) (estate -> datums [row -> varnos [fnum ]]);
4604
4607
4605
- while (anum < t_natts && tupdesc -> attrs [anum ]-> attisdropped )
4608
+ while (anum < td_natts && tupdesc -> attrs [anum ]-> attisdropped )
4606
4609
anum ++ ; /* skip dropped column in tuple */
4607
4610
4608
- if (anum < t_natts )
4611
+ if (anum < td_natts )
4609
4612
{
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
+ }
4611
4620
valtype = SPI_gettypeid (tupdesc , anum + 1 );
4612
4621
anum ++ ;
4613
4622
}
0 commit comments