From: Tom Lane Date: Tue, 3 Jan 2006 22:48:28 +0000 (+0000) Subject: Add checks to verify that a plpgsql function returning a rowtype is actually X-Git-Tag: REL8_0_6~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dea775eb25e0f7b0f0b14e83d88041954f469c29;p=postgresql 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. --- diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 0470a14f99..9d17ead258 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.3 2005/06/20 22:51:49 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.4 2006/01/03 22:48:28 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -382,10 +382,37 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo) { if (estate.retistuple) { - /* Copy tuple to upper executor memory, as a tuple Datum */ + /* + * We have to check that the returned tuple actually matches + * the expected result type. + */ + ReturnSetInfo *rsi = estate.rsi; + TupleDesc tupdesc; + + if (rsi && IsA(rsi, ReturnSetInfo) && + rsi->expectedDesc != NULL) + tupdesc = rsi->expectedDesc; + else if (estate.fn_rettype == RECORDOID) + { + /* assume caller can handle any record type */ + tupdesc = estate.rettupdesc; + } + else + tupdesc = lookup_rowtype_tupdesc(estate.fn_rettype, -1); + /* got the expected result rowtype, now check it */ + if (estate.rettupdesc == NULL || + !compatible_tupdesc(estate.rettupdesc, tupdesc)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("returned record type does not match expected record type"))); + + /* + * Copy tuple to upper executor memory, as a tuple Datum. + * Make sure it is labeled with the caller-supplied tuple type. + */ estate.retval = PointerGetDatum(SPI_returntuple((HeapTuple) (estate.retval), - estate.rettupdesc)); + tupdesc)); } else {