summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-08-06 18:28:47 (GMT)
committerGitHub <noreply@github.com>2021-08-06 18:28:47 (GMT)
commit7d747f26e6cac9f6891d475f3443441ce947697b (patch)
tree2b21130c1bbc45c410cec55d13bdae26e23df10c /Modules
parent738ac00a08cb6a9d104ec85ccb1a44c2399d6baa (diff)
downloadcpython-7d747f26e6cac9f6891d475f3443441ce947697b.zip
cpython-7d747f26e6cac9f6891d475f3443441ce947697b.tar.gz
cpython-7d747f26e6cac9f6891d475f3443441ce947697b.tar.bz2
bpo-44839: Raise more specific errors in sqlite3 (GH-27613)
MemoryError raised in user-defined functions will now preserve its type. OverflowError will now be converted to DataError. Previously both were converted to OperationalError.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_sqlite/connection.c67
1 files changed, 31 insertions, 36 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index aae6c66..0dab3e8 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -619,6 +619,29 @@ error:
return NULL;
}
+// Checks the Python exception and sets the appropriate SQLite error code.
+static void
+set_sqlite_error(sqlite3_context *context, const char *msg)
+{
+ assert(PyErr_Occurred());
+ if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ sqlite3_result_error_nomem(context);
+ }
+ else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ sqlite3_result_error_toobig(context);
+ }
+ else {
+ sqlite3_result_error(context, msg, -1);
+ }
+ pysqlite_state *state = pysqlite_get_state(NULL);
+ if (state->enable_callback_tracebacks) {
+ PyErr_Print();
+ }
+ else {
+ PyErr_Clear();
+ }
+}
+
static void
_pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv)
{
@@ -645,14 +668,7 @@ _pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv
Py_DECREF(py_retval);
}
if (!ok) {
- pysqlite_state *state = pysqlite_get_state(NULL);
- if (state->enable_callback_tracebacks) {
- PyErr_Print();
- }
- else {
- PyErr_Clear();
- }
- sqlite3_result_error(context, "user-defined function raised exception", -1);
+ set_sqlite_error(context, "user-defined function raised exception");
}
PyGILState_Release(threadstate);
@@ -676,18 +692,9 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
if (*aggregate_instance == NULL) {
*aggregate_instance = _PyObject_CallNoArg(aggregate_class);
-
- if (PyErr_Occurred()) {
- *aggregate_instance = 0;
-
- pysqlite_state *state = pysqlite_get_state(NULL);
- if (state->enable_callback_tracebacks) {
- PyErr_Print();
- }
- else {
- PyErr_Clear();
- }
- sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
+ if (!*aggregate_instance) {
+ set_sqlite_error(context,
+ "user-defined aggregate's '__init__' method raised error");
goto error;
}
}
@@ -706,14 +713,8 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
Py_DECREF(args);
if (!function_result) {
- pysqlite_state *state = pysqlite_get_state(NULL);
- if (state->enable_callback_tracebacks) {
- PyErr_Print();
- }
- else {
- PyErr_Clear();
- }
- sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
+ set_sqlite_error(context,
+ "user-defined aggregate's 'step' method raised error");
}
error:
@@ -761,14 +762,8 @@ _pysqlite_final_callback(sqlite3_context *context)
Py_DECREF(function_result);
}
if (!ok) {
- pysqlite_state *state = pysqlite_get_state(NULL);
- if (state->enable_callback_tracebacks) {
- PyErr_Print();
- }
- else {
- PyErr_Clear();
- }
- sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
+ set_sqlite_error(context,
+ "user-defined aggregate's 'finalize' method raised error");
}
/* Restore the exception (if any) of the last call to step(),