[Python-checkins] gh-93421: Update sqlite3 cursor.rowcount only after SQLITE_DONE (GH-93526)
miss-islington
webhook-mailer at python.org
Wed Jun 8 07:07:20 EDT 2022
https://github.com/python/cpython/commit/68aae80159996374509b98b6345ff9b72743b4d9
commit: 68aae80159996374509b98b6345ff9b72743b4d9
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-06-08T04:07:15-07:00
summary:
gh-93421: Update sqlite3 cursor.rowcount only after SQLITE_DONE (GH-93526)
(cherry picked from commit 875de61c296604f3a3a51e9d76355e0f1a24c6af)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com>
files:
A Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst
M Lib/test/test_sqlite3/test_dbapi.py
M Modules/_sqlite/cursor.c
diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py
index e514adb35eec1..39dbbb9530033 100644
--- a/Lib/test/test_sqlite3/test_dbapi.py
+++ b/Lib/test/test_sqlite3/test_dbapi.py
@@ -903,6 +903,14 @@ def test_rowcount_executemany(self):
self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
self.assertEqual(self.cu.rowcount, 3)
+ @unittest.skipIf(sqlite.sqlite_version_info < (3, 35, 0),
+ "Requires SQLite 3.35.0 or newer")
+ def test_rowcount_update_returning(self):
+ # gh-93421: rowcount is updated correctly for UPDATE...RETURNING queries
+ self.cu.execute("update test set name='bar' where name='foo' returning 1")
+ self.assertEqual(self.cu.fetchone()[0], 1)
+ self.assertEqual(self.cu.rowcount, 1)
+
def test_total_changes(self):
self.cu.execute("insert into test(name) values ('foo')")
self.cu.execute("insert into test(name) values ('foo')")
diff --git a/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst b/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst
new file mode 100644
index 0000000000000..9e1d6554e0ab2
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst
@@ -0,0 +1,3 @@
+Update :data:`sqlite3.Cursor.rowcount` when a DML statement has run to
+completion. This fixes the row count for SQL queries like
+``UPDATE ... RETURNING``. Patch by Erlend E. Aasland.
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index c58def5f0362f..414584d8ee30e 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -835,10 +835,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
stmt_reset(self->statement);
}
- /* reset description and rowcount */
+ /* reset description */
Py_INCREF(Py_None);
Py_SETREF(self->description, Py_None);
- self->rowcount = 0L;
if (self->statement) {
(void)stmt_reset(self->statement);
@@ -867,6 +866,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
stmt_reset(self->statement);
stmt_mark_dirty(self->statement);
+ self->rowcount = self->statement->is_dml ? 0L : -1L;
/* We start a transaction implicitly before a DML statement.
SELECT is the only exception. See #9924. */
@@ -944,18 +944,18 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
}
}
- if (self->statement->is_dml) {
- self->rowcount += (long)sqlite3_changes(self->connection->db);
- } else {
- self->rowcount= -1L;
- }
-
if (rc == SQLITE_DONE && !multiple) {
+ if (self->statement->is_dml) {
+ self->rowcount = (long)sqlite3_changes(self->connection->db);
+ }
stmt_reset(self->statement);
Py_CLEAR(self->statement);
}
if (multiple) {
+ if (self->statement->is_dml && rc == SQLITE_DONE) {
+ self->rowcount += (long)sqlite3_changes(self->connection->db);
+ }
stmt_reset(self->statement);
}
Py_XDECREF(parameters);
@@ -1125,6 +1125,9 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
}
int rc = stmt_step(stmt);
if (rc == SQLITE_DONE) {
+ if (self->statement->is_dml) {
+ self->rowcount = (long)sqlite3_changes(self->connection->db);
+ }
(void)stmt_reset(self->statement);
}
else if (rc != SQLITE_ROW) {
More information about the Python-checkins
mailing list