Content-Length: 779922 | pFad | http://github.com/tonybelloni/postgres/commit/d0aa965c0a0ac2ff7906ae1b1dad50a7952efa56

68 Consistently catch errors from Python _New() functions · tonybelloni/postgres@d0aa965 · GitHub
Skip to content

Commit d0aa965

Browse files
committed
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>
1 parent 976a1a4 commit d0aa965

10 files changed

+70
-23
lines changed

contrib/hstore_plpython/hstore_plpython.c

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ hstore_to_plpython(PG_FUNCTION_ARGS)
9393
PyObject *dict;
9494

9595
dict = PyDict_New();
96+
if (!dict)
97+
ereport(ERROR,
98+
(errcode(ERRCODE_OUT_OF_MEMORY),
99+
errmsg("out of memory")));
96100

97101
for (i = 0; i < count; i++)
98102
{

contrib/ltree_plpython/ltree_plpython.c

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ ltree_to_plpython(PG_FUNCTION_ARGS)
4646
ltree_level *curlevel;
4747

4848
list = PyList_New(in->numlevel);
49+
if (!list)
50+
ereport(ERROR,
51+
(errcode(ERRCODE_OUT_OF_MEMORY),
52+
errmsg("out of memory")));
4953

5054
curlevel = LTREE_FIRST(in);
5155
for (i = 0; i < in->numlevel; i++)

src/pl/plpython/plpy_cursorobject.c

+16-9
Original file line numberDiff line numberDiff line change
@@ -457,17 +457,24 @@ PLy_cursor_fetch(PyObject *self, PyObject *args)
457457

458458
Py_DECREF(ret->rows);
459459
ret->rows = PyList_New(SPI_processed);
460-
461-
PLy_input_setup_tuple(&cursor->result, SPI_tuptable->tupdesc,
462-
exec_ctx->curr_proc);
463-
464-
for (i = 0; i < SPI_processed; i++)
460+
if (!ret->rows)
465461
{
466-
PyObject *row = PLy_input_from_tuple(&cursor->result,
467-
SPI_tuptable->vals[i],
468-
SPI_tuptable->tupdesc);
462+
Py_DECREF(ret);
463+
ret = NULL;
464+
}
465+
else
466+
{
467+
PLy_input_setup_tuple(&cursor->result, SPI_tuptable->tupdesc,
468+
exec_ctx->curr_proc);
469+
470+
for (i = 0; i < SPI_processed; i++)
471+
{
472+
PyObject *row = PLy_input_from_tuple(&cursor->result,
473+
SPI_tuptable->vals[i],
474+
SPI_tuptable->tupdesc);
469475

470-
PyList_SetItem(ret->rows, i, row);
476+
PyList_SetItem(ret->rows, i, row);
477+
}
471478
}
472479
}
473480

src/pl/plpython/plpy_exec.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,9 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
420420
PG_TRY();
421421
{
422422
args = PyList_New(proc->nargs);
423+
if (!args)
424+
return NULL;
425+
423426
for (i = 0; i < proc->nargs; i++)
424427
{
425428
PLyDatumToOb *arginfo = &proc->args[i];
@@ -693,7 +696,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
693696
{
694697
pltdata = PyDict_New();
695698
if (!pltdata)
696-
PLy_elog(ERROR, "could not create new dictionary while building trigger arguments");
699+
return NULL;
697700

698701
pltname = PyString_FromString(tdata->tg_trigger->tgname);
699702
PyDict_SetItemString(pltdata, "name", pltname);
@@ -826,6 +829,11 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
826829
PyObject *pltarg;
827830

828831
pltargs = PyList_New(tdata->tg_trigger->tgnargs);
832+
if (!pltargs)
833+
{
834+
Py_DECREF(pltdata);
835+
return NULL;
836+
}
829837
for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
830838
{
831839
pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]);

src/pl/plpython/plpy_main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ PLy_init_interp(void)
167167
PLy_interp_globals = PyModule_GetDict(mainmod);
168168
PLy_interp_safe_globals = PyDict_New();
169169
if (PLy_interp_safe_globals == NULL)
170-
PLy_elog(ERROR, "could not create globals");
170+
PLy_elog(ERROR, NULL);
171171
PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
172172
Py_DECREF(mainmod);
173173
if (PLy_interp_globals == NULL || PyErr_Occurred())

src/pl/plpython/plpy_plpymodule.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ PLy_create_exception(char *name, PyObject *base, PyObject *dict,
233233

234234
exc = PyErr_NewException(name, base, dict);
235235
if (exc == NULL)
236-
PLy_elog(ERROR, "could not create exception \"%s\"", name);
236+
PLy_elog(ERROR, NULL);
237237

238238
/*
239239
* PyModule_AddObject does not add a refcount to the object, for some odd
@@ -268,7 +268,7 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base)
268268
PyObject *dict = PyDict_New();
269269

270270
if (dict == NULL)
271-
PLy_elog(ERROR, "could not generate SPI exceptions");
271+
PLy_elog(ERROR, NULL);
272272

273273
sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate));
274274
if (sqlstate == NULL)

src/pl/plpython/plpy_procedure.c

+2
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ PLy_procedure_compile(PLyProcedure *proc, const char *src)
368368
* all functions
369369
*/
370370
proc->statics = PyDict_New();
371+
if (!proc->statics)
372+
PLy_elog(ERROR, NULL);
371373
PyDict_SetItemString(proc->globals, "SD", proc->statics);
372374

373375
/*

src/pl/plpython/plpy_resultobject.c

+11
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ PLy_result_new(void)
112112
ob->nrows = PyInt_FromLong(-1);
113113
ob->rows = PyList_New(0);
114114
ob->tupdesc = NULL;
115+
if (!ob->rows)
116+
{
117+
Py_DECREF(ob);
118+
return NULL;
119+
}
115120

116121
return (PyObject *) ob;
117122
}
@@ -147,6 +152,8 @@ PLy_result_colnames(PyObject *self, PyObject *unused)
147152
}
148153

149154
list = PyList_New(ob->tupdesc->natts);
155+
if (!list)
156+
return NULL;
150157
for (i = 0; i < ob->tupdesc->natts; i++)
151158
{
152159
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
@@ -171,6 +178,8 @@ PLy_result_coltypes(PyObject *self, PyObject *unused)
171178
}
172179

173180
list = PyList_New(ob->tupdesc->natts);
181+
if (!list)
182+
return NULL;
174183
for (i = 0; i < ob->tupdesc->natts; i++)
175184
{
176185
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
@@ -195,6 +204,8 @@ PLy_result_coltypmods(PyObject *self, PyObject *unused)
195204
}
196205

197206
list = PyList_New(ob->tupdesc->natts);
207+
if (!list)
208+
return NULL;
198209
for (i = 0; i < ob->tupdesc->natts; i++)
199210
{
200211
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);

src/pl/plpython/plpy_spi.c

+18-9
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status)
360360
volatile MemoryContext oldcontext;
361361

362362
result = (PLyResultObject *) PLy_result_new();
363+
if (!result)
364+
return NULL;
363365
Py_DECREF(result->status);
364366
result->status = PyInt_FromLong(status);
365367

@@ -409,17 +411,24 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status)
409411

410412
Py_DECREF(result->rows);
411413
result->rows = PyList_New(rows);
412-
413-
PLy_input_setup_tuple(&ininfo, tuptable->tupdesc,
414-
exec_ctx->curr_proc);
415-
416-
for (i = 0; i < rows; i++)
414+
if (!result->rows)
417415
{
418-
PyObject *row = PLy_input_from_tuple(&ininfo,
419-
tuptable->vals[i],
420-
tuptable->tupdesc);
416+
Py_DECREF(result);
417+
result = NULL;
418+
}
419+
else
420+
{
421+
PLy_input_setup_tuple(&ininfo, tuptable->tupdesc,
422+
exec_ctx->curr_proc);
423+
424+
for (i = 0; i < rows; i++)
425+
{
426+
PyObject *row = PLy_input_from_tuple(&ininfo,
427+
tuptable->vals[i],
428+
tuptable->tupdesc);
421429

422-
PyList_SetItem(result->rows, i, row);
430+
PyList_SetItem(result->rows, i, row);
431+
}
423432
}
424433
}
425434

src/pl/plpython/plpy_typeio.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ PLyList_FromArray_recurse(PLyDatumToOb *elm, int *dims, int ndim, int dim,
718718
PyObject *list;
719719

720720
list = PyList_New(dims[dim]);
721+
if (!list)
722+
return NULL;
721723

722724
if (dim < ndim - 1)
723725
{
@@ -826,7 +828,7 @@ PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc)
826828

827829
dict = PyDict_New();
828830
if (dict == NULL)
829-
PLy_elog(ERROR, "could not create new dictionary");
831+
return NULL;
830832

831833
PG_TRY();
832834
{

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tonybelloni/postgres/commit/d0aa965c0a0ac2ff7906ae1b1dad50a7952efa56

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy