提交 8326b1b6 编写于 作者: H Heikki Linnakangas

Backport patch to preserve SQLSTATE in PL/python.

We had backported PL/python from PostgreSQL 9.1, but not this patch
that was applied later to the stable branch. I noticed when I started
looking at this, while cleaning up the source file/line number information
in error messages.

I did not backport the regression test changes, because we had apparently
not backported other regression test changes either, and I was not able
to make the tests work easily.

Original commit:

commit d2192a108c7b118d430f03cff0ff84861d5026e0
Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:   Thu Nov 24 17:18:43 2011 +0200

    Preserve SQLSTATE when an SPI error is propagated through PL/python
    exception handler. This was a regression in 9.1, when the capability
    to catch specific SPI errors was added, so backpatch to 9.1.

    Mika Eloranta, with some editing by Jan Urbański.
上级 f6f5c9ef
......@@ -2,7 +2,7 @@
-- the trigger handler once. the errors and subsequent core dump were
-- interesting.
SELECT invalid_type_uncaught('rick');
ERROR: plpy.SPIError: type "test" does not exist (plpython.c:4703)
ERROR: plpy.SPIError: type "test" does not exist
CONTEXT: Traceback (most recent call last):
PL/Python function "invalid_type_uncaught", line 3, in <module>
SD["plan"] = plpy.prepare(q, [ "test" ])
......@@ -16,7 +16,7 @@ CONTEXT: PL/Python function "invalid_type_caught"
(1 row)
SELECT invalid_type_reraised('rick');
ERROR: plpy.Error: type "test" does not exist (plpython.c:4703)
ERROR: plpy.Error: type "test" does not exist
CONTEXT: Traceback (most recent call last):
PL/Python function "invalid_type_reraised", line 6, in <module>
plpy.error(str(ex))
......
......@@ -46,7 +46,7 @@ SELECT * FROM subtransaction_tbl order by i;
TRUNCATE subtransaction_tbl;
SELECT subtransaction_test('SPI');
ERROR: plpy.SPIError: invalid input syntax for integer: "oops" (plpython.c:4718)
ERROR: plpy.SPIError: invalid input syntax for integer: "oops"
LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops')
^
QUERY: INSERT INTO subtransaction_tbl VALUES ('oops')
......@@ -98,7 +98,7 @@ SELECT * FROM subtransaction_tbl order by i;
TRUNCATE subtransaction_tbl;
SELECT subtransaction_ctx_test('SPI');
ERROR: plpy.SPIError: invalid input syntax for integer: "oops" (plpython.c:4718)
ERROR: plpy.SPIError: invalid input syntax for integer: "oops"
LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops')
^
QUERY: INSERT INTO subtransaction_tbl VALUES ('oops')
......
......@@ -346,7 +346,7 @@ static char *PLy_procedure_name(PLyProcedure *);
static void
PLy_elog(int, const char *,...)
__attribute__((format(printf, 2, 3)));
static void PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position);
static void PLy_get_spi_error_data(PyObject *exc, int *sqlerrcode, char **detail, char **hint, char **query, int *position);
static void PLy_traceback(char **, char **, int *);
static void *PLy_malloc(size_t);
......@@ -4638,7 +4638,7 @@ PLy_spi_exception_set(PyObject *excclass, ErrorData *edata)
if (!spierror)
goto failure;
spidata = Py_BuildValue("(zzzi)", edata->detail, edata->hint,
spidata = Py_BuildValue("(izzzi)", edata->sqlerrcode, edata->detail, edata->hint,
edata->internalquery, edata->internalpos);
if (!spidata)
goto failure;
......@@ -4678,6 +4678,7 @@ PLy_elog(int elevel, const char *fmt,...)
*val,
*tb;
const char *primary = NULL;
int sqlerrcode = 0;
char *detail = NULL;
char *hint = NULL;
char *query = NULL;
......@@ -4687,7 +4688,7 @@ PLy_elog(int elevel, const char *fmt,...)
if (exc != NULL)
{
if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
PLy_get_spi_error_data(val, &detail, &hint, &query, &position);
PLy_get_spi_error_data(val, &sqlerrcode, &detail, &hint, &query, &position);
else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
elevel = FATAL;
}
......@@ -4728,7 +4729,8 @@ PLy_elog(int elevel, const char *fmt,...)
PG_TRY();
{
ereport(elevel,
(errmsg("%s", primary ? primary : "no exception data"),
(errcode(sqlerrcode ? sqlerrcode : ERRCODE_INTERNAL_ERROR),
errmsg("%s", primary ? primary : "no exception data"),
(detail) ? errdetail("%s", detail) : 0,
(tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
(hint) ? errhint("%s", hint) : 0,
......@@ -4759,7 +4761,7 @@ PLy_elog(int elevel, const char *fmt,...)
* Extract the error data from a SPIError
*/
static void
PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position)
PLy_get_spi_error_data(PyObject *exc, int* sqlerrcode, char **detail, char **hint, char **query, int *position)
{
PyObject *spidata = NULL;
......@@ -4767,7 +4769,7 @@ PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query,
if (!spidata)
goto cleanup;
if (!PyArg_ParseTuple(spidata, "zzzi", detail, hint, query, position))
if (!PyArg_ParseTuple(spidata, "izzzi", sqlerrcode, detail, hint, query, position))
goto cleanup;
cleanup:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册