Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8bb3c8f

Browse files
committed
exec_move_row() should be more forgiving of tuples with a different
number of columns than it was expecting, for reasons that are now documented in the code...
1 parent e2004df commit 8bb3c8f

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

src/pl/plpgsql/src/pl_exec.c

+33-32
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.40 2001/03/22 06:16:21 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.41 2001/04/30 20:05:40 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -2569,8 +2569,7 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate,
25692569

25702570

25712571
/* ----------
2572-
* exec_move_row Move one tuples values into a
2573-
* record or row
2572+
* exec_move_row Move one tuple's values into a record or row
25742573
* ----------
25752574
*/
25762575
static void
@@ -2579,12 +2578,6 @@ exec_move_row(PLpgSQL_execstate * estate,
25792578
PLpgSQL_row * row,
25802579
HeapTuple tup, TupleDesc tupdesc)
25812580
{
2582-
PLpgSQL_var *var;
2583-
int i;
2584-
Datum value;
2585-
Oid valtype;
2586-
bool isnull;
2587-
25882581
/*
25892582
* Record is simple - just put the tuple and its descriptor into the
25902583
* record
@@ -2605,41 +2598,49 @@ exec_move_row(PLpgSQL_execstate * estate,
26052598
return;
26062599
}
26072600

2608-
26092601
/*
2610-
* Row is a bit more complicated in that we assign the single
2611-
* attributes of the query to the variables the row points to.
2602+
* Row is a bit more complicated in that we assign the individual
2603+
* attributes of the tuple to the variables the row points to.
2604+
*
2605+
* NOTE: this code used to demand row->nfields == tup->t_data->t_natts,
2606+
* but that's wrong. The tuple might have more fields than we expected
2607+
* if it's from an inheritance-child table of the current table, or it
2608+
* might have fewer if the table has had columns added by ALTER TABLE.
2609+
* Ignore extra columns and assume NULL for missing columns, the same
2610+
* as heap_getattr would do.
26122611
*/
26132612
if (row != NULL)
26142613
{
2614+
int t_natts;
2615+
int i;
2616+
26152617
if (HeapTupleIsValid(tup))
2618+
t_natts = tup->t_data->t_natts;
2619+
else
2620+
t_natts = 0;
2621+
2622+
for (i = 0; i < row->nfields; i++)
26162623
{
2617-
if (row->nfields != tup->t_data->t_natts)
2618-
{
2619-
elog(ERROR, "query didn't return correct # of attributes for %s",
2620-
row->refname);
2621-
}
2624+
PLpgSQL_var *var;
2625+
Datum value;
2626+
bool isnull;
2627+
Oid valtype;
26222628

2623-
for (i = 0; i < row->nfields; i++)
2629+
var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]);
2630+
if (i < t_natts)
26242631
{
2625-
var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]);
2626-
2627-
valtype = SPI_gettypeid(tupdesc, i + 1);
26282632
value = SPI_getbinval(tup, tupdesc, i + 1, &isnull);
2629-
exec_assign_value(estate, estate->datums[row->varnos[i]],
2630-
value, valtype, &isnull);
2631-
26322633
}
2633-
}
2634-
else
2635-
{
2636-
for (i = 0; i < row->nfields; i++)
2634+
else
26372635
{
2638-
bool nullval = true;
2639-
2640-
exec_assign_value(estate, estate->datums[row->varnos[i]],
2641-
(Datum) 0, 0, &nullval);
2636+
value = (Datum) 0;
2637+
isnull = true;
26422638
}
2639+
/* tupdesc should have entries for all columns I expect... */
2640+
valtype = SPI_gettypeid(tupdesc, i + 1);
2641+
2642+
exec_assign_value(estate, estate->datums[row->varnos[i]],
2643+
value, valtype, &isnull);
26432644
}
26442645

26452646
return;

0 commit comments

Comments
 (0)