aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpy_elog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plpython/plpy_elog.c')
-rw-r--r--src/pl/plpython/plpy_elog.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c
index c375ac07fa8..70450d7d9e5 100644
--- a/src/pl/plpython/plpy_elog.c
+++ b/src/pl/plpython/plpy_elog.c
@@ -337,6 +337,31 @@ PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
}
/*
+ * Extract error code from SPIError's sqlstate attribute.
+ */
+static void
+PLy_get_spi_sqlerrcode(PyObject *exc, int *sqlerrcode)
+{
+ PyObject *sqlstate;
+ char *buffer;
+
+ sqlstate = PyObject_GetAttrString(exc, "sqlstate");
+ if (sqlstate == NULL)
+ return;
+
+ buffer = PyString_AsString(sqlstate);
+ if (strlen(buffer) == 5 &&
+ strspn(buffer, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
+ {
+ *sqlerrcode = MAKE_SQLSTATE(buffer[0], buffer[1], buffer[2],
+ buffer[3], buffer[4]);
+ }
+
+ Py_DECREF(sqlstate);
+}
+
+
+/*
* Extract the error data from a SPIError
*/
static void
@@ -345,13 +370,20 @@ PLy_get_spi_error_data(PyObject *exc, int *sqlerrcode, char **detail, char **hin
PyObject *spidata = NULL;
spidata = PyObject_GetAttrString(exc, "spidata");
- if (!spidata)
- goto cleanup;
- if (!PyArg_ParseTuple(spidata, "izzzi", sqlerrcode, detail, hint, query, position))
- goto cleanup;
+ if (spidata != NULL)
+ {
+ PyArg_ParseTuple(spidata, "izzzi", sqlerrcode, detail, hint, query, position);
+ }
+ else
+ {
+ /*
+ * If there's no spidata, at least set the sqlerrcode. This can happen
+ * if someone explicitly raises a SPI exception from Python code.
+ */
+ PLy_get_spi_sqlerrcode(exc, sqlerrcode);
+ }
-cleanup:
PyErr_Clear();
/* no elog here, we simply won't report the errhint, errposition etc */
Py_XDECREF(spidata);