Author malin
Recipients berker.peksag, malin, palaviv, palm.kevin, willingc
Date 2017-02-23.02:33:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1487817239.8.0.143317968486.issue29355@psf.upfronthosting.co.za>
In-reply-to
Content
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);
History
Date User Action Args
2017-02-23 02:33:59malinsetrecipients: + malin, palm.kevin, berker.peksag, willingc, palaviv
2017-02-23 02:33:59malinsetmessageid: <1487817239.8.0.143317968486.issue29355@psf.upfronthosting.co.za>
2017-02-23 02:33:59malinlinkissue29355 messages
2017-02-23 02:33:58malincreate