@@ -141,6 +141,45 @@ def test_rollback_cursor_consistency(self):
141
141
con .rollback ()
142
142
self .assertEqual (cur .fetchall (), [(1 ,), (2 ,), (3 ,)])
143
143
144
+ def test_multiple_cursors_and_iternext (self ):
145
+ # gh-94028: statements are cleared and reset in cursor iternext.
146
+
147
+ # Provoke the gh-94028 by using a cursor cache.
148
+ CURSORS = {}
149
+ def sql (cx , sql , * args ):
150
+ cu = cx .cursor ()
151
+ cu .execute (sql , args )
152
+ CURSORS [id (sql )] = cu
153
+ return cu
154
+
155
+ self .con1 .execute ("create table t(t)" )
156
+ sql (self .con1 , "insert into t values (?), (?), (?)" , "u1" , "u2" , "u3" )
157
+ self .con1 .commit ()
158
+
159
+ # On second connection, verify rows are visible, then delete them.
160
+ count = sql (self .con2 , "select count(*) from t" ).fetchone ()[0 ]
161
+ self .assertEqual (count , 3 )
162
+ changes = sql (self .con2 , "delete from t" ).rowcount
163
+ self .assertEqual (changes , 3 )
164
+ self .con2 .commit ()
165
+
166
+ # Back in original connection, create 2 new users.
167
+ sql (self .con1 , "insert into t values (?)" , "u4" )
168
+ sql (self .con1 , "insert into t values (?)" , "u5" )
169
+
170
+ # The second connection cannot see uncommitted changes.
171
+ count = sql (self .con2 , "select count(*) from t" ).fetchone ()[0 ]
172
+ self .assertEqual (count , 0 )
173
+
174
+ # First connection can see its own changes.
175
+ count = sql (self .con1 , "select count(*) from t" ).fetchone ()[0 ]
176
+ self .assertEqual (count , 2 )
177
+
178
+ # The second connection can now see the changes.
179
+ self .con1 .commit ()
180
+ count = sql (self .con2 , "select count(*) from t" ).fetchone ()[0 ]
181
+ self .assertEqual (count , 2 )
182
+
144
183
145
184
class RollbackTests (unittest .TestCase ):
146
185
"""bpo-44092: sqlite3 now leaves it to SQLite to resolve rollback issues"""
0 commit comments