[issue29355] sqlite3: remove sqlite3_stmt_readonly()

Ma Lin report at bugs.python.org
Wed Feb 22 21:33:59 EST 2017


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 <report at bugs.python.org>
<http://bugs.python.org/issue29355>
_______________________________________


More information about the Python-bugs-list mailing list