File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -273,9 +273,10 @@ def close(self) -> None:
273273 connection-close would otherwise issue a kernel call into an
274274 already-disposed session.
275275 """
276- # Drop rows parked by fetchone() so post-close fetches return
277- # nothing, matching the cleared batch FIFO below.
276+ # Drop rows parked by fetchone() (and any lost-rows poison) so
277+ # post-close fetches return nothing, matching the cleared batch FIFO below.
278278 self ._row_buffer_clear ()
279+ self ._lost_rows_error = None
279280 if self ._kernel_handle is None :
280281 return
281282 if not self .connection .open :
Original file line number Diff line number Diff line change @@ -563,8 +563,10 @@ def close(self) -> None:
563563 if isinstance (e .args [1 ], CursorAlreadyClosedError ):
564564 logger .info ("Operation was canceled by a prior request" )
565565 finally :
566- # Drop rows parked by fetchone() so post-close fetches return nothing.
566+ # Drop rows parked by fetchone() (and any lost-rows poison) so
567+ # post-close fetches return nothing.
567568 self ._row_buffer_clear ()
569+ self ._lost_rows_error = None
568570 self .has_been_closed_server_side = True
569571 self .status = CommandState .CLOSED
570572
Original file line number Diff line number Diff line change @@ -390,6 +390,23 @@ def test_close_drops_fetchone_row_buffer(self):
390390 self .assertEqual (fetch_after_close (rs ), [])
391391 self .assertIsNone (rs .fetchone ())
392392
393+ def test_close_clears_lost_rows_error (self ):
394+ # A result set poisoned by a lost fetchone() refill must behave like any
395+ # other closed result set: post-close fetches return nothing, not raise.
396+ from databricks .sql .result_set import _FETCHONE_BUFFER_MAX_ROWS
397+
398+ rs = self .make_dummy_result_set_from_initial_results ([[1 ], [2 ], [3 ]])
399+ # Warm refill pulls every row into the buffer, so the queue is empty.
400+ rs ._fetchone_refill_rows = _FETCHONE_BUFFER_MAX_ROWS
401+ self .assertSequenceEqual (rs .fetchone (), [1 ])
402+ rs ._lost_rows_error = "lost"
403+ with self .assertRaises (InternalError ):
404+ rs .fetchone ()
405+ rs .close ()
406+ self .assertIsNone (rs ._lost_rows_error )
407+ self .assertIsNone (rs .fetchone ())
408+ self .assertEqual (rs .fetchall (), [])
409+
393410 def test_fetchone_refill_does_not_fetch_extra_pages (self ):
394411 # A refill must not make extra round-trips to fill ``arraysize`` when
395412 # server pages are smaller (e.g. byte-limited): it serves what the current
Original file line number Diff line number Diff line change @@ -288,6 +288,16 @@ def test_close_drops_fetchone_row_buffer(int_schema):
288288 assert rs .fetchall () == []
289289
290290
291+ def test_close_clears_lost_rows_error (int_schema ):
292+ # A poisoned result set must return nothing after close(), not keep raising.
293+ rs = _make_rs (_ten_rows_handle (int_schema ), arraysize = 4 )
294+ rs ._lost_rows_error = "lost"
295+ rs .close ()
296+ assert rs ._lost_rows_error is None
297+ assert rs .fetchone () is None
298+ assert rs .fetchall () == []
299+
300+
291301def test_empty_stream (int_schema ):
292302 rs = _make_rs (_FakeKernelHandle (int_schema , []))
293303 assert rs .fetchone () is None
You can’t perform that action at this time.
0 commit comments