aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@protonmail.com>2022-05-04 07:16:01 -0600
committerGitHub <noreply@github.com>2022-05-04 07:16:01 -0600
commit090819ec5faea2d0c2cdf6bcfdbbc9df144a8aad (patch)
tree71881b44e7ffb8eaa92dcdfc88a6ad037bc057d9 /Modules/_sqlite
parentUse static inline function Py_EnterRecursiveCall() (#91988) (diff)
downloadcpython-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.c33
-rw-r--r--Modules/_sqlite/util.c1
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: