1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Enhanced error context support in PL/Python

Extract the "while creating return value" and "while modifying trigger
row" parts of some error messages into another layer of error context.
This will simplify the upcoming patch to improve data type support, but
it can stand on its own.
This commit is contained in:
Peter Eisentraut
2009-08-25 12:44:59 +00:00
parent 983d10833e
commit 27c405d61a
8 changed files with 71 additions and 26 deletions

View File

@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.126 2009/08/25 08:14:42 petere Exp $
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.127 2009/08/25 12:44:59 petere Exp $
*
*********************************************************************
*/
@ -339,6 +339,20 @@ plpython_error_callback(void *arg)
errcontext("PL/Python function \"%s\"", PLy_procedure_name(PLy_curr_procedure));
}
static void
plpython_trigger_error_callback(void *arg)
{
if (PLy_curr_procedure)
errcontext("while modifying trigger row");
}
static void
plpython_return_error_callback(void *arg)
{
if (PLy_curr_procedure)
errcontext("while creating return value");
}
Datum
plpython_call_handler(PG_FUNCTION_ARGS)
{
@ -506,6 +520,11 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
Datum *volatile modvalues;
char *volatile modnulls;
TupleDesc tupdesc;
ErrorContextCallback plerrcontext;
plerrcontext.callback = plpython_trigger_error_callback;
plerrcontext.previous = error_context_stack;
error_context_stack = &plerrcontext;
plntup = plkeys = platt = plval = plstr = NULL;
modattrs = NULL;
@ -563,7 +582,7 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
{
plstr = PyObject_Str(plval);
if (!plstr)
PLy_elog(ERROR, "could not compute string representation of Python object, while modifying trigger row");
PLy_elog(ERROR, "could not create string representation of Python object");
src = PyString_AsString(plstr);
modvalues[i] =
@ -620,6 +639,8 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
pfree(modvalues);
pfree(modnulls);
error_context_stack = plerrcontext.previous;
return rtup;
}
@ -811,6 +832,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
PyObject *volatile plrv = NULL;
PyObject *volatile plrv_so = NULL;
char *plrv_sc;
ErrorContextCallback plerrcontext;
PG_TRY();
{
@ -901,6 +923,10 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
}
}
plerrcontext.callback = plpython_return_error_callback;
plerrcontext.previous = error_context_stack;
error_context_stack = &plerrcontext;
/*
* If the function is declared to return void, the Python return value
* must be None. For void-returning functions, we also treat a None
@ -959,7 +985,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
fcinfo->isnull = false;
plrv_so = PyObject_Str(plrv);
if (!plrv_so)
PLy_elog(ERROR, "could not create string representation of Python object, while creating return value");
PLy_elog(ERROR, "could not create string representation of Python object");
plrv_sc = PyString_AsString(plrv_so);
rv = InputFunctionCall(&proc->result.out.d.typfunc,
plrv_sc,
@ -977,6 +1003,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
}
PG_END_TRY();
error_context_stack = plerrcontext.previous;
Py_XDECREF(plargs);
Py_DECREF(plrv);
Py_XDECREF(plrv_so);