]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44042: Optimize sqlite3 begin transaction (GH-25908)
authorErlend Egeberg Aasland <erlend.aasland@innova.no>
Thu, 3 Jun 2021 21:24:25 +0000 (23:24 +0200)
committerGitHub <noreply@github.com>
Thu, 3 Jun 2021 21:24:25 +0000 (22:24 +0100)
Modules/_sqlite/connection.c
Modules/_sqlite/connection.h
Modules/_sqlite/cursor.c

index c43f74ceace3035d1cf76059fecef8939414f7fb..47ae9aaf4ae6839d1b0c9661af1ebddf81f3c859 100644 (file)
@@ -405,42 +405,6 @@ int pysqlite_check_connection(pysqlite_Connection* con)
     }
 }
 
-PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
-{
-    int rc;
-    sqlite3_stmt* statement;
-
-    Py_BEGIN_ALLOW_THREADS
-    rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement,
-                            NULL);
-    Py_END_ALLOW_THREADS
-
-    if (rc != SQLITE_OK) {
-        _pysqlite_seterror(self->db);
-        goto error;
-    }
-
-    rc = pysqlite_step(statement, self);
-    if (rc != SQLITE_DONE) {
-        _pysqlite_seterror(self->db);
-    }
-
-    Py_BEGIN_ALLOW_THREADS
-    rc = sqlite3_finalize(statement);
-    Py_END_ALLOW_THREADS
-
-    if (rc != SQLITE_OK && !PyErr_Occurred()) {
-        _pysqlite_seterror(self->db);
-    }
-
-error:
-    if (PyErr_Occurred()) {
-        return NULL;
-    } else {
-        Py_RETURN_NONE;
-    }
-}
-
 /*[clinic input]
 _sqlite3.Connection.commit as pysqlite_connection_commit
 
index f2be4f1a955acec106ebdabf1816f22e03f002d2..03845a696d2bf97c3605741265b958d3178f03da 100644 (file)
@@ -107,8 +107,6 @@ typedef struct
 
 extern PyTypeObject *pysqlite_ConnectionType;
 
-PyObject* _pysqlite_connection_begin(pysqlite_Connection* self);
-
 int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor);
 int pysqlite_check_thread(pysqlite_Connection* self);
 int pysqlite_check_connection(pysqlite_Connection* con);
index 8073f3bbb78c78293bb87dc9e41fd8620af1987f..7f33b3deb30f7bceddea5de24f38dd03b427ce58 100644 (file)
@@ -415,6 +415,38 @@ static int check_cursor(pysqlite_Cursor* cur)
     return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
 }
 
+static int
+begin_transaction(pysqlite_Connection *self)
+{
+    int rc;
+    sqlite3_stmt *statement;
+
+    Py_BEGIN_ALLOW_THREADS
+    rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement,
+                            NULL);
+    Py_END_ALLOW_THREADS
+
+    if (rc != SQLITE_OK) {
+        _pysqlite_seterror(self->db);
+        goto error;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    sqlite3_step(statement);
+    rc = sqlite3_finalize(statement);
+    Py_END_ALLOW_THREADS
+
+    if (rc != SQLITE_OK && !PyErr_Occurred()) {
+        _pysqlite_seterror(self->db);
+    }
+
+error:
+    if (PyErr_Occurred()) {
+        return -1;
+    }
+    return 0;
+}
+
 static PyObject *
 get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation)
 {
@@ -431,7 +463,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
     PyObject* parameters = NULL;
     int i;
     int rc;
-    PyObject* result;
     int numcols;
     PyObject* column_name;
     sqlite_int64 lastrowid;
@@ -515,13 +546,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
 
     /* We start a transaction implicitly before a DML statement.
        SELECT is the only exception. See #9924. */
-    if (self->connection->begin_statement && self->statement->is_dml) {
-        if (sqlite3_get_autocommit(self->connection->db)) {
-            result = _pysqlite_connection_begin(self->connection);
-            if (!result) {
-                goto error;
-            }
-            Py_DECREF(result);
+    if (self->connection->begin_statement
+        && self->statement->is_dml
+        && sqlite3_get_autocommit(self->connection->db))
+    {
+        if (begin_transaction(self->connection) < 0) {
+            goto error;
         }
     }