You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The part to set is_dml skips space, tabs and newline and checks for the first set of characters that is not skipped to be insert, update, delete or replace and in this case the first set of characters to be matched will be "/* watermarking */". Thus with comment not matching, is_dml is not set and -1 is set for the rowcount.
Now that we require SQLite 3.7.15, we can safely use sqlite3_stmt_readonly to determine if we should update .rowcount or not. The API returns true for SELECT queries, which is also the case today. The API is pretty conservative, and returns false for cases where a query might modify the database. In those cases, we may end up with .rowcount being zero. That is perfectly fine.
I see no reason not to use sqlite3_stmt_readonly to solve this.
EDIT:
sqlite3_changes support INSERT, UPDATE, and DELETE statements only. sqlite3_stmt_readonly encompasses a lot more than that. As long as we are using sqlite3_changes to update .rowcount, we simply cannot use sqlite3_stmt_readonly, because SQLite does not reset the number returned by sqlite3_changes; for unsupported statements, you may end up with sqlite3_changes returning the change count for a previous statement.
If we'd used something like sqlite3_total_changes64, we could safely use sqlite3_stmt_readonly, because in the worst cases we'd end up with a .rowcount of zero, and that is perfectly fine.
Activity
montanalow commentedon Dec 4, 2018
SQLite driver returns an incorrect row count (-1) for UPDATE statements that begin with a comment.
Downstream Reference:
sqlalchemy/sqlalchemy#4396
Test Case:
tirkarthi commentedon Dec 4, 2018
Did some debugging here. If I am understanding this correctly the rowcount is set at
cpython/Modules/_sqlite/cursor.c
Line 574 in b8e689a
cpython/Modules/_sqlite/statement.c
Line 78 in b8e689a
The part to set is_dml skips space, tabs and newline and checks for the first set of characters that is not skipped to be insert, update, delete or replace and in this case the first set of characters to be matched will be "/* watermarking */". Thus with comment not matching, is_dml is not set and -1 is set for the rowcount.
montanalow commentedon Dec 5, 2018
I took a stab at patch. It fixes the issue for me, as proven via the Test Case.
erlend-aasland commentedon Aug 11, 2021
See also gh-81040.
erlend-aasland commentedon Jun 6, 2022
Now that we require SQLite 3.7.15, we can safely use sqlite3_stmt_readonly to determine if we should update
.rowcountor not. The API returns true for SELECT queries, which is also the case today. The API is pretty conservative, and returns false for cases where a query might modify the database. In those cases, we may end up with.rowcountbeing zero. That is perfectly fine.I see no reason not to usesqlite3_stmt_readonlyto solve this.EDIT:
sqlite3_changessupport INSERT, UPDATE, and DELETE statements only.sqlite3_stmt_readonlyencompasses a lot more than that. As long as we are usingsqlite3_changesto update.rowcount, we simply cannot usesqlite3_stmt_readonly, because SQLite does not reset the number returned bysqlite3_changes; for unsupported statements, you may end up withsqlite3_changesreturning the change count for a previous statement.If we'd used something like
sqlite3_total_changes64, we could safely usesqlite3_stmt_readonly, because in the worst cases we'd end up with a.rowcountof zero, and that is perfectly fine.pythongh-79579: Update sqlite3.Cursor.rowcount for all datamodifying …
erlend-aasland commentedon Jun 8, 2022
@animalize made me change my mind about that, so I made a competing PR: gh-93623
Thanks for pushing, Ma Lin.
Merge branch 'main' into sqlite-rowcount/pythongh-79579-alt
gh-79579: Improve DML query detection in sqlite3 (#93623)
[3.11] pythongh-79579: Improve DML query detection in sqlite3 (python…
[3.10] pythongh-79579: Improve DML query detection in sqlite3 (python…
erlend-aasland commentedon Jun 14, 2022
Fixed by:
[3.11] gh-79579: Improve DML query detection in sqlite3 (GH-93623) (#…
[3.10] gh-79579: Improve DML query detection in sqlite3 (GH-93623) (#…
Revert 30935 defer bpo45162 to 312 (#94285)
sqlite3: deal with comments at the start of the query