Martijn van Oosterhout <kleptog@svana.org> writes:
> On Mon, May 12, 2008 at 11:23:17PM -0600, Josh Tolley wrote:
>> SPI_push();
>> retval =
>> InputFunctionCall(&flinfo, lolVarGetString(returnVal, true),
>> resultTypeIOParam, -1);
>> SPI_pop();
> Won't this cause the return value to be allocated inside a new memory
> block which gets freeds at the SPI_pop?
The SPI_pop in itself is harmless ... the problem is the SPI_finish
further down, which will release all simple palloc's done within the
SPI function context. What he needs is something comparable to this bit
in plpgsql:
/* * If the function's return type isn't by value, copy the value * into upper
executormemory context. */ if (!fcinfo->isnull && !func->fn_retbyval) {
Size len; void *tmp;
len = datumGetSize(estate.retval, false, func->fn_rettyplen); tmp = SPI_palloc(len);
memcpy(tmp, DatumGetPointer(estate.retval), len); estate.retval = PointerGetDatum(tmp);
}
ie, push the data into something allocated with SPI_palloc().
I would bet large amounts of money that the problem is not "new in
8.3.0", either. Perhaps Josh was not testing in an --enable-cassert
(CLOBBER_FREED_MEMORY) build before.
regards, tom lane