From 239ead3de23e39b869f460acf20fb5c112ffb749 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 20 Jun 2022 23:10:03 +0200 Subject: [PATCH 1/5] gh-94028: Clear and reset sqlite3 statements properly in cursor iternext --- Modules/_sqlite/cursor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 414584d8ee30e9..3f5cfef0c32589 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -1129,10 +1129,13 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) self->rowcount = (long)sqlite3_changes(self->connection->db); } (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); } else if (rc != SQLITE_ROW) { (void)_pysqlite_seterror(self->connection->state, self->connection->db); + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); Py_DECREF(row); return NULL; } From 5c59655fd8c52f39124a99a5c47d4bb76774b729 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 20 Jun 2022 23:14:47 +0200 Subject: [PATCH 2/5] Add NEWS --- .../next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst diff --git a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst new file mode 100644 index 00000000000000..4e3d175adb0979 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst @@ -0,0 +1,3 @@ +Fix a regression in the :mod:`sqlite3` where statement objects were not +properly cleared and reset after use in cursor iters. The regression was +introduced by gh-27884 in Python 3.11a1. Patch by Erlend E. Aasland. From f08c504ecb73f169ffe7015742bcce1069576599 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 20 Jun 2022 23:15:40 +0200 Subject: [PATCH 3/5] Update 2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst --- .../next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst index 4e3d175adb0979..e209bc762fb09d 100644 --- a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst +++ b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst @@ -1,3 +1,3 @@ Fix a regression in the :mod:`sqlite3` where statement objects were not properly cleared and reset after use in cursor iters. The regression was -introduced by gh-27884 in Python 3.11a1. Patch by Erlend E. Aasland. +introduced by :gh:`27884` in Python 3.11a1. Patch by Erlend E. Aasland. From ae7c8961ecba55a5ee8e5c0c9216a30b92a0f74a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 20 Jun 2022 23:37:15 +0200 Subject: [PATCH 4/5] Add issue repro as test --- Lib/test/test_sqlite3/test_transactions.py | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py index 21acad8383c29e..a67d72709d39ab 100644 --- a/Lib/test/test_sqlite3/test_transactions.py +++ b/Lib/test/test_sqlite3/test_transactions.py @@ -139,6 +139,45 @@ def test_rollback_cursor_consistency(self): con.rollback() self.assertEqual(cur.fetchall(), [(1,), (2,), (3,)]) + def test_multiple_cursors_and_iternext(self): + # gh-94028: statements are cleared and reset in cursor iternext. + + # Provoke the gh-94028 by using a cursor cache. + CURSORS = {} + def sql(cx, sql, *args): + cu = cx.cursor() + cu.execute(sql, args) + CURSORS[id(sql)] = cu + return cu + + self.con1.execute("create table t(t)") + sql(self.con1, "insert into t values (?), (?), (?)", "u1", "u2", "u3") + self.con1.commit() + + # On second connection, verify rows are visible, then delete them. + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 3) + changes = sql(self.con2, "delete from t").rowcount + self.assertEqual(changes, 3) + self.con2.commit() + + # Back in original connection, create 2 new users. + sql(self.con1, "insert into t values (?)", "u4") + sql(self.con1, "insert into t values (?)", "u5") + + # The second connection cannot see uncommitted changes. + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 0) + + # First connection can see its own changes. + count = sql(self.con1, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 2) + + # The second connection can now see the changes. + self.con1.commit() + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 2) + class RollbackTests(unittest.TestCase): """bpo-44092: sqlite3 now leaves it to SQLite to resolve rollback issues""" From 4e4b4da86dd8bedd74b26dfe2db31ae0c7dd4cdb Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 20 Jun 2022 23:40:54 +0200 Subject: [PATCH 5/5] Update 2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst --- .../next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst index e209bc762fb09d..5775b2276d70b4 100644 --- a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst +++ b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst @@ -1,3 +1,3 @@ Fix a regression in the :mod:`sqlite3` where statement objects were not properly cleared and reset after use in cursor iters. The regression was -introduced by :gh:`27884` in Python 3.11a1. Patch by Erlend E. Aasland. +introduced by PR 27884 in Python 3.11a1. Patch by Erlend E. Aasland. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy