@@ -67,9 +67,6 @@ def __init__(self, connection: TConnection, **kwargs):
6767 self ._exception_factory = ExceptionFactory ()
6868 self ._buffered : bool = bool (kwargs .pop ('buffered' , True ))
6969 self ._result : Optional [TResult ] = None
70- self ._executemany_mode : bool = False
71- self ._executemany_rowcount : int = 0
72- self ._executemany_lastrowid : Optional [int ] = None
7370 self ._force_binary : bool = False
7471 self ._stmt : Optional [PrepareStmtPacket ] = None
7572 if kwargs :
@@ -91,9 +88,6 @@ def __init__(self, connection: TConnection, **kwargs):
9188 @property
9289 def rowcount (self ) -> int :
9390 """Get the number of rows (read-only property)"""
94- # For executemany, return the aggregated rowcount
95- if self ._executemany_mode :
96- return self ._executemany_rowcount
9791 # Get the current completion
9892 if self ._completion_index < len (self ._completions ):
9993 completion = self ._completions [self ._completion_index ]
@@ -147,8 +141,6 @@ def sp_outparams(self) -> bool:
147141 def lastrowid (self ) -> Optional [int ]:
148142 """Get the last insert ID from the current completion"""
149143 # For executemany, return the last insert ID from all executions
150- if self ._executemany_mode :
151- return self ._executemany_lastrowid
152144 if self ._completion_index < len (self ._completions ):
153145 completion = self ._completions [self ._completion_index ]
154146 return completion .insert_id or None
@@ -287,11 +279,6 @@ def _process_completions(self, completions: List[Any]) -> None:
287279 Args:
288280 completions: List of completion objects
289281 """
290- # Reset executemany mode for regular execute
291- self ._executemany_mode = False
292- self ._executemany_rowcount = 0
293- self ._executemany_lastrowid = None
294-
295282 # Store all completions for nextset() functionality
296283 self ._completions = completions
297284 self ._completion_index = 0
@@ -321,53 +308,33 @@ def _process_rows_set_completion(self, result_set: Result) -> None:
321308 """
322309 self ._result = result_set
323310
324- def _process_executemany_completions (self , completions : List [Any ]) -> None :
311+ def _process_executemany_completions (self , completions : List [List [ Completion ] ]) -> None :
325312 """
326313 Process completions from executemany - aggregate all result sets.
327314 Since executemany runs the same query multiple times, all completions have identical metadata.
328- """
329- # Enable executemany mode and calculate aggregated values
330- self ._executemany_mode = True
331- self ._executemany_rowcount = 0
332- self ._executemany_lastrowid = None
333-
334- # Calculate total affected rows and last insert ID from all completions
335- for c in completions :
336- if c .affected_rows >= 0 :
337- self ._executemany_rowcount += c .affected_rows
338- if c .insert_id is not None and c .insert_id > 0 :
339- self ._executemany_lastrowid = c .insert_id
340315
316+ Args:
317+ completions: List[List[Completion]] - one list per executed message
318+ """
341319 if not completions :
342320 self ._result = None
343321 return
344-
345- # Find completions with result sets
346- result_set_completions = [c for c in completions if c .has_result_set ()]
347-
348- if not result_set_completions :
349- # No result sets - just update counts (e.g., INSERT/UPDATE/DELETE)
350- # The aggregated values are already set above
322+
323+ firstCompletion = completions [0 ]
324+ if not firstCompletion :
351325 self ._result = None
352326 return
353-
354- # All completions have identical metadata - use the first one
355- first_rs = result_set_completions [0 ].get_result_set ()
356- first_columns = first_rs .columns
357-
358- # Aggregate all rows from all result sets
359- aggregated_rows = []
360- for completion in result_set_completions :
361- rs = completion .get_result_set ()
362- rows = rs .rows if hasattr (rs , 'rows' ) else rs .get ('rows' , [])
363- aggregated_rows .extend (rows )
364-
365- # Build result from aggregated data (description will be computed on-demand)
366- self ._result = self ._create_complete_result (
367- columns = first_columns ,
368- column_count = len (first_columns ),
369- rows = aggregated_rows
370- )
327+
328+ for u in range (1 , len (completions )):
329+ unit_completions = completions [u ]
330+ for i , c in enumerate (unit_completions ):
331+ if c .affected_rows >= 0 :
332+ firstCompletion [i ].affected_rows += c .affected_rows
333+ if c .insert_id is not None and c .insert_id > 0 :
334+ firstCompletion [i ].insert_id = c .insert_id
335+ if c .has_result_set ():
336+ firstCompletion [i ].result_set .rows .extend (c .result_set .rows )
337+ self ._process_completions (firstCompletion )
371338
372339 def _build_description (self , columns : List [ColumnDefinitionPacket ]) -> Optional [tuple ]:
373340 """Build cursor description tuple from column definitions"""
0 commit comments