From fa4bb9e068097115dfd1888f90dd35070d69aac5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 18 Jul 2021 23:48:00 +0200 Subject: [PATCH 1/4] bpo-42064: Optimise sqlite3 state access using defining class --- Modules/_sqlite/clinic/connection.c.h | 24 ++++----- Modules/_sqlite/clinic/cursor.c.h | 73 +++++++++++++-------------- Modules/_sqlite/connection.c | 9 ++-- Modules/_sqlite/cursor.c | 39 ++++++++------ Modules/_sqlite/microprotocols.c | 4 +- Modules/_sqlite/microprotocols.h | 5 +- Modules/_sqlite/module.c | 5 +- Modules/_sqlite/module.h | 6 +++ Modules/_sqlite/statement.c | 10 ++-- Modules/_sqlite/statement.h | 4 +- 10 files changed, 95 insertions(+), 84 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index ec0a43a17fbe9c..d8d98d5cfd2747 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -110,31 +110,25 @@ PyDoc_STRVAR(pysqlite_connection_cursor__doc__, "Return a cursor for the connection."); #define PYSQLITE_CONNECTION_CURSOR_METHODDEF \ - {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, + {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, static PyObject * -pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory); +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyTypeObject *cls, + PyObject *factory); static PyObject * -pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_connection_cursor(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"factory", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + static _PyArg_Parser _parser = {"|O:cursor", _keywords, 0}; PyObject *factory = NULL; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &factory)) { goto exit; } - if (!noptargs) { - goto skip_optional_pos; - } - factory = args[0]; -skip_optional_pos: - return_value = pysqlite_connection_cursor_impl(self, factory); + return_value = pysqlite_connection_cursor_impl(self, cls, factory); exit: return return_value; @@ -811,4 +805,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=30f11f2d8f09bdf0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b81bc52da6810c0e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 8bcdc1a5d73789..1c897af6db405c 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -37,36 +37,26 @@ PyDoc_STRVAR(pysqlite_cursor_execute__doc__, "Executes a SQL statement."); #define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ - {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, + {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_execute__doc__}, static PyObject * -pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, - PyObject *parameters); +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyTypeObject *cls, + PyObject *sql, PyObject *parameters); static PyObject * -pysqlite_cursor_execute(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +pysqlite_cursor_execute(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"U|O:execute", _keywords, 0}; PyObject *sql; PyObject *parameters = NULL; - if (!_PyArg_CheckPositional("execute", nargs, 1, 2)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &sql, ¶meters)) { goto exit; } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("execute", "argument 1", "str", args[0]); - goto exit; - } - if (PyUnicode_READY(args[0]) == -1) { - goto exit; - } - sql = args[0]; - if (nargs < 2) { - goto skip_optional; - } - parameters = args[1]; -skip_optional: - return_value = pysqlite_cursor_execute_impl(self, sql, parameters); + return_value = pysqlite_cursor_execute_impl(self, cls, sql, parameters); exit: return return_value; @@ -79,32 +69,26 @@ PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, "Repeatedly executes a SQL statement."); #define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ - {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, + {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_executemany__doc__}, static PyObject * -pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, - PyObject *seq_of_parameters); +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyTypeObject *cls, + PyObject *sql, PyObject *seq_of_parameters); static PyObject * -pysqlite_cursor_executemany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +pysqlite_cursor_executemany(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"UO:executemany", _keywords, 0}; PyObject *sql; PyObject *seq_of_parameters; - if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &sql, &seq_of_parameters)) { goto exit; } - if (PyUnicode_READY(args[0]) == -1) { - goto exit; - } - sql = args[0]; - seq_of_parameters = args[1]; - return_value = pysqlite_cursor_executemany_impl(self, sql, seq_of_parameters); + return_value = pysqlite_cursor_executemany_impl(self, cls, sql, seq_of_parameters); exit: return return_value; @@ -249,14 +233,25 @@ PyDoc_STRVAR(pysqlite_cursor_close__doc__, "Closes the cursor."); #define PYSQLITE_CURSOR_CLOSE_METHODDEF \ - {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, pysqlite_cursor_close__doc__}, + {"close", (PyCFunction)(void(*)(void))pysqlite_cursor_close, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_close__doc__}, static PyObject * -pysqlite_cursor_close_impl(pysqlite_Cursor *self); +pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls); static PyObject * -pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +pysqlite_cursor_close(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return pysqlite_cursor_close_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":close", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = pysqlite_cursor_close_impl(self, cls); + +exit: + return return_value; } -/*[clinic end generated code: output=8f70eac5f8aa8d97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=962dc783e02c2a8d input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 33d3d4cfbd15e5..50839ae92cf46b 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -322,14 +322,17 @@ int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObjec /*[clinic input] _sqlite3.Connection.cursor as pysqlite_connection_cursor + cls: defining_class + / factory: object = NULL Return a cursor for the connection. [clinic start generated code]*/ static PyObject * -pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) -/*[clinic end generated code: output=562432a9e6af2aa1 input=4127345aa091b650]*/ +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyTypeObject *cls, + PyObject *factory) +/*[clinic end generated code: output=c48c9335315ba58d input=c19d77941a005430]*/ { PyObject* cursor; @@ -337,7 +340,7 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = pysqlite_get_state_by_cls(cls); if (factory == NULL) { factory = (PyObject *)state->CursorType; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 24b4a37521d836..aee4ea132c4ef1 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -468,9 +468,10 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) } static PyObject * -_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) +_pysqlite_query_execute(pysqlite_state *state, pysqlite_Cursor *self, + int multiple, PyObject *operation, + PyObject *second_argument) { - pysqlite_state *state = pysqlite_get_state(NULL); PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; PyObject* parameters = NULL; @@ -576,7 +577,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation pysqlite_statement_mark_dirty(self->statement); - pysqlite_statement_bind_parameters(self->statement, parameters); + pysqlite_statement_bind_parameters(state, self->statement, parameters); if (PyErr_Occurred()) { goto error; } @@ -597,7 +598,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } if (pysqlite_build_row_cast_map(self) != 0) { - _PyErr_FormatFromCause(self->connection->OperationalError, + _PyErr_FormatFromCause(state->OperationalError, "Error while building row_cast_map"); goto error; } @@ -651,7 +652,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation if (rc == SQLITE_ROW) { if (multiple) { - PyErr_SetString(self->connection->ProgrammingError, + PyErr_SetString(state->ProgrammingError, "executemany() can only execute DML " "statements."); goto error; @@ -689,6 +690,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation /*[clinic input] _sqlite3.Cursor.execute as pysqlite_cursor_execute + cls: defining_class sql: unicode parameters: object(c_default = 'NULL') = () / @@ -697,16 +699,18 @@ Executes a SQL statement. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, - PyObject *parameters) -/*[clinic end generated code: output=d81b4655c7c0bbad input=91d7bb36f127f597]*/ +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyTypeObject *cls, + PyObject *sql, PyObject *parameters) +/*[clinic end generated code: output=240cbdd024d071c2 input=754c85bca348dc35]*/ { - return _pysqlite_query_execute(self, 0, sql, parameters); + pysqlite_state *state = pysqlite_get_state_by_cls(cls); + return _pysqlite_query_execute(state, self, 0, sql, parameters); } /*[clinic input] _sqlite3.Cursor.executemany as pysqlite_cursor_executemany + cls: defining_class sql: unicode seq_of_parameters: object / @@ -715,11 +719,12 @@ Repeatedly executes a SQL statement. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, - PyObject *seq_of_parameters) -/*[clinic end generated code: output=2c65a3c4733fb5d8 input=440707b7af87fba8]*/ +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyTypeObject *cls, + PyObject *sql, PyObject *seq_of_parameters) +/*[clinic end generated code: output=0b767529517fbaf4 input=cd9f263377d1a7a4]*/ { - return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); + pysqlite_state *state = pysqlite_get_state_by_cls(cls); + return _pysqlite_query_execute(state, self, 1, sql, seq_of_parameters); } /*[clinic input] @@ -1023,15 +1028,17 @@ pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, /*[clinic input] _sqlite3.Cursor.close as pysqlite_cursor_close + cls: defining_class + Closes the cursor. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_close_impl(pysqlite_Cursor *self) -/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ +pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls) +/*[clinic end generated code: output=a08ab3d772f45438 input=28ba9b532ab46ba0]*/ { if (!self->connection) { - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = pysqlite_get_state_by_cls(cls); PyErr_SetString(state->ProgrammingError, "Base Cursor.__init__ not called."); return NULL; diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 160d7b923d7a1f..68e4f7fb166db7 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -71,7 +71,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) /* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */ PyObject * -pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) +pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, + PyObject *proto, PyObject *alt) { _Py_IDENTIFIER(__adapt__); _Py_IDENTIFIER(__conform__); @@ -86,7 +87,6 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) if (!key) { return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); adapter = PyDict_GetItemWithError(state->psyco_adapters, key); Py_DECREF(key); if (adapter) { diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index e9adef916e724b..e4d9038e89d5af 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -41,7 +41,8 @@ extern int pysqlite_microprotocols_init(PyObject *module); extern int pysqlite_microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); -extern PyObject *pysqlite_microprotocols_adapt( - PyObject *obj, PyObject *proto, PyObject *alt); +extern PyObject *pysqlite_microprotocols_adapt(pysqlite_state *state, + PyObject *obj, PyObject *proto, + PyObject *alt); #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 98b2c90108f07b..993e572c5cdb3e 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -158,7 +158,7 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, state->BaseTypeAdapted = 1; } - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = pysqlite_get_state(module); PyObject *protocol = (PyObject *)state->PrepareProtocolType; rc = pysqlite_microprotocols_add(type, protocol, caster); if (rc == -1) { @@ -239,7 +239,8 @@ pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, PyObject *alt) /*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/ { - return pysqlite_microprotocols_adapt(obj, proto, alt); + pysqlite_state *state = pysqlite_get_state(module); + return pysqlite_microprotocols_adapt(state, obj, proto, alt); } static int converters_init(PyObject* module) diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 1344490700851f..731a39cf7232c1 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -68,6 +68,12 @@ pysqlite_get_state(PyObject *Py_UNUSED(module)) return &pysqlite_global_state; } +static inline pysqlite_state * +pysqlite_get_state_by_cls(PyTypeObject *Py_UNUSED(cls)) +{ + return &pysqlite_global_state; +} + #define PARSE_DECLTYPES 1 #define PARSE_COLNAMES 2 #endif diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 8add50960f86a3..a8344b89e53311 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -224,9 +224,11 @@ static int _need_adapt(PyObject* obj) } } -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters) +void +pysqlite_statement_bind_parameters(pysqlite_state *state, + pysqlite_Statement *self, + PyObject *parameters) { - pysqlite_state *state = pysqlite_get_state(NULL); PyObject* current_param; PyObject* adapted; const char* binding_name; @@ -276,7 +278,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para adapted = current_param; } else { PyObject *protocol = (PyObject *)state->PrepareProtocolType; - adapted = pysqlite_microprotocols_adapt(current_param, + adapted = pysqlite_microprotocols_adapt(state, current_param, protocol, current_param); Py_DECREF(current_param); @@ -336,7 +338,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para adapted = current_param; } else { PyObject *protocol = (PyObject *)state->PrepareProtocolType; - adapted = pysqlite_microprotocols_adapt(current_param, + adapted = pysqlite_microprotocols_adapt(state, current_param, protocol, current_param); Py_DECREF(current_param); diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 70801cc5ce9fdb..dc692d7df99fd7 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -41,7 +41,9 @@ typedef struct pysqlite_Statement *pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql); int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); +void pysqlite_statement_bind_parameters(pysqlite_state *state, + pysqlite_Statement *self, + PyObject *parameters); int pysqlite_statement_finalize(pysqlite_Statement* self); int pysqlite_statement_reset(pysqlite_Statement* self); From 7f4cce3e5891f8e0f157c4709d669e5f08c2924a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 18 Jul 2021 23:55:10 +0200 Subject: [PATCH 2/4] Pass state as argument to new_statement_cache() --- Modules/_sqlite/connection.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 50839ae92cf46b..83f98b19f00815 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -60,13 +60,13 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static PyObject * -new_statement_cache(pysqlite_Connection *self, int maxsize) +new_statement_cache(pysqlite_state *state, pysqlite_Connection *self, + int maxsize) { PyObject *args[] = { PyLong_FromLong(maxsize), }; if (args[0] == NULL) { return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); PyObject *inner = PyObject_Vectorcall(state->lru_cache, args, 1, NULL); Py_DECREF(args[0]); if (inner == NULL) { @@ -150,7 +150,9 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, } Py_DECREF(isolation_level); - self->statement_cache = new_statement_cache(self, cached_statements); + pysqlite_state *state = pysqlite_get_state(NULL); + self->statement_cache = new_statement_cache(state, self, + cached_statements); if (self->statement_cache == NULL) { return -1; } @@ -182,7 +184,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, return -1; } - pysqlite_state *state = pysqlite_get_state(NULL); self->Warning = state->Warning; self->Error = state->Error; self->InterfaceError = state->InterfaceError; From 5f54745e6f2c2d16aa2b128a82fa6514c1898cc4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 28 Jul 2021 00:32:47 +0200 Subject: [PATCH 3/4] Update clinic --- Modules/_sqlite/clinic/connection.c.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index d8d98d5cfd2747..ec0a43a17fbe9c 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -110,25 +110,31 @@ PyDoc_STRVAR(pysqlite_connection_cursor__doc__, "Return a cursor for the connection."); #define PYSQLITE_CONNECTION_CURSOR_METHODDEF \ - {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, + {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, static PyObject * -pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyTypeObject *cls, - PyObject *factory); +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory); static PyObject * -pysqlite_connection_cursor(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"factory", NULL}; - static _PyArg_Parser _parser = {"|O:cursor", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *factory = NULL; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &factory)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } - return_value = pysqlite_connection_cursor_impl(self, cls, factory); + if (!noptargs) { + goto skip_optional_pos; + } + factory = args[0]; +skip_optional_pos: + return_value = pysqlite_connection_cursor_impl(self, factory); exit: return return_value; @@ -805,4 +811,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=b81bc52da6810c0e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=30f11f2d8f09bdf0 input=a9049054013a1b77]*/ From 317625d6338470ee22722e36891280b1d9b2bde0 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 28 Jul 2021 01:30:43 +0200 Subject: [PATCH 4/4] Keep a pointer to the state in connection contex --- Modules/_sqlite/clinic/cursor.c.h | 54 ++++++++++++++++++---------- Modules/_sqlite/connection.c | 37 +++++++++---------- Modules/_sqlite/connection.h | 1 + Modules/_sqlite/cursor.c | 59 +++++++++++++++---------------- Modules/_sqlite/module.h | 9 ++++- Modules/_sqlite/row.c | 2 +- Modules/_sqlite/statement.c | 12 +++---- Modules/_sqlite/util.c | 3 +- Modules/_sqlite/util.h | 2 +- 9 files changed, 101 insertions(+), 78 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 1c897af6db405c..d2c453b38b4b9e 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -37,26 +37,36 @@ PyDoc_STRVAR(pysqlite_cursor_execute__doc__, "Executes a SQL statement."); #define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ - {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_execute__doc__}, + {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, static PyObject * -pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyTypeObject *cls, - PyObject *sql, PyObject *parameters); +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters); static PyObject * -pysqlite_cursor_execute(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_cursor_execute(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"U|O:execute", _keywords, 0}; PyObject *sql; PyObject *parameters = NULL; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &sql, ¶meters)) { + if (!_PyArg_CheckPositional("execute", nargs, 1, 2)) { goto exit; } - return_value = pysqlite_cursor_execute_impl(self, cls, sql, parameters); + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("execute", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + if (nargs < 2) { + goto skip_optional; + } + parameters = args[1]; +skip_optional: + return_value = pysqlite_cursor_execute_impl(self, sql, parameters); exit: return return_value; @@ -69,26 +79,32 @@ PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, "Repeatedly executes a SQL statement."); #define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ - {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_executemany__doc__}, + {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, static PyObject * -pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyTypeObject *cls, - PyObject *sql, PyObject *seq_of_parameters); +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *seq_of_parameters); static PyObject * -pysqlite_cursor_executemany(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_cursor_executemany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"UO:executemany", _keywords, 0}; PyObject *sql; PyObject *seq_of_parameters; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &sql, &seq_of_parameters)) { + if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { goto exit; } - return_value = pysqlite_cursor_executemany_impl(self, cls, sql, seq_of_parameters); + sql = args[0]; + seq_of_parameters = args[1]; + return_value = pysqlite_cursor_executemany_impl(self, sql, seq_of_parameters); exit: return return_value; @@ -254,4 +270,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const exit: return return_value; } -/*[clinic end generated code: output=962dc783e02c2a8d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7b216aba2439f5cf input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index af093c3319c8b2..a5b9d6fe29f88a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -66,8 +66,8 @@ new_statement_cache(pysqlite_Connection *self, int maxsize) if (args[0] == NULL) { return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); - PyObject *inner = PyObject_Vectorcall(state->lru_cache, args, 1, NULL); + PyObject *lru_cache = self->state->lru_cache; + PyObject *inner = PyObject_Vectorcall(lru_cache, args, 1, NULL); Py_DECREF(args[0]); if (inner == NULL) { return NULL; @@ -106,6 +106,9 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, return -1; } + pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self)); + self->state = state; + const char *database = PyBytes_AsString(database_obj); self->initialized = 1; @@ -131,7 +134,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, Py_DECREF(database_obj); // needed bco. the AC FSConverter if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(state, self->db); return -1; } @@ -177,7 +180,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, self->function_pinboard_progress_handler = NULL; self->function_pinboard_authorizer_cb = NULL; - pysqlite_state *state = pysqlite_get_state(NULL); self->Warning = state->Warning; self->Error = state->Error; self->InterfaceError = state->InterfaceError; @@ -330,15 +332,14 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); if (factory == NULL) { - factory = (PyObject *)state->CursorType; + factory = (PyObject *)self->state->CursorType; } cursor = PyObject_CallOneArg(factory, (PyObject *)self); if (cursor == NULL) return NULL; - if (!PyObject_TypeCheck(cursor, state->CursorType)) { + if (!PyObject_TypeCheck(cursor, self->state->CursorType)) { PyErr_Format(PyExc_TypeError, "factory must return a cursor, not %.100s", Py_TYPE(cursor)->tp_name); @@ -383,15 +384,15 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) */ int pysqlite_check_connection(pysqlite_Connection* con) { - pysqlite_state *state = pysqlite_get_state(NULL); if (!con->initialized) { + pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(con)); PyErr_SetString(state->ProgrammingError, "Base Connection.__init__ not called."); return 0; } if (!con->db) { - PyErr_SetString(state->ProgrammingError, + PyErr_SetString(con->state->ProgrammingError, "Cannot operate on a closed database."); return 0; } else { @@ -422,20 +423,20 @@ pysqlite_connection_commit_impl(pysqlite_Connection *self) rc = sqlite3_prepare_v2(self->db, "COMMIT", 7, &statement, NULL); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); goto error; } rc = pysqlite_step(statement); if (rc != SQLITE_DONE) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); } Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(statement); Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); } } @@ -472,20 +473,20 @@ pysqlite_connection_rollback_impl(pysqlite_Connection *self) rc = sqlite3_prepare_v2(self->db, "ROLLBACK", 9, &statement, NULL); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); goto error; } rc = pysqlite_step(statement); if (rc != SQLITE_DONE) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); } Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(statement); Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); } } @@ -1672,7 +1673,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, Py_END_ALLOW_THREADS if (bck_handle == NULL) { - _pysqlite_seterror(bck_conn); + _pysqlite_seterror(self->state, bck_conn); return NULL; } @@ -1710,7 +1711,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(bck_conn); + _pysqlite_seterror(self->state, bck_conn); return NULL; } @@ -1797,7 +1798,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self, if (callable != Py_None) { Py_DECREF(callable); } - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); goto finally; } diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 50c2015be3eb19..edf565020420d3 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -36,6 +36,7 @@ typedef struct { PyObject_HEAD sqlite3* db; + pysqlite_state *state; /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a * bitwise combination thereof makes sense */ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index aee4ea132c4ef1..2f4494690f9557 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -130,7 +130,8 @@ cursor_dealloc(pysqlite_Cursor *self) } static PyObject * -_pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) +_pysqlite_get_converter(pysqlite_state *state, const char *keystr, + Py_ssize_t keylen) { PyObject *key; PyObject *upcase_key; @@ -147,7 +148,6 @@ _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) return NULL; } - pysqlite_state *state = pysqlite_get_state(NULL); retval = PyDict_GetItemWithError(state->converters, upcase_key); Py_DECREF(upcase_key); @@ -187,7 +187,9 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self) type_start = pos + 1; } else if (*pos == ']' && type_start != NULL) { - converter = _pysqlite_get_converter(type_start, pos - type_start); + pysqlite_state *state = self->connection->state; + converter = _pysqlite_get_converter(state, type_start, + pos - type_start); if (!converter && PyErr_Occurred()) { Py_CLEAR(self->row_cast_map); return -1; @@ -206,7 +208,9 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self) * 'NUMBER(10)' to be treated as 'NUMBER', for example. * In other words, it will work as people expect it to work.*/ if (*pos == ' ' || *pos == '(' || *pos == 0) { - converter = _pysqlite_get_converter(decltype, pos - decltype); + pysqlite_state *state = self->connection->state; + converter = _pysqlite_get_converter(state, decltype, + pos - decltype); if (!converter && PyErr_Occurred()) { Py_CLEAR(self->row_cast_map); return -1; @@ -404,22 +408,21 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) */ static int check_cursor(pysqlite_Cursor* cur) { - pysqlite_state *state = pysqlite_get_state(NULL); - if (!cur->initialized) { + pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(cur)); PyErr_SetString(state->ProgrammingError, "Base Cursor.__init__ not called."); return 0; } if (cur->closed) { - PyErr_SetString(state->ProgrammingError, + PyErr_SetString(cur->connection->state->ProgrammingError, "Cannot operate on a closed cursor."); return 0; } if (cur->locked) { - PyErr_SetString(state->ProgrammingError, + PyErr_SetString(cur->connection->state->ProgrammingError, "Recursive use of cursors not allowed."); return 0; } @@ -439,7 +442,7 @@ begin_transaction(pysqlite_Connection *self) Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); goto error; } @@ -449,7 +452,7 @@ begin_transaction(pysqlite_Connection *self) Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db); + _pysqlite_seterror(self->state, self->db); } error: @@ -468,9 +471,7 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) } static PyObject * -_pysqlite_query_execute(pysqlite_state *state, pysqlite_Cursor *self, - int multiple, PyObject *operation, - PyObject *second_argument) +_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; @@ -569,6 +570,7 @@ _pysqlite_query_execute(pysqlite_state *state, pysqlite_Cursor *self, } } + pysqlite_state *state = self->connection->state; while (1) { parameters = PyIter_Next(parameters_iter); if (!parameters) { @@ -593,7 +595,7 @@ _pysqlite_query_execute(pysqlite_state *state, pysqlite_Cursor *self, } } (void)pysqlite_statement_reset(self->statement); - _pysqlite_seterror(self->connection->db); + _pysqlite_seterror(state, self->connection->db); goto error; } @@ -690,7 +692,6 @@ _pysqlite_query_execute(pysqlite_state *state, pysqlite_Cursor *self, /*[clinic input] _sqlite3.Cursor.execute as pysqlite_cursor_execute - cls: defining_class sql: unicode parameters: object(c_default = 'NULL') = () / @@ -699,18 +700,16 @@ Executes a SQL statement. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyTypeObject *cls, - PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=240cbdd024d071c2 input=754c85bca348dc35]*/ +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=d81b4655c7c0bbad input=91d7bb36f127f597]*/ { - pysqlite_state *state = pysqlite_get_state_by_cls(cls); - return _pysqlite_query_execute(state, self, 0, sql, parameters); + return _pysqlite_query_execute(self, 0, sql, parameters); } /*[clinic input] _sqlite3.Cursor.executemany as pysqlite_cursor_executemany - cls: defining_class sql: unicode seq_of_parameters: object / @@ -719,12 +718,11 @@ Repeatedly executes a SQL statement. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyTypeObject *cls, - PyObject *sql, PyObject *seq_of_parameters) -/*[clinic end generated code: output=0b767529517fbaf4 input=cd9f263377d1a7a4]*/ +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *seq_of_parameters) +/*[clinic end generated code: output=2c65a3c4733fb5d8 input=440707b7af87fba8]*/ { - pysqlite_state *state = pysqlite_get_state_by_cls(cls); - return _pysqlite_query_execute(state, self, 1, sql, seq_of_parameters); + return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); } /*[clinic input] @@ -778,6 +776,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) } Py_DECREF(result); + pysqlite_state *state = self->connection->state; while (1) { const char *tail; @@ -789,7 +788,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(self->connection->db); + _pysqlite_seterror(state, self->connection->db); goto error; } @@ -804,13 +803,13 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) if (rc != SQLITE_DONE) { (void)sqlite3_finalize(statement); - _pysqlite_seterror(self->connection->db); + _pysqlite_seterror(state, self->connection->db); goto error; } rc = sqlite3_finalize(statement); if (rc != SQLITE_OK) { - _pysqlite_seterror(self->connection->db); + _pysqlite_seterror(state, self->connection->db); goto error; } @@ -879,7 +878,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) if (rc != SQLITE_DONE && rc != SQLITE_ROW) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(next_row); - _pysqlite_seterror(self->connection->db); + _pysqlite_seterror(self->connection->state, self->connection->db); return NULL; } diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 731a39cf7232c1..a286739579db6e 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -65,12 +65,19 @@ extern pysqlite_state pysqlite_global_state; static inline pysqlite_state * pysqlite_get_state(PyObject *Py_UNUSED(module)) { - return &pysqlite_global_state; + return &pysqlite_global_state; // Replace with PyModule_GetState } static inline pysqlite_state * pysqlite_get_state_by_cls(PyTypeObject *Py_UNUSED(cls)) { + return &pysqlite_global_state; // Replace with PyType_GetModuleState +} + +static inline pysqlite_state * +pysqlite_get_state_by_type(PyTypeObject *Py_UNUSED(tp)) +{ + // Replace with _PyType_GetModuleByDef & PyModule_GetState return &pysqlite_global_state; } diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index d2f9bdd00b670a..b146c9dc5e3bd1 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -219,7 +219,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = pysqlite_get_state_by_cls(Py_TYPE(self)); if (PyObject_TypeCheck(_other, state->RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index a8344b89e53311..983df2d50c975d 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -51,7 +51,7 @@ typedef enum { pysqlite_Statement * pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) { - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = connection->state; assert(PyUnicode_Check(sql)); Py_ssize_t size; const char *sql_cstr = PyUnicode_AsUTF8AndSize(sql, &size); @@ -83,7 +83,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { - _pysqlite_seterror(db); + _pysqlite_seterror(state, db); return NULL; } @@ -209,9 +209,9 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec } /* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ -static int _need_adapt(PyObject* obj) +static int +_need_adapt(pysqlite_state *state, PyObject *obj) { - pysqlite_state *state = pysqlite_get_state(NULL); if (state->BaseTypeAdapted) { return 1; } @@ -274,7 +274,7 @@ pysqlite_statement_bind_parameters(pysqlite_state *state, return; } - if (!_need_adapt(current_param)) { + if (!_need_adapt(state, current_param)) { adapted = current_param; } else { PyObject *protocol = (PyObject *)state->PrepareProtocolType; @@ -334,7 +334,7 @@ pysqlite_statement_bind_parameters(pysqlite_state *state, return; } - if (!_need_adapt(current_param)) { + if (!_need_adapt(state, current_param)) { adapted = current_param; } else { PyObject *protocol = (PyObject *)state->PrepareProtocolType; diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 6ddf0c732b4575..24cefc626b66e2 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -41,9 +41,8 @@ pysqlite_step(sqlite3_stmt *statement) * Returns the error code (0 means no error occurred). */ int -_pysqlite_seterror(sqlite3 *db) +_pysqlite_seterror(pysqlite_state *state, sqlite3 *db) { - pysqlite_state *state = pysqlite_get_state(NULL); int errorcode = sqlite3_errcode(db); switch (errorcode) diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index f308f03f71f440..5eee3fac6f114e 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -35,7 +35,7 @@ int pysqlite_step(sqlite3_stmt *statement); * Checks the SQLite error code and sets the appropriate DB-API exception. * Returns the error code (0 means no error occurred). */ -int _pysqlite_seterror(sqlite3 *db); +int _pysqlite_seterror(pysqlite_state *state, sqlite3 *db); sqlite_int64 _pysqlite_long_as_int64(PyObject * value);