Ma Lin added the comment:

The "old way" is not using sqlite3_stmt_readonly().

Before 3.6.0, we only count rowcount for INSERT, UPDATE, DELETE, REPLACE:
https://hg.python.org/cpython/file/3.5/Modules/_sqlite/cursor.c#l689

These four statements can be representd by is_dml in PR 245:
https://github.com/python/cpython/pull/245/commits/cbeabf4044e9e1563d228e359b0e7952f369b42a#diff-5a6abb9997d51e693f3b24986659c857R88

So only change this line is ok, then restore the behavior before 3.6.0 exactly:

- if (!sqlite3_stmt_readonly(self->statement->st)) {
+ if (self->statement->is_dml) {
    self->rowcount += (long)sqlite3_changes(self->connection->db);
} else {
    self->rowcount= -1L;
}

Why it's better?
sqlite3_changes() only works for INSERT, UPDATE, DELETE. see:
https://sqlite.org/c3ref/changes.html
So using sqlite3_stmt_readonly() to determine statements is not necessary at 
all.

In addition, we can add a comment for code safe in statement.c.
+    /* is_dml is used in two sites:
+        1, determine statements for implicit BEGIN.
+        2, determine statements for counting rowcount */
self->is_dml = (PyOS_strnicmp(p, "insert ", 7) == 0)
            || (PyOS_strnicmp(p, "update ", 7) == 0)
            || (PyOS_strnicmp(p, "delete ", 7) == 0)
            || (PyOS_strnicmp(p, "replace ", 8) == 0);

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue29355>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to