77
88import json
99import logging
10- from typing import Optional , List , Any , Dict , Tuple
10+ from typing import Optional , List , Any , Dict , Tuple , cast
11+
12+ try :
13+ import pyarrow
14+ except ImportError :
15+ pyarrow = None
1116
1217from databricks .sql .result_set import ResultSet
1318from databricks .sql .types import Row
1419from databricks .sql .backend .types import CommandId , CommandState
1520from databricks .sql .exc import Error
21+ from databricks .sql .utils import ResultSetQueueFactory , JsonQueue
1622
1723from databricks .sql .backend .models import (
1824 StatementStatus ,
@@ -106,14 +112,19 @@ def __init__(
106112
107113 # Initialize other properties
108114 self ._is_staging_operation = False # SEA doesn't have staging operations
109- self ._rows_buffer = []
110- self ._current_row_index = 0
111- self ._has_more_rows = True
115+ self ._has_more_rows = False
112116 self ._current_chunk_index = 0
113117
114- # If we have inline data, fill the buffer
115- if self .result and self .result .data :
116- self ._rows_buffer = self .result .data
118+ # Initialize queue for result data
119+ if self .result :
120+ self .results = ResultSetQueueFactory .build_queue (
121+ sea_result_data = self .result ,
122+ description = cast (Optional [List [List [Any ]]], self .description )
123+ )
124+ self ._has_more_rows = True if self .result .data else False
125+ else :
126+ self .results = JsonQueue ([])
127+ self ._has_more_rows = False
117128
118129 @property
119130 def is_staging_operation (self ) -> bool :
@@ -153,28 +164,120 @@ def _extract_description_from_manifest(
153164 return description
154165
155166 def _fill_results_buffer (self ) -> None :
156- """Fill the results buffer from the backend."""
157- raise NotImplementedError ("Not implemented yet" )
167+ """Fill the results buffer from the backend for INLINE disposition."""
168+ if not self .result or not self .result .data :
169+ self ._has_more_rows = False
170+ return
171+
172+ # For INLINE disposition, we already have all the data
173+ # No need to fetch more data from the backend
174+ self ._has_more_rows = False # No more rows to fetch for INLINE
175+
176+ def _convert_rows_to_arrow_table (self , rows ):
177+ """Convert rows to Arrow table."""
178+ if not self .description :
179+ return pyarrow .Table .from_pylist ([])
180+
181+ # Create dict of column data
182+ column_data = {}
183+ column_names = [col [0 ] for col in self .description ]
184+
185+ for i , name in enumerate (column_names ):
186+ column_data [name ] = [row [i ] for row in rows ]
187+
188+ return pyarrow .Table .from_pydict (column_data )
189+
190+ def _create_empty_arrow_table (self ):
191+ """Create an empty Arrow table with the correct schema."""
192+ if not self .description :
193+ return pyarrow .Table .from_pylist ([])
194+
195+ column_names = [col [0 ] for col in self .description ]
196+ return pyarrow .Table .from_pydict ({name : [] for name in column_names })
158197
159198 def fetchone (self ) -> Optional [Row ]:
160199 """Fetch the next row of a query result set."""
161- raise NotImplementedError ("Not implemented yet" )
200+ if isinstance (self .results , JsonQueue ):
201+ rows = self .results .next_n_rows (1 )
202+ if not rows :
203+ return None
204+
205+ row = rows [0 ]
206+
207+ # Convert to Row object
208+ if self .description :
209+ column_names = [col [0 ] for col in self .description ]
210+ ResultRow = Row (* column_names )
211+ return ResultRow (* row )
212+ return row
213+ else :
214+ # This should not happen with current implementation
215+ # but added for future compatibility
216+ raise NotImplementedError ("Unsupported queue type" )
162217
163- def fetchmany (self , size : int ) -> List [Row ]:
218+ def fetchmany (self , size : Optional [ int ] = None ) -> List [Row ]:
164219 """Fetch the next set of rows of a query result."""
165- raise NotImplementedError ("Not implemented yet" )
220+ if size is None :
221+ size = self .arraysize
222+
223+ if size < 0 :
224+ raise ValueError (f"size argument for fetchmany is { size } but must be >= 0" )
225+
226+ if isinstance (self .results , JsonQueue ):
227+ rows = self .results .next_n_rows (size )
228+
229+ # Convert to Row objects
230+ if self .description :
231+ column_names = [col [0 ] for col in self .description ]
232+ ResultRow = Row (* column_names )
233+ return [ResultRow (* row ) for row in rows ]
234+ return rows
235+ else :
236+ # This should not happen with current implementation
237+ # but added for future compatibility
238+ raise NotImplementedError ("Unsupported queue type" )
166239
167240 def fetchall (self ) -> List [Row ]:
168241 """Fetch all remaining rows of a query result."""
169- raise NotImplementedError ("Not implemented yet" )
242+ if isinstance (self .results , JsonQueue ):
243+ rows = self .results .remaining_rows ()
244+
245+ # Convert to Row objects
246+ if self .description :
247+ column_names = [col [0 ] for col in self .description ]
248+ ResultRow = Row (* column_names )
249+ return [ResultRow (* row ) for row in rows ]
250+ return rows
251+ else :
252+ # This should not happen with current implementation
253+ # but added for future compatibility
254+ raise NotImplementedError ("Unsupported queue type" )
170255
171256 def fetchmany_arrow (self , size : int ) -> Any :
172257 """Fetch the next set of rows as an Arrow table."""
173- raise NotImplementedError ("Not implemented yet" )
258+ if not pyarrow :
259+ raise ImportError ("PyArrow is required for Arrow support" )
260+
261+ rows = self .fetchmany (size )
262+ if not rows :
263+ # Return empty Arrow table with schema
264+ return self ._create_empty_arrow_table ()
265+
266+ # Convert rows to Arrow table
267+ return self ._convert_rows_to_arrow_table (rows )
174268
175269 def fetchall_arrow (self ) -> Any :
176270 """Fetch all remaining rows as an Arrow table."""
177- raise NotImplementedError ("Not implemented yet" )
271+ if not pyarrow :
272+ raise ImportError ("PyArrow is required for Arrow support" )
273+
274+ rows = self .fetchall ()
275+ if not rows :
276+ # Return empty Arrow table with schema
277+ return self ._create_empty_arrow_table ()
278+
279+ # Convert rows to Arrow table
280+ return self ._convert_rows_to_arrow_table (rows )
178281
179282 def close (self ) -> None :
180283 """Close the result set and release any resources."""
@@ -185,4 +288,4 @@ def close(self) -> None:
185288 CommandId .from_sea_statement_id (self .statement_id )
186289 )
187290 except Exception as e :
188- logger .warning (f"Error closing SEA statement: { e } " )
291+ logger .warning (f"Error closing SEA statement: { e } " )
0 commit comments