diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2017-10-31 10:49:36 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2017-11-18 13:39:53 -0500 |
commit | d0aa965c0a0ac2ff7906ae1b1dad50a7952efa56 (patch) | |
tree | 0a464efb705e7df59aefb68bb7cbcba3772fb9fa /src/pl/plpython/plpy_spi.c | |
parent | 976a1a48fc35cde3c750982be64f872c4de4d343 (diff) | |
download | postgresql-d0aa965c0a0ac2ff7906ae1b1dad50a7952efa56.tar.gz postgresql-d0aa965c0a0ac2ff7906ae1b1dad50a7952efa56.zip |
Consistently catch errors from Python _New() functions
Python Py*_New() functions can fail and return NULL in out-of-memory
conditions. The previous code handled that inconsistently or not at
all. This change organizes that better. If we are in a function that
is called from Python, we just check for failure and return NULL
ourselves, which will cause any exception information to be passed up.
If we are called from PostgreSQL, we consistently create an "out of
memory" error.
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Diffstat (limited to 'src/pl/plpython/plpy_spi.c')
-rw-r--r-- | src/pl/plpython/plpy_spi.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index 69eb6b39f67..ade27f39242 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -360,6 +360,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status) volatile MemoryContext oldcontext; result = (PLyResultObject *) PLy_result_new(); + if (!result) + return NULL; Py_DECREF(result->status); result->status = PyInt_FromLong(status); @@ -409,17 +411,24 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status) Py_DECREF(result->rows); result->rows = PyList_New(rows); - - PLy_input_setup_tuple(&ininfo, tuptable->tupdesc, - exec_ctx->curr_proc); - - for (i = 0; i < rows; i++) + if (!result->rows) { - PyObject *row = PLy_input_from_tuple(&ininfo, - tuptable->vals[i], - tuptable->tupdesc); + Py_DECREF(result); + result = NULL; + } + else + { + PLy_input_setup_tuple(&ininfo, tuptable->tupdesc, + exec_ctx->curr_proc); + + for (i = 0; i < rows; i++) + { + PyObject *row = PLy_input_from_tuple(&ininfo, + tuptable->vals[i], + tuptable->tupdesc); - PyList_SetItem(result->rows, i, row); + PyList_SetItem(result->rows, i, row); + } } } |