diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2012-05-02 20:59:51 +0300 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2012-05-02 20:59:51 +0300 |
commit | 52aa334fcd5a9d230be7e8fb964d94c6c4e63dc7 (patch) | |
tree | 1bf7fe4cd01a6d127c6271c5d81b4e5199bf6107 /src/pl/plpython/plpy_spi.c | |
parent | e9605a039b60350003daf8a5b3c0c10993994b60 (diff) | |
download | postgresql-52aa334fcd5a9d230be7e8fb964d94c6c4e63dc7.tar.gz postgresql-52aa334fcd5a9d230be7e8fb964d94c6c4e63dc7.zip |
PL/Python: Fix crash in functions returning SETOF and using SPI
Allocate PLyResultObject.tupdesc in TopMemoryContext, because its
lifetime is the lifetime of the Python object and it shouldn't be
freed by some other memory context, such as one controlled by SPI. We
trust that the Python object will clean up its own memory.
Before, this would crash the included regression test case by trying
to use memory that was already freed.
reported by Asif Naeem, analysis by Tom Lane
Diffstat (limited to 'src/pl/plpython/plpy_spi.c')
-rw-r--r-- | src/pl/plpython/plpy_spi.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index cde3c08f967..4bc3d96d589 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -11,6 +11,7 @@ #include "executor/spi_priv.h" #include "mb/pg_wchar.h" #include "parser/parse_type.h" +#include "utils/memutils.h" #include "utils/syscache.h" #include "plpython.h" @@ -403,7 +404,17 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status) oldcontext = CurrentMemoryContext; PG_TRY(); { + MemoryContext oldcontext2; + + /* + * Save tuple descriptor for later use by result set metadata + * functions. Save it in TopMemoryContext so that it survives + * outside of an SPI context. We trust that PLy_result_dealloc() + * will clean it up when the time is right. + */ + oldcontext2 = MemoryContextSwitchTo(TopMemoryContext); result->tupdesc = CreateTupleDescCopy(tuptable->tupdesc); + MemoryContextSwitchTo(oldcontext2); if (rows) { |