@@ -257,6 +257,9 @@ def _convert_rows_individually(
257257 def _cap_to_current_chunk (self , size : int ) -> int :
258258 """Cap ``size`` at the rows left in the current CloudFetch chunk, if any.
259259
260+ Limits each fetchone() refill to a single CloudFetch chunk. It does not
261+ avoid waiting on the next download: ``next_n_rows`` advances to the next
262+ file as soon as the current one is fully read, inside the same call.
260263 Shared by the Thrift and SEA fetchone() refills so the CloudFetchQueue
261264 internals (``table`` / ``table_row_index``) are read in one place.
262265 """
@@ -604,10 +607,11 @@ def _fetch_available_from_queue(self, size: int):
604607 until ``size`` rows are collected: it only refills the queue while it is
605608 empty, so fetchone() makes no more round-trips than it needs to return one
606609 row (server pages can be smaller than ``size`` when they hit the byte limit).
607- On CloudFetch, ``next_n_rows`` keeps walking downloaded files until it has
608- ``size`` rows, so the request is also capped at what the current chunk still
609- holds; otherwise a refill near a chunk boundary would block on the next
610- download before returning a row that is already available.
610+ On CloudFetch, the request is also capped at what the current chunk still
611+ holds (see ``_cap_to_current_chunk``), so a refill never stitches rows from
612+ several downloaded files into one batch. This only bounds the batch: reading
613+ to the end of a chunk still makes ``next_n_rows`` advance to (and wait for)
614+ the next file before it returns, exactly as the uncapped path did.
611615 Only called while the fetchone() row buffer is empty.
612616 """
613617 results = self .results .next_n_rows (self ._cap_to_current_chunk (size ))
0 commit comments