[Python-checkins] bpo-42064: Optimise `sqlite3` state access, part 1 (GH-27273)

miss-islington webhook-mailer at python.org
Thu Jul 29 05:22:00 EDT 2021


https://github.com/python/cpython/commit/d542742128b634264d5b6796297613975211b43b
commit: d542742128b634264d5b6796297613975211b43b
branch: main
author: Erlend Egeberg Aasland <erlend.aasland at innova.no>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2021-07-29T02:21:45-07:00
summary:

bpo-42064: Optimise `sqlite3` state access, part 1 (GH-27273)



Prepare for module state:

- Add "get state by defining class" and "get state by module def" stubs
- Add AC defining class when needed
- Add state pointer to connection context
- Pass state as argument to utility functions

Automerge-Triggered-By: GH:encukou

files:
M Modules/_sqlite/clinic/cursor.c.h
M Modules/_sqlite/connection.c
M Modules/_sqlite/connection.h
M Modules/_sqlite/cursor.c
M Modules/_sqlite/microprotocols.c
M Modules/_sqlite/microprotocols.h
M Modules/_sqlite/module.c
M Modules/_sqlite/module.h
M Modules/_sqlite/row.c
M Modules/_sqlite/statement.c
M Modules/_sqlite/statement.h
M Modules/_sqlite/util.c
M Modules/_sqlite/util.h

diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h
index 8bcdc1a5d7378..d2c453b38b4b9 100644
--- a/Modules/_sqlite/clinic/cursor.c.h
+++ b/Modules/_sqlite/clinic/cursor.c.h
@@ -249,14 +249,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=7b216aba2439f5cf input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 85b666a41958f..a95b75a0fe14a 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;
     }
 
@@ -1762,7 +1763,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);
         return NULL;
     }
 
diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h
index 50c2015be3eb1..edf565020420d 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 24b4a37521d83..2f4494690f955 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:
@@ -470,7 +473,6 @@ 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_state *state = pysqlite_get_state(NULL);
     PyObject* parameters_list = NULL;
     PyObject* parameters_iter = NULL;
     PyObject* parameters = NULL;
@@ -568,6 +570,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
         }
     }
 
+    pysqlite_state *state = self->connection->state;
     while (1) {
         parameters = PyIter_Next(parameters_iter);
         if (!parameters) {
@@ -576,7 +579,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;
         }
@@ -592,12 +595,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
                 }
             }
             (void)pysqlite_statement_reset(self->statement);
-            _pysqlite_seterror(self->connection->db);
+            _pysqlite_seterror(state, self->connection->db);
             goto error;
         }
 
         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 +654,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;
@@ -773,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;
 
@@ -784,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;
         }
 
@@ -799,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;
         }
 
@@ -874,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;
         }
 
@@ -1023,15 +1027,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 160d7b923d7a1..68e4f7fb166db 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 e9adef916e724..e4d9038e89d5a 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 98b2c90108f07..993e572c5cdb3 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 1344490700851..a286739579db6 100644
--- a/Modules/_sqlite/module.h
+++ b/Modules/_sqlite/module.h
@@ -65,6 +65,19 @@ extern pysqlite_state pysqlite_global_state;
 static inline pysqlite_state *
 pysqlite_get_state(PyObject *Py_UNUSED(module))
 {
+    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 d2f9bdd00b670..b146c9dc5e3bd 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 8add50960f86a..983df2d50c975 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;
     }
@@ -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;
@@ -272,11 +274,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
                 return;
             }
 
-            if (!_need_adapt(current_param)) {
+            if (!_need_adapt(state, current_param)) {
                 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);
@@ -332,11 +334,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
                 return;
             }
 
-            if (!_need_adapt(current_param)) {
+            if (!_need_adapt(state, current_param)) {
                 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 70801cc5ce9fd..dc692d7df99fd 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);
diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c
index 6ddf0c732b457..24cefc626b66e 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 f308f03f71f44..5eee3fac6f114 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);
 



More information about the Python-checkins mailing list