1010from decimal import Decimal
1111from enum import Enum
1212import re
13+ import pytz
1314
1415import lz4 .frame
1516
@@ -53,6 +54,32 @@ def get_session_config_value(
5354 return None
5455
5556
57+ def parse_timestamp (
58+ value : str , timestamp_format : Optional [str ] = None
59+ ) -> datetime .datetime :
60+ """Parse a timestamp string into a datetime object.
61+
62+ If timestamp_format is provided, tries strptime first and falls back to
63+ dateutil.parser.parse on ValueError. If timestamp_format is None, uses
64+ dateutil.parser.parse directly.
65+
66+ Args:
67+ value: The timestamp string to parse.
68+ timestamp_format: An optional strptime-compatible format string.
69+
70+ Returns:
71+ A datetime.datetime object.
72+ """
73+ if timestamp_format is not None :
74+ try :
75+ return datetime .datetime .strptime (value , timestamp_format ).replace (
76+ tzinfo = pytz .UTC
77+ )
78+ except ValueError :
79+ return parser .parse (value )
80+ return parser .parse (value )
81+
82+
5683class ResultSetQueue (ABC ):
5784 @abstractmethod
5885 def next_n_rows (self , num_rows : int ):
@@ -81,6 +108,7 @@ def build_queue(
81108 http_client ,
82109 lz4_compressed : bool = True ,
83110 description : List [Tuple ] = [],
111+ timestamp_format : Optional [str ] = None ,
84112 ) -> ResultSetQueue :
85113 """
86114 Factory method to build a result set queue for Thrift backend.
@@ -93,6 +121,7 @@ def build_queue(
93121 description (List[List[Any]]): Hive table schema description.
94122 max_download_threads (int): Maximum number of downloader thread pool threads.
95123 ssl_options (SSLOptions): SSLOptions object for CloudFetchQueue
124+ timestamp_format: Optional strptime-compatible format for timestamp parsing.
96125
97126 Returns:
98127 ResultSetQueue
@@ -112,7 +141,7 @@ def build_queue(
112141 )
113142
114143 converted_column_table = convert_to_assigned_datatypes_in_column_table (
115- column_table , description
144+ column_table , description , timestamp_format = timestamp_format
116145 )
117146
118147 return ColumnQueue (ColumnTable (converted_column_table , column_names ))
@@ -760,7 +789,9 @@ def convert_decimals_in_arrow_table(table, description) -> "pyarrow.Table":
760789 return pyarrow .Table .from_arrays (new_columns , schema = new_schema )
761790
762791
763- def convert_to_assigned_datatypes_in_column_table (column_table , description ):
792+ def convert_to_assigned_datatypes_in_column_table (
793+ column_table , description , timestamp_format = None
794+ ):
764795
765796 converted_column_table = []
766797 for i , col in enumerate (column_table ):
@@ -774,7 +805,10 @@ def convert_to_assigned_datatypes_in_column_table(column_table, description):
774805 )
775806 elif description [i ][1 ] == "timestamp" :
776807 converted_column_table .append (
777- tuple ((v if v is None else parser .parse (v )) for v in col )
808+ tuple (
809+ (v if v is None else parse_timestamp (v , timestamp_format ))
810+ for v in col
811+ )
778812 )
779813 else :
780814 converted_column_table .append (col )
0 commit comments