]> granicus.if.org Git - postgresql/commitdiff
exec_move_row() should be more forgiving of tuples with a different
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Apr 2001 20:05:40 +0000 (20:05 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Apr 2001 20:05:40 +0000 (20:05 +0000)
number of columns than it was expecting, for reasons that are now
documented in the code...

src/pl/plpgsql/src/pl_exec.c

index 7a65b6512d7d8edcc335168da845f44ed6f89785..566bae70167167e9c609386d47e3b01296769861 100644 (file)
@@ -3,7 +3,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.40 2001/03/22 06:16:21 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.41 2001/04/30 20:05:40 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -2569,8 +2569,7 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate,
 
 
 /* ----------
- * exec_move_row                       Move one tuples values into a
- *                                     record or row
+ * exec_move_row                       Move one tuple's values into a record or row
  * ----------
  */
 static void
@@ -2579,12 +2578,6 @@ exec_move_row(PLpgSQL_execstate * estate,
                          PLpgSQL_row * row,
                          HeapTuple tup, TupleDesc tupdesc)
 {
-       PLpgSQL_var *var;
-       int                     i;
-       Datum           value;
-       Oid                     valtype;
-       bool            isnull;
-
        /*
         * Record is simple - just put the tuple and its descriptor into the
         * record
@@ -2605,41 +2598,49 @@ exec_move_row(PLpgSQL_execstate * estate,
                return;
        }
 
-
        /*
-        * Row is a bit more complicated in that we assign the single
-        * attributes of the query to the variables the row points to.
+        * Row is a bit more complicated in that we assign the individual
+        * attributes of the tuple to the variables the row points to.
+        *
+        * NOTE: this code used to demand row->nfields == tup->t_data->t_natts,
+        * but that's wrong.  The tuple might have more fields than we expected
+        * if it's from an inheritance-child table of the current table, or it
+        * might have fewer if the table has had columns added by ALTER TABLE.
+        * Ignore extra columns and assume NULL for missing columns, the same
+        * as heap_getattr would do.
         */
        if (row != NULL)
        {
+               int                     t_natts;
+               int                     i;
+
                if (HeapTupleIsValid(tup))
+                       t_natts = tup->t_data->t_natts;
+               else
+                       t_natts = 0;
+
+               for (i = 0; i < row->nfields; i++)
                {
-                       if (row->nfields != tup->t_data->t_natts)
-                       {
-                               elog(ERROR, "query didn't return correct # of attributes for %s",
-                                        row->refname);
-                       }
+                       PLpgSQL_var *var;
+                       Datum           value;
+                       bool            isnull;
+                       Oid                     valtype;
 
-                       for (i = 0; i < row->nfields; i++)
+                       var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]);
+                       if (i < t_natts)
                        {
-                               var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]);
-
-                               valtype = SPI_gettypeid(tupdesc, i + 1);
                                value = SPI_getbinval(tup, tupdesc, i + 1, &isnull);
-                               exec_assign_value(estate, estate->datums[row->varnos[i]],
-                                                                 value, valtype, &isnull);
-
                        }
-               }
-               else
-               {
-                       for (i = 0; i < row->nfields; i++)
+                       else
                        {
-                               bool            nullval = true;
-
-                               exec_assign_value(estate, estate->datums[row->varnos[i]],
-                                                                 (Datum) 0, 0, &nullval);
+                               value = (Datum) 0;
+                               isnull = true;
                        }
+                       /* tupdesc should have entries for all columns I expect... */
+                       valtype = SPI_gettypeid(tupdesc, i + 1);
+
+                       exec_assign_value(estate, estate->datums[row->varnos[i]],
+                                                         value, valtype, &isnull);
                }
 
                return;