-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sqlite3 dml statement detection does not account for CTEs #81040
Comments
In statement.c, there is some logic which detects whether or not an incoming statement is a DML-type. The logic, as of 2019-05-08, I am referring to is here: cpython/Modules/_sqlite/statement.c Lines 78 to 93 in fc662ac
To demonstrate the bug: import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('create table kv ("key" text primary key, "value" integer)')
conn.execute('insert into kv (key, value) values (?, ?), (?, ?)',
('k1', 1, 'k2', 2))
assert conn.in_transaction # Yes we are in a transaction.
conn.commit()
assert not conn.in_transaction # Not anymore, as expected.
rc = conn.execute(
'with c(k, v) as (select key, value + 10 from kv) '
'update kv set value=(select v from c where k=kv.key)')
print(rc.rowcount) # Should be 2, prints "-1".
#assert conn.in_transaction # !!! Fails.
curs = conn.execute('select * from kv order by key;')
print(curs.fetchall()) # [('k1', 11), ('k2', 12)] |
Sqlite since 3.7.11 provides sqlite3_stmt_readonly() API for determining if a prepared statement will affect the database. I made the change, removing the SQL scanning code and replacing it with: self->is_dml = !sqlite3_stmt_readonly(self->st); But then I see a number of test failures, mostly related to the fact that table-creation is now treated as "is_dml" with the above change. I don't know if the above API is going to be a workable path forward, since it seems like DML statements *not* automatically starting a transaction is a behavior a lot of people may have come to depend on (whether or not it is correct). I've attached a patch just-in-case anyone's interested. |
Oh, one more thing that is actually quite important -- since BEGIN IMMEDIATE and BEGIN EXCLUSIVE "modify" the database, these statements (intended to begin a transaction) are treated as "is_dml" when using the sqlite3_stmt_readonly API. |
I've got a patch working now that:
I think this should be good-to-go and I've in fact merged a similar patch on my own standalone pysqlite3 package. Also I will add that the little 'test script' I provided is working as-expected with this patch applied. |
CPython now accepts PRs on GitHub. Please try raising a PR as per devuguide : https://devguide.python.org/ |
I believe #13216 would be an improvement. I see that your original branch is unavailable, Charles; would you mind if I cherry-picked it and rebased it onto master? The sqlite3 module now requires SQLite >= 3.7.15 which simplifies the change a lot. |
Yeah, go for it erlendaasland - I abandoned all hope of getting it merged, and have just been maintaining my own pysqlite3 which simplifies my life greatly. |
Thanks, Charles. I'll give it a shot and see if get can provoke a response :) |
As of the recent discussion on Discourse, I'm closing this as superseded by the proposed solution in gh-83638. TL;DR: We cannot change the behaviour because of backwards compatibility. The proposed fix is to introducing a new, PEP 249 compliant way of controlling transactions. The old transaction handling ( |
I'm reopening this, because this issue materialises into two problems:
|
Suggesting to address the |
(cherry picked from commit f9b3706) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
(cherry picked from commit f9b3706) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
Rowcount docs are updated in the following branches:
Considering this as resolved. |
(cherry picked from commit f9b3706) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
(cherry picked from commit f9b3706) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: