1
+ import time
1
2
from typing import Dict , Tuple , List , Optional , Any , Union , Sequence
2
3
3
4
import pandas
@@ -430,6 +431,8 @@ def __init__(
430
431
self .escaper = ParamEscaper ()
431
432
self .lastrowid = None
432
433
434
+ self .ASYNC_DEFAULT_POLLING_INTERVAL = 2
435
+
433
436
# The ideal return type for this method is perhaps Self, but that was not added until 3.11, and we support pre-3.11 pythons, currently.
434
437
def __enter__ (self ) -> "Cursor" :
435
438
return self
@@ -733,7 +736,6 @@ def execute(
733
736
self ,
734
737
operation : str ,
735
738
parameters : Optional [TParameterCollection ] = None ,
736
- async_op = False ,
737
739
) -> "Cursor" :
738
740
"""
739
741
Execute a query and wait for execution to complete.
@@ -802,15 +804,14 @@ def execute(
802
804
cursor = self ,
803
805
use_cloud_fetch = self .connection .use_cloud_fetch ,
804
806
parameters = prepared_params ,
805
- async_op = async_op ,
807
+ async_op = False ,
806
808
)
807
809
self .active_result_set = ResultSet (
808
810
self .connection ,
809
811
execute_response ,
810
812
self .thrift_backend ,
811
813
self .buffer_size_bytes ,
812
814
self .arraysize ,
813
- async_op ,
814
815
)
815
816
816
817
if execute_response .is_staging_operation :
@@ -829,12 +830,43 @@ def execute_async(
829
830
830
831
Execute a query and do not wait for it to complete and just move ahead
831
832
832
- Internally it calls execute function with async_op=True
833
833
:param operation:
834
834
:param parameters:
835
835
:return:
836
836
"""
837
- self .execute (operation , parameters , True )
837
+ param_approach = self ._determine_parameter_approach (parameters )
838
+ if param_approach == ParameterApproach .NONE :
839
+ prepared_params = NO_NATIVE_PARAMS
840
+ prepared_operation = operation
841
+
842
+ elif param_approach == ParameterApproach .INLINE :
843
+ prepared_operation , prepared_params = self ._prepare_inline_parameters (
844
+ operation , parameters
845
+ )
846
+ elif param_approach == ParameterApproach .NATIVE :
847
+ normalized_parameters = self ._normalize_tparametercollection (parameters )
848
+ param_structure = self ._determine_parameter_structure (normalized_parameters )
849
+ transformed_operation = transform_paramstyle (
850
+ operation , normalized_parameters , param_structure
851
+ )
852
+ prepared_operation , prepared_params = self ._prepare_native_parameters (
853
+ transformed_operation , normalized_parameters , param_structure
854
+ )
855
+
856
+ self ._check_not_closed ()
857
+ self ._close_and_clear_active_result_set ()
858
+ self .thrift_backend .execute_command (
859
+ operation = prepared_operation ,
860
+ session_handle = self .connection ._session_handle ,
861
+ max_rows = self .arraysize ,
862
+ max_bytes = self .buffer_size_bytes ,
863
+ lz4_compression = self .connection .lz4_compression ,
864
+ cursor = self ,
865
+ use_cloud_fetch = self .connection .use_cloud_fetch ,
866
+ parameters = prepared_params ,
867
+ async_op = True ,
868
+ )
869
+
838
870
return self
839
871
840
872
def get_query_state (self ) -> "TOperationState" :
@@ -846,15 +878,25 @@ def get_query_state(self) -> "TOperationState":
846
878
self ._check_not_closed ()
847
879
return self .thrift_backend .get_query_state (self .active_op_handle )
848
880
849
- def get_execution_result (self ):
881
+ def get_async_execution_result (self ):
850
882
"""
851
883
852
884
Checks for the status of the async executing query and fetches the result if the query is finished
853
- If executed sets the active_result_set to the obtained result
885
+ Otherwise it will keep polling the status of the query till there is a Not pending state
854
886
:return:
855
887
"""
856
888
self ._check_not_closed ()
857
889
890
+ def is_executing (operation_state ) -> "bool" :
891
+ return not operation_state or operation_state in [
892
+ ttypes .TOperationState .RUNNING_STATE ,
893
+ ttypes .TOperationState .PENDING_STATE ,
894
+ ]
895
+
896
+ while (is_executing (self .get_query_state ())):
897
+ # Poll after some default time
898
+ time .sleep (self .ASYNC_DEFAULT_POLLING_INTERVAL )
899
+
858
900
operation_state = self .get_query_state ()
859
901
if operation_state == ttypes .TOperationState .FINISHED_STATE :
860
902
execute_response = self .thrift_backend .get_execution_result (
@@ -1164,7 +1206,6 @@ def __init__(
1164
1206
thrift_backend : ThriftBackend ,
1165
1207
result_buffer_size_bytes : int = DEFAULT_RESULT_BUFFER_SIZE_BYTES ,
1166
1208
arraysize : int = 10000 ,
1167
- async_op = False ,
1168
1209
):
1169
1210
"""
1170
1211
A ResultSet manages the results of a single command.
@@ -1187,7 +1228,7 @@ def __init__(
1187
1228
self ._arrow_schema_bytes = execute_response .arrow_schema_bytes
1188
1229
self ._next_row_index = 0
1189
1230
1190
- if execute_response .arrow_queue or async_op :
1231
+ if execute_response .arrow_queue :
1191
1232
# In this case the server has taken the fast path and returned an initial batch of
1192
1233
# results
1193
1234
self .results = execute_response .arrow_queue
0 commit comments