]> granicus.if.org Git - postgresql/commitdiff
Fix ExecMakeTableFunctionResult to verify that all rows returned by a SRF
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 26 Aug 2010 18:54:37 +0000 (18:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 26 Aug 2010 18:54:37 +0000 (18:54 +0000)
returning "record" actually do have the same rowtype.  This is needed because
the parser can't realistically enforce that they will all have the same typmod,
as seen in a recent example from David Wheeler.

Back-patch to 8.0, which is as far back as we have the notion of RECORD
subtypes being distinguished by typmod.  Wheeler's example depends on
8.4-and-up features, but I suspect there may be ways to provoke similar
failures before 8.4.

src/backend/executor/execQual.c

index e30689bba30f7a6776db2b3838ded19f8b41c39a..e88ae58d2b2f8e0fb3ea0f73eb8055f256dffeab 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.264 2010/07/12 17:01:05 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.265 2010/08/26 18:54:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2143,6 +2143,16 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
 
                                td = DatumGetHeapTupleHeader(result);
 
+                               /*
+                                * Verify all returned rows have same subtype; necessary in
+                                * case the type is RECORD.
+                                */
+                               if (HeapTupleHeaderGetTypeId(td) != tupdesc->tdtypeid ||
+                                       HeapTupleHeaderGetTypMod(td) != tupdesc->tdtypmod)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
+                                                        errmsg("rows returned by function are not all of the same row type")));
+
                                /*
                                 * tuplestore_puttuple needs a HeapTuple not a bare
                                 * HeapTupleHeader, but it doesn't need all the fields.