Commit 418df3a5 authored by Peter Eisentraut's avatar Peter Eisentraut

Also save the error detail in SPIError

The temporarily broken plpython_unicode test shows a case where this
is used.

Do remaining fix-ups on the expected files at the same time.
parent ddf8c168
...@@ -41,7 +41,7 @@ SELECT * FROM unicode_test; ...@@ -41,7 +41,7 @@ SELECT * FROM unicode_test;
SELECT unicode_plan1(); SELECT unicode_plan1();
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
CONTEXT: PL/Python function "unicode_plan1" CONTEXT: PL/Python function "unicode_plan1"
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding ERROR: PL/Python: plpy.SPIError: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
DETAIL: UnicodeError: ASCII encoding error: ordinal not in range(128) DETAIL: UnicodeError: ASCII encoding error: ordinal not in range(128)
CONTEXT: PL/Python function "unicode_plan1" CONTEXT: PL/Python function "unicode_plan1"
SELECT unicode_plan2(); SELECT unicode_plan2();
......
...@@ -42,6 +42,7 @@ SELECT unicode_plan1(); ...@@ -42,6 +42,7 @@ SELECT unicode_plan1();
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
CONTEXT: PL/Python function "unicode_plan1" CONTEXT: PL/Python function "unicode_plan1"
ERROR: PL/Python: plpy.SPIError: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding ERROR: PL/Python: plpy.SPIError: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
CONTEXT: PL/Python function "unicode_plan1" CONTEXT: PL/Python function "unicode_plan1"
SELECT unicode_plan2(); SELECT unicode_plan2();
unicode_plan2 unicode_plan2
......
...@@ -294,7 +294,7 @@ static char *PLy_procedure_name(PLyProcedure *); ...@@ -294,7 +294,7 @@ static char *PLy_procedure_name(PLyProcedure *);
static void static void
PLy_elog(int, const char *,...) PLy_elog(int, const char *,...)
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));
static void PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position); static void PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position);
static char *PLy_traceback(int *); static char *PLy_traceback(int *);
static void *PLy_malloc(size_t); static void *PLy_malloc(size_t);
...@@ -3551,7 +3551,7 @@ PLy_spi_exception_set(ErrorData *edata) ...@@ -3551,7 +3551,7 @@ PLy_spi_exception_set(ErrorData *edata)
if (!spierror) if (!spierror)
goto failure; goto failure;
spidata = Py_BuildValue("(zzi)", edata->hint, spidata = Py_BuildValue("(zzzi)", edata->detail, edata->hint,
edata->internalquery, edata->internalpos); edata->internalquery, edata->internalpos);
if (!spidata) if (!spidata)
goto failure; goto failure;
...@@ -3586,13 +3586,14 @@ PLy_elog(int elevel, const char *fmt,...) ...@@ -3586,13 +3586,14 @@ PLy_elog(int elevel, const char *fmt,...)
int xlevel; int xlevel;
StringInfoData emsg; StringInfoData emsg;
PyObject *exc, *val, *tb; PyObject *exc, *val, *tb;
char *detail = NULL;
char *hint = NULL; char *hint = NULL;
char *query = NULL; char *query = NULL;
int position = 0; int position = 0;
PyErr_Fetch(&exc, &val, &tb); PyErr_Fetch(&exc, &val, &tb);
if (exc != NULL && PyErr_GivenExceptionMatches(val, PLy_exc_spi_error)) if (exc != NULL && PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
PLy_get_spi_error_data(val, &hint, &query, &position); PLy_get_spi_error_data(val, &detail, &hint, &query, &position);
PyErr_Restore(exc, val, tb); PyErr_Restore(exc, val, tb);
xmsg = PLy_traceback(&xlevel); xmsg = PLy_traceback(&xlevel);
...@@ -3626,6 +3627,7 @@ PLy_elog(int elevel, const char *fmt,...) ...@@ -3626,6 +3627,7 @@ PLy_elog(int elevel, const char *fmt,...)
else else
ereport(elevel, ereport(elevel,
(errmsg("PL/Python: %s", xmsg), (errmsg("PL/Python: %s", xmsg),
(detail) ? errdetail("%s", detail) : 0,
(hint) ? errhint("%s", hint) : 0, (hint) ? errhint("%s", hint) : 0,
(query) ? internalerrquery(query) : 0, (query) ? internalerrquery(query) : 0,
(position) ? internalerrposition(position) : 0)); (position) ? internalerrposition(position) : 0));
...@@ -3650,7 +3652,7 @@ PLy_elog(int elevel, const char *fmt,...) ...@@ -3650,7 +3652,7 @@ PLy_elog(int elevel, const char *fmt,...)
* Extract the error data from a SPIError * Extract the error data from a SPIError
*/ */
static void static void
PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position) PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position)
{ {
PyObject *spidata = NULL; PyObject *spidata = NULL;
...@@ -3658,7 +3660,7 @@ PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position) ...@@ -3658,7 +3660,7 @@ PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position)
if (!spidata) if (!spidata)
goto cleanup; goto cleanup;
if (!PyArg_ParseTuple(spidata, "zzi", hint, query, position)) if (!PyArg_ParseTuple(spidata, "zzzi", detail, hint, query, position))
goto cleanup; goto cleanup;
cleanup: cleanup:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment