diff options
author | Erlend Egeberg Aasland <erlend.aasland@protonmail.com> | 2022-05-04 07:16:01 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-04 07:16:01 -0600 |
commit | 090819ec5faea2d0c2cdf6bcfdbbc9df144a8aad (patch) | |
tree | 71881b44e7ffb8eaa92dcdfc88a6ad037bc057d9 /Modules/_sqlite | |
parent | Use static inline function Py_EnterRecursiveCall() (#91988) (diff) | |
download | cpython-090819ec5faea2d0c2cdf6bcfdbbc9df144a8aad.tar.gz cpython-090819ec5faea2d0c2cdf6bcfdbbc9df144a8aad.tar.bz2 cpython-090819ec5faea2d0c2cdf6bcfdbbc9df144a8aad.zip |
gh-89022: Improve sqlite3 exceptions related to binding params and API misuse (#91572)
* Map SQLITE_MISUSE to sqlite3.InterfaceError
SQLITE_MISUSE implies misuse of the SQLite C API, which, if it happens,
is _not_ a user error; it is an sqlite3 extension module error.
* Raise better errors when binding parameters fail.
Instead of always raising InterfaceError, guessing what went wrong,
raise accurate exceptions with more accurate error messages.
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r-- | Modules/_sqlite/cursor.c | 33 | ||||
-rw-r--r-- | Modules/_sqlite/util.c | 1 |
2 files changed, 19 insertions, 15 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index f72bf300240..c58def5f036 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -527,7 +527,8 @@ stmt_step(sqlite3_stmt *statement) } static int -bind_param(pysqlite_Statement *self, int pos, PyObject *parameter) +bind_param(pysqlite_state *state, pysqlite_Statement *self, int pos, + PyObject *parameter) { int rc = SQLITE_OK; const char *string; @@ -603,6 +604,9 @@ bind_param(pysqlite_Statement *self, int pos, PyObject *parameter) break; } case TYPE_UNKNOWN: + PyErr_Format(state->ProgrammingError, + "Error binding parameter %d: type '%s' is not supported", + pos, Py_TYPE(parameter)->tp_name); rc = -1; } @@ -688,15 +692,15 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } } - rc = bind_param(self, i + 1, adapted); + rc = bind_param(state, self, i + 1, adapted); Py_DECREF(adapted); if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(state->InterfaceError, - "Error binding parameter %d - " - "probably unsupported type.", i); - } + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + sqlite3 *db = sqlite3_db_handle(self->st); + _pysqlite_seterror(state, db); + _PyErr_ChainExceptions(exc, val, tb); return; } } @@ -748,20 +752,21 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } } - rc = bind_param(self, i, adapted); + rc = bind_param(state, self, i, adapted); Py_DECREF(adapted); if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(state->InterfaceError, - "Error binding parameter :%s - " - "probably unsupported type.", binding_name); - } + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + sqlite3 *db = sqlite3_db_handle(self->st); + _pysqlite_seterror(state, db); + _PyErr_ChainExceptions(exc, val, tb); return; } } } else { - PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type"); + PyErr_SetString(state->ProgrammingError, + "parameters are of unsupported type"); } } diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 37b2dd6cb29..2b3bbfefa3c 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -59,7 +59,6 @@ get_exception_class(pysqlite_state *state, int errorcode) case SQLITE_MISMATCH: return state->IntegrityError; case SQLITE_MISUSE: - return state->ProgrammingError; case SQLITE_RANGE: return state->InterfaceError; default: |