Skip to content

Commit 41ec930

Browse files
committed
Add checks to verify that a plpgsql function returning a rowtype is actually
returning the rowtype it's supposed to return. Per reports from David Niblett and Michael Fuhr.
1 parent 75bb2b6 commit 41ec930

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

src/pl/plpgsql/src/pl_exec.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.158 2005/12/28 01:30:01 tgl Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.159 2006/01/03 22:48:10 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -343,10 +343,48 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
343343
{
344344
if (estate.retistuple)
345345
{
346-
/* Copy tuple to upper executor memory, as a tuple Datum */
346+
/*
347+
* We have to check that the returned tuple actually matches
348+
* the expected result type. XXX would be better to cache the
349+
* tupdesc instead of repeating get_call_result_type()
350+
*/
351+
TupleDesc tupdesc;
352+
353+
switch (get_call_result_type(fcinfo, NULL, &tupdesc))
354+
{
355+
case TYPEFUNC_COMPOSITE:
356+
/* got the expected result rowtype, now check it */
357+
if (estate.rettupdesc == NULL ||
358+
!compatible_tupdesc(estate.rettupdesc, tupdesc))
359+
ereport(ERROR,
360+
(errcode(ERRCODE_DATATYPE_MISMATCH),
361+
errmsg("returned record type does not match expected record type")));
362+
break;
363+
case TYPEFUNC_RECORD:
364+
/*
365+
* Failed to determine actual type of RECORD. We could
366+
* raise an error here, but what this means in practice
367+
* is that the caller is expecting any old generic
368+
* rowtype, so we don't really need to be restrictive.
369+
* Pass back the generated result type, instead.
370+
*/
371+
tupdesc = estate.rettupdesc;
372+
if (tupdesc == NULL) /* shouldn't happen */
373+
elog(ERROR, "return type must be a row type");
374+
break;
375+
default:
376+
/* shouldn't get here if retistuple is true ... */
377+
elog(ERROR, "return type must be a row type");
378+
break;
379+
}
380+
381+
/*
382+
* Copy tuple to upper executor memory, as a tuple Datum.
383+
* Make sure it is labeled with the caller-supplied tuple type.
384+
*/
347385
estate.retval =
348386
PointerGetDatum(SPI_returntuple((HeapTuple) (estate.retval),
349-
estate.rettupdesc));
387+
tupdesc));
350388
}
351389
else
352390
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy