@@ -329,6 +329,10 @@ class InvalidChunk(RuntimeError):
329
329
"""Exception raised to to invalid chunk data from back-end."""
330
330
331
331
332
+ class InvalidRetryRequest (RuntimeError ):
333
+ """Exception raised when retry request is invalid."""
334
+
335
+
332
336
def _retry_read_rows_exception (exc ):
333
337
if isinstance (exc , grpc .RpcError ):
334
338
exc = exceptions .from_grpc_error (exc )
@@ -487,6 +491,9 @@ def __iter__(self):
487
491
if self .state != self .NEW_ROW :
488
492
raise ValueError ("The row remains partial / is not committed." )
489
493
break
494
+ except InvalidRetryRequest :
495
+ self ._cancelled = True
496
+ break
490
497
491
498
for chunk in response .chunks :
492
499
if self ._cancelled :
@@ -625,29 +632,38 @@ def __init__(self, message, last_scanned_key, rows_read_so_far):
625
632
626
633
def build_updated_request (self ):
627
634
"""Updates the given message request as per last scanned key"""
628
- r_kwargs = {
629
- "table_name" : self . message . table_name ,
630
- "filter" : self .message . filter ,
631
- }
635
+
636
+ resume_request = data_messages_v2_pb2 . ReadRowsRequest ()
637
+ data_messages_v2_pb2 . ReadRowsRequest . CopyFrom ( resume_request , self .message )
638
+ resume_request . rows . Clear ()
632
639
633
640
if self .message .rows_limit != 0 :
634
- r_kwargs ["rows_limit" ] = max (
635
- 1 , self .message .rows_limit - self .rows_read_so_far
636
- )
641
+ row_limit_remaining = self .message .rows_limit - self .rows_read_so_far
642
+ if row_limit_remaining > 0 :
643
+ resume_request .rows_limit = row_limit_remaining
644
+ else :
645
+ raise InvalidRetryRequest
637
646
638
647
# if neither RowSet.row_keys nor RowSet.row_ranges currently exist,
639
648
# add row_range that starts with last_scanned_key as start_key_open
640
649
# to request only rows that have not been returned yet
641
650
if not self .message .HasField ("rows" ):
642
651
row_range = data_v2_pb2 .RowRange (start_key_open = self .last_scanned_key )
643
- r_kwargs [ " rows" ] = data_v2_pb2 . RowSet ( row_ranges = [ row_range ] )
652
+ resume_request . rows . row_ranges . add (). CopyFrom ( row_range )
644
653
else :
645
654
row_keys = self ._filter_rows_keys ()
646
655
row_ranges = self ._filter_row_ranges ()
647
- r_kwargs ["rows" ] = data_v2_pb2 .RowSet (
648
- row_keys = row_keys , row_ranges = row_ranges
649
- )
650
- return data_messages_v2_pb2 .ReadRowsRequest (** r_kwargs )
656
+
657
+ if len (row_keys ) == 0 and len (row_ranges ) == 0 :
658
+ # Avoid sending empty row_keys and row_ranges
659
+ # if that was not the intention
660
+ raise InvalidRetryRequest
661
+
662
+ resume_request .rows .row_keys [:] = row_keys
663
+ for rr in row_ranges :
664
+ resume_request .rows .row_ranges .add ().CopyFrom (rr )
665
+
666
+ return resume_request
651
667
652
668
def _filter_rows_keys (self ):
653
669
"""Helper for :meth:`build_updated_request`"""
0 commit comments