Skip to content

Commit 02b8baf

Browse files
ai: apply changes for #1007 (1 review thread)
Addresses: - #4419671350 at src/databricks/sql/result_set.py:567 Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>
1 parent 4a4bc03 commit 02b8baf

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

‎src/databricks/sql/backend/kernel/result_set.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff 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:

‎src/databricks/sql/result_set.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff 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

‎tests/unit/test_fetches.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff 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

‎tests/unit/test_kernel_result_set.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
291301
def test_empty_stream(int_schema):
292302
rs = _make_rs(_FakeKernelHandle(int_schema, []))
293303
assert rs.fetchone() is None

0 commit comments

Comments
 (0)