66import pandas
77
88from databricks .sql .backend .sea .backend import SeaDatabricksClient
9+ from databricks .sql .backend .sea .models .base import ResultData , ResultManifest
910
1011try :
1112 import pyarrow
1920from databricks .sql .thrift_api .TCLIService import ttypes
2021from databricks .sql .types import Row
2122from databricks .sql .exc import Error , RequestError , CursorAlreadyClosedError
22- from databricks .sql .utils import ColumnTable , ColumnQueue
23+ from databricks .sql .utils import ColumnTable , ColumnQueue , JsonQueue , SeaResultSetQueueFactory
2324from databricks .sql .backend .types import CommandId , CommandState , ExecuteResponse
2425
2526logger = logging .getLogger (__name__ )
@@ -441,6 +442,14 @@ def __init__(
441442 sea_response: Direct SEA response (legacy style)
442443 """
443444
445+ queue = SeaResultSetQueueFactory .build_queue (
446+ sea_result_data = execute_response .results_data ,
447+ manifest = execute_response .results_manifest ,
448+ statement_id = execute_response .command_id .to_sea_statement_id (),
449+ description = execute_response .description ,
450+ schema_bytes = execute_response .arrow_schema_bytes ,
451+ )
452+
444453 super ().__init__ (
445454 connection = connection ,
446455 backend = sea_client ,
@@ -450,42 +459,135 @@ def __init__(
450459 status = execute_response .status ,
451460 has_been_closed_server_side = execute_response .has_been_closed_server_side ,
452461 has_more_rows = execute_response .has_more_rows ,
453- results_queue = execute_response . results_queue ,
462+ results_queue = queue ,
454463 description = execute_response .description ,
455464 is_staging_operation = execute_response .is_staging_operation ,
456465 )
466+
467+ def _convert_to_row_objects (self , rows ):
468+ """
469+ Convert raw data rows to Row objects with named columns based on description.
470+
471+ Args:
472+ rows: List of raw data rows
473+
474+ Returns:
475+ List of Row objects with named columns
476+ """
477+ if not self .description or not rows :
478+ return rows
479+
480+ column_names = [col [0 ] for col in self .description ]
481+ ResultRow = Row (* column_names )
482+ return [ResultRow (* row ) for row in rows ]
457483
458484 def _fill_results_buffer (self ):
459485 """Fill the results buffer from the backend."""
460- raise NotImplementedError ("fetchone is not implemented for SEA backend" )
486+ return None
487+
488+ def _convert_rows_to_arrow_table (self , rows ):
489+ """Convert rows to Arrow table."""
490+ if not self .description :
491+ return pyarrow .Table .from_pylist ([])
492+
493+ # Create dict of column data
494+ column_data = {}
495+ column_names = [col [0 ] for col in self .description ]
496+
497+ for i , name in enumerate (column_names ):
498+ column_data [name ] = [row [i ] for row in rows ]
499+
500+ return pyarrow .Table .from_pydict (column_data )
501+
502+ def _create_empty_arrow_table (self ):
503+ """Create an empty Arrow table with the correct schema."""
504+ if not self .description :
505+ return pyarrow .Table .from_pylist ([])
506+
507+ column_names = [col [0 ] for col in self .description ]
508+ return pyarrow .Table .from_pydict ({name : [] for name in column_names })
461509
462510 def fetchone (self ) -> Optional [Row ]:
463511 """
464512 Fetch the next row of a query result set, returning a single sequence,
465513 or None when no more data is available.
466514 """
467-
468- raise NotImplementedError ("fetchone is not implemented for SEA backend" )
515+ if isinstance (self .results , JsonQueue ):
516+ rows = self .results .next_n_rows (1 )
517+ if not rows :
518+ return None
519+
520+ # Convert to Row object
521+ converted_rows = self ._convert_to_row_objects (rows )
522+ return converted_rows [0 ] if converted_rows else None
523+ else :
524+ raise NotImplementedError ("Unsupported queue type" )
469525
470526 def fetchmany (self , size : Optional [int ] = None ) -> List [Row ]:
471527 """
472528 Fetch the next set of rows of a query result, returning a list of rows.
473529
474530 An empty sequence is returned when no more rows are available.
475531 """
532+ if size is None :
533+ size = self .arraysize
534+
535+ if size < 0 :
536+ raise ValueError (f"size argument for fetchmany is { size } but must be >= 0" )
537+
538+ # Note: We check for the specific queue type to maintain consistency with ThriftResultSet
539+ if isinstance (self .results , JsonQueue ):
540+ rows = self .results .next_n_rows (size )
541+ self ._next_row_index += len (rows )
476542
477- raise NotImplementedError ("fetchmany is not implemented for SEA backend" )
543+ # Convert to Row objects
544+ return self ._convert_to_row_objects (rows )
545+ else :
546+ raise NotImplementedError ("Unsupported queue type" )
478547
479548 def fetchall (self ) -> List [Row ]:
480549 """
481550 Fetch all (remaining) rows of a query result, returning them as a list of rows.
482551 """
483- raise NotImplementedError ("fetchall is not implemented for SEA backend" )
552+ # Note: We check for the specific queue type to maintain consistency with ThriftResultSet
553+ if isinstance (self .results , JsonQueue ):
554+ rows = self .results .remaining_rows ()
555+ self ._next_row_index += len (rows )
556+
557+ # Convert to Row objects
558+ return self ._convert_to_row_objects (rows )
559+ else :
560+ raise NotImplementedError ("Unsupported queue type" )
484561
485562 def fetchmany_arrow (self , size : int ) -> Any :
486563 """Fetch the next set of rows as an Arrow table."""
487- raise NotImplementedError ("fetchmany_arrow is not implemented for SEA backend" )
564+ if not pyarrow :
565+ raise ImportError ("PyArrow is required for Arrow support" )
566+
567+ if isinstance (self .results , JsonQueue ):
568+ rows = self .fetchmany (size )
569+ if not rows :
570+ # Return empty Arrow table with schema
571+ return self ._create_empty_arrow_table ()
572+
573+ # Convert rows to Arrow table
574+ return self ._convert_rows_to_arrow_table (rows )
575+ else :
576+ raise NotImplementedError ("Unsupported queue type" )
488577
489578 def fetchall_arrow (self ) -> Any :
490579 """Fetch all remaining rows as an Arrow table."""
491- raise NotImplementedError ("fetchall_arrow is not implemented for SEA backend" )
580+ if not pyarrow :
581+ raise ImportError ("PyArrow is required for Arrow support" )
582+
583+ if isinstance (self .results , JsonQueue ):
584+ rows = self .fetchall ()
585+ if not rows :
586+ # Return empty Arrow table with schema
587+ return self ._create_empty_arrow_table ()
588+
589+ # Convert rows to Arrow table
590+ return self ._convert_rows_to_arrow_table (rows )
591+ else :
592+ raise NotImplementedError ("Unsupported queue type" )
593+
0 commit comments