Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit875de61

Browse files
gh-93421: Update sqlite3 cursor.rowcount only after SQLITE_DONE (#93526)
1 parent5849af7 commit875de61

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

‎Lib/test/test_sqlite3/test_dbapi.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,14 @@ def test_rowcount_executemany(self):
898898
self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
899899
self.assertEqual(self.cu.rowcount,3)
900900

901+
@unittest.skipIf(sqlite.sqlite_version_info< (3,35,0),
902+
"Requires SQLite 3.35.0 or newer")
903+
deftest_rowcount_update_returning(self):
904+
# gh-93421: rowcount is updated correctly for UPDATE...RETURNING queries
905+
self.cu.execute("update test set name='bar' where name='foo' returning 1")
906+
self.assertEqual(self.cu.fetchone()[0],1)
907+
self.assertEqual(self.cu.rowcount,1)
908+
901909
deftest_total_changes(self):
902910
self.cu.execute("insert into test(name) values ('foo')")
903911
self.cu.execute("insert into test(name) values ('foo')")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Update:data:`sqlite3.Cursor.rowcount` when a DML statement has run to
2+
completion. This fixes the row count for SQL queries like
3+
``UPDATE ... RETURNING``. Patch by Erlend E. Aasland.

‎Modules/_sqlite/cursor.c‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
835835
stmt_reset(self->statement);
836836
}
837837

838-
/* reset descriptionand rowcount*/
838+
/* reset description */
839839
Py_INCREF(Py_None);
840840
Py_SETREF(self->description,Py_None);
841-
self->rowcount=0L;
842841

843842
if (self->statement) {
844843
(void)stmt_reset(self->statement);
@@ -867,6 +866,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
867866

868867
stmt_reset(self->statement);
869868
stmt_mark_dirty(self->statement);
869+
self->rowcount=self->statement->is_dml ?0L :-1L;
870870

871871
/* We start a transaction implicitly before a DML statement.
872872
SELECT is the only exception. See #9924. */
@@ -944,18 +944,18 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
944944
}
945945
}
946946

947-
if (self->statement->is_dml) {
948-
self->rowcount+= (long)sqlite3_changes(self->connection->db);
949-
}else {
950-
self->rowcount=-1L;
951-
}
952-
953947
if (rc==SQLITE_DONE&& !multiple) {
948+
if (self->statement->is_dml) {
949+
self->rowcount= (long)sqlite3_changes(self->connection->db);
950+
}
954951
stmt_reset(self->statement);
955952
Py_CLEAR(self->statement);
956953
}
957954

958955
if (multiple) {
956+
if (self->statement->is_dml&&rc==SQLITE_DONE) {
957+
self->rowcount+= (long)sqlite3_changes(self->connection->db);
958+
}
959959
stmt_reset(self->statement);
960960
}
961961
Py_XDECREF(parameters);
@@ -1125,6 +1125,9 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
11251125
}
11261126
intrc=stmt_step(stmt);
11271127
if (rc==SQLITE_DONE) {
1128+
if (self->statement->is_dml) {
1129+
self->rowcount= (long)sqlite3_changes(self->connection->db);
1130+
}
11281131
(void)stmt_reset(self->statement);
11291132
}
11301133
elseif (rc!=SQLITE_ROW) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp