[issue33376] [pysqlite] Duplicate rows can be returned after rolling back a transaction
Ma Lin
report at bugs.python.org
Sat Nov 27 23:26:09 EST 2021
Ma Lin <malincns at 163.com> added the comment:
Since 243b6c3b8fd3144450c477d99f01e31e7c3ebc0f (21-08-19), this bug can't be reproduced.
In `pysqlite_do_all_statements()`, 243b6c3 resets statements like this:
sqlite3_stmt *stmt = NULL;
while ((stmt = sqlite3_next_stmt(self->db, stmt))) {
if (sqlite3_stmt_busy(stmt)) {
(void)sqlite3_reset(stmt);
}
}
But the `pysqlite_Statement.in_use` flag is not reset.
In `_pysqlite_query_execute()` function, if `pysqlite_Statement.in_use` flag is 1, it creates a new `pysqlite_Statement` instance. So this line will use a new statement:
gen = conn.execute("SELECT c FROM t WHERE ?", (1,))
The duplicate row is from `pysqlite_Cursor.next_row` before 3df0fc89bc2714f5ef03e36a926bc795dcd5e05a (21-08-25).
A digressive suggestion is whether it can be changed like this, and add a check for resetting statement. So that statements are not allowed to be reset by other Cursors, which may improve code robust:
typedef struct
{
...
- int in_use;
+ pysqlite_Cursor *in_use; // points to the attached cursor
...
} pysqlite_Statement;
----------
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue33376>
_______________________________________
More information about the Python-bugs-list
mailing list