10
10
# See the License for the specific language governing permissions and
11
11
# limitations under the License.
12
12
import math
13
- from datetime import datetime
13
+ from datetime import datetime , time , date , timezone , timedelta
14
+ from decimal import Decimal
14
15
15
16
import pytest
16
17
import pytz
@@ -123,22 +124,267 @@ def test_string_query_param(trino_connection):
123
124
assert rows [0 ][0 ] == "six'"
124
125
125
126
126
- def test_datetime_query_param (trino_connection ):
127
+ def test_python_types_not_used_when_experimental_python_types_is_not_set (trino_connection ):
127
128
cur = trino_connection .cursor ()
128
129
129
- cur .execute ("SELECT ?" , params = (datetime (2020 , 1 , 1 , 0 , 0 , 0 ),))
130
+ cur .execute ("""
131
+ SELECT
132
+ DECIMAL '0.142857',
133
+ DATE '2018-01-01',
134
+ TIMESTAMP '2019-01-01 00:00:00.000+01:00',
135
+ TIMESTAMP '2019-01-01 00:00:00.000 UTC',
136
+ TIMESTAMP '2019-01-01 00:00:00.000',
137
+ TIME '00:00:00.000'
138
+ """ )
139
+ rows = cur .fetchall ()
140
+
141
+ assert rows [0 ][0 ] == '0.142857'
142
+ assert rows [0 ][1 ] == '2018-01-01'
143
+ assert rows [0 ][2 ] == '2019-01-01 00:00:00.000 +01:00'
144
+ assert rows [0 ][3 ] == '2019-01-01 00:00:00.000 UTC'
145
+ assert rows [0 ][4 ] == '2019-01-01 00:00:00.000'
146
+ assert rows [0 ][5 ] == '00:00:00.000'
147
+
148
+
149
+ def test_decimal_query_param (trino_connection ):
150
+ cur = trino_connection .cursor (experimental_python_types = True )
151
+
152
+ cur .execute ("SELECT ?" , params = (Decimal ('0.142857' ),))
153
+ rows = cur .fetchall ()
154
+
155
+ assert rows [0 ][0 ] == Decimal ('0.142857' )
156
+
157
+
158
+ def test_null_decimal (trino_connection ):
159
+ cur = trino_connection .cursor (experimental_python_types = True )
160
+
161
+ cur .execute ("SELECT CAST(NULL AS DECIMAL)" )
162
+ rows = cur .fetchall ()
163
+
164
+ assert rows [0 ][0 ] is None
165
+
166
+
167
+ def test_biggest_decimal (trino_connection ):
168
+ cur = trino_connection .cursor (experimental_python_types = True )
169
+
170
+ params = Decimal ('99999999999999999999999999999999999999' )
171
+ cur .execute ("SELECT ?" , params = (params ,))
130
172
rows = cur .fetchall ()
131
173
132
- assert rows [0 ][0 ] == "2020-01-01 00:00:00.000"
174
+ assert rows [0 ][0 ] == params
133
175
134
- cur .execute ("SELECT ?" ,
135
- params = (datetime (2020 , 1 , 1 , 0 , 0 , 0 , tzinfo = pytz .utc ),))
176
+
177
+ def test_smallest_decimal (trino_connection ):
178
+ cur = trino_connection .cursor (experimental_python_types = True )
179
+
180
+ params = Decimal ('-99999999999999999999999999999999999999' )
181
+ cur .execute ("SELECT ?" , params = (params ,))
136
182
rows = cur .fetchall ()
137
183
138
- assert rows [0 ][0 ] == "2020-01-01 00:00:00.000 UTC"
184
+ assert rows [0 ][0 ] == params
185
+
186
+
187
+ def test_highest_precision_decimal (trino_connection ):
188
+ cur = trino_connection .cursor (experimental_python_types = True )
189
+
190
+ params = Decimal ('0.99999999999999999999999999999999999999' )
191
+ cur .execute ("SELECT ?" , params = (params ,))
192
+ rows = cur .fetchall ()
193
+
194
+ assert rows [0 ][0 ] == params
195
+
196
+
197
+ def test_datetime_query_param (trino_connection ):
198
+ cur = trino_connection .cursor (experimental_python_types = True )
199
+
200
+ params = datetime (2020 , 1 , 1 , 16 , 43 , 22 , 320000 )
201
+
202
+ cur .execute ("SELECT ?" , params = (params ,))
203
+ rows = cur .fetchall ()
204
+
205
+ assert rows [0 ][0 ] == params
206
+ assert cur .description [0 ][1 ] == "timestamp"
207
+
208
+
209
+ def test_datetime_with_trailing_zeros (trino_connection ):
210
+ cur = trino_connection .cursor (experimental_python_types = True )
211
+
212
+ cur .execute ("SELECT TIMESTAMP '2001-08-22 03:04:05.321000'" )
213
+ rows = cur .fetchall ()
214
+
215
+ assert rows [0 ][0 ] == datetime .strptime ("2001-08-22 03:04:05.321000" , "%Y-%m-%d %H:%M:%S.%f" )
216
+
217
+
218
+ def test_datetime_with_utc_time_zone_query_param (trino_connection ):
219
+ cur = trino_connection .cursor (experimental_python_types = True )
220
+
221
+ params = datetime (2020 , 1 , 1 , 16 , 43 , 22 , 320000 , tzinfo = pytz .timezone ('UTC' ))
222
+
223
+ cur .execute ("SELECT ?" , params = (params ,))
224
+ rows = cur .fetchall ()
225
+
226
+ assert rows [0 ][0 ] == params
139
227
assert cur .description [0 ][1 ] == "timestamp with time zone"
140
228
141
229
230
+ def test_datetime_with_numeric_offset_time_zone_query_param (trino_connection ):
231
+ cur = trino_connection .cursor (experimental_python_types = True )
232
+
233
+ tz = timezone (- timedelta (hours = 5 , minutes = 30 ))
234
+
235
+ params = datetime (2020 , 1 , 1 , 16 , 43 , 22 , 320000 , tzinfo = tz )
236
+
237
+ cur .execute ("SELECT ?" , params = (params ,))
238
+ rows = cur .fetchall ()
239
+
240
+ assert rows [0 ][0 ] == params
241
+ assert cur .description [0 ][1 ] == "timestamp with time zone"
242
+
243
+
244
+ def test_datetime_with_named_time_zone_query_param (trino_connection ):
245
+ cur = trino_connection .cursor (experimental_python_types = True )
246
+
247
+ params = datetime (2020 , 1 , 1 , 16 , 43 , 22 , 320000 , tzinfo = pytz .timezone ('America/Los_Angeles' ))
248
+
249
+ cur .execute ("SELECT ?" , params = (params ,))
250
+ rows = cur .fetchall ()
251
+
252
+ assert rows [0 ][0 ] == params
253
+ assert cur .description [0 ][1 ] == "timestamp with time zone"
254
+
255
+
256
+ def test_null_datetime_with_time_zone (trino_connection ):
257
+ cur = trino_connection .cursor (experimental_python_types = True )
258
+
259
+ cur .execute ("SELECT CAST(NULL AS TIMESTAMP WITH TIME ZONE)" )
260
+ rows = cur .fetchall ()
261
+
262
+ assert rows [0 ][0 ] is None
263
+
264
+
265
+ def test_datetime_with_time_zone_numeric_offset (trino_connection ):
266
+ cur = trino_connection .cursor (experimental_python_types = True )
267
+
268
+ cur .execute ("SELECT TIMESTAMP '2001-08-22 03:04:05.321 -08:00'" )
269
+ rows = cur .fetchall ()
270
+
271
+ assert rows [0 ][0 ] == datetime .strptime ("2001-08-22 03:04:05.321 -08:00" , "%Y-%m-%d %H:%M:%S.%f %z" )
272
+
273
+
274
+ def test_unexisting_datetimes_with_time_zone_query_param (trino_connection ):
275
+ cur = trino_connection .cursor (experimental_python_types = True )
276
+
277
+ params = datetime (2021 , 3 , 28 , 2 , 30 , 0 , tzinfo = pytz .timezone ('Europe/Brussels' ))
278
+ with pytest .raises (trino .exceptions .TrinoUserError ):
279
+ cur .execute ("SELECT ?" , params = (params ,))
280
+ cur .fetchall ()
281
+
282
+
283
+ def test_doubled_datetimes_first_query_param (trino_connection ):
284
+ cur = trino_connection .cursor (experimental_python_types = True )
285
+
286
+ params = pytz .timezone ('US/Eastern' ).localize (datetime (2002 , 10 , 27 , 1 , 30 , 0 ), is_dst = True )
287
+
288
+ cur .execute ("SELECT ?" , params = (params ,))
289
+ rows = cur .fetchall ()
290
+
291
+ assert rows [0 ][0 ] == datetime (2002 , 10 , 27 , 1 , 30 , 0 , tzinfo = pytz .timezone ('US/Eastern' ))
292
+
293
+
294
+ def test_doubled_datetimes_second_query_param (trino_connection ):
295
+ cur = trino_connection .cursor (experimental_python_types = True )
296
+
297
+ params = pytz .timezone ('US/Eastern' ).localize (datetime (2002 , 10 , 27 , 1 , 30 , 0 ), is_dst = False )
298
+
299
+ cur .execute ("SELECT ?" , params = (params ,))
300
+ rows = cur .fetchall ()
301
+
302
+ assert rows [0 ][0 ] == datetime (2002 , 10 , 27 , 1 , 30 , 0 , tzinfo = pytz .timezone ('US/Eastern' ))
303
+
304
+
305
+ def test_date_query_param (trino_connection ):
306
+ cur = trino_connection .cursor (experimental_python_types = True )
307
+
308
+ params = datetime (2020 , 1 , 1 , 0 , 0 , 0 ).date ()
309
+
310
+ cur .execute ("SELECT ?" , params = (params ,))
311
+ rows = cur .fetchall ()
312
+
313
+ assert rows [0 ][0 ] == params
314
+
315
+
316
+ def test_null_date (trino_connection ):
317
+ cur = trino_connection .cursor (experimental_python_types = True )
318
+
319
+ cur .execute ("SELECT CAST(NULL AS DATE)" )
320
+ rows = cur .fetchall ()
321
+
322
+ assert rows [0 ][0 ] is None
323
+
324
+
325
+ def test_unsupported_python_dates (trino_connection ):
326
+ cur = trino_connection .cursor (experimental_python_types = True )
327
+
328
+ # dates not supported in Python date type
329
+ for unsupported_date in [
330
+ '-0001-01-01' ,
331
+ '0000-01-01'
332
+ ]:
333
+ with pytest .raises (trino .exceptions .TrinoDataError ):
334
+ cur .execute (f"SELECT DATE '{ unsupported_date } '" )
335
+ cur .fetchall ()
336
+
337
+
338
+ def test_supported_special_dates_query_param (trino_connection ):
339
+ cur = trino_connection .cursor (experimental_python_types = True )
340
+
341
+ for params in (
342
+ # first day of AD
343
+ date (1 , 1 , 1 ),
344
+ date (12 , 12 , 12 ),
345
+ # before julian->gregorian switch
346
+ date (1500 , 1 , 1 ),
347
+ # During julian->gregorian switch
348
+ date (1752 , 9 , 4 ),
349
+ # before epoch
350
+ date (1952 , 4 , 3 ),
351
+ date (1970 , 1 , 1 ),
352
+ date (1970 , 2 , 3 ),
353
+ # summer on northern hemisphere (possible DST)
354
+ date (2017 , 7 , 1 ),
355
+ # winter on northern hemisphere (possible DST on southern hemisphere)
356
+ date (2017 , 1 , 1 ),
357
+ # winter on southern hemisphere (possible DST on northern hemisphere)
358
+ date (2017 , 12 , 31 ),
359
+ date (1983 , 4 , 1 ),
360
+ date (1983 , 10 , 1 ),
361
+ ):
362
+ cur .execute ("SELECT ?" , params = (params ,))
363
+ rows = cur .fetchall ()
364
+
365
+ assert rows [0 ][0 ] == params
366
+
367
+
368
+ def test_time_query_param (trino_connection ):
369
+ cur = trino_connection .cursor (experimental_python_types = True )
370
+
371
+ params = time (12 , 3 , 44 , 333000 )
372
+
373
+ cur .execute ("SELECT ?" , params = (params ,))
374
+ rows = cur .fetchall ()
375
+
376
+ assert rows [0 ][0 ] == params
377
+
378
+
379
+ def test_time_with_time_zone_query_param (trino_connection ):
380
+ with pytest .raises (trino .exceptions .NotSupportedError ):
381
+ cur = trino_connection .cursor ()
382
+
383
+ params = time (16 , 43 , 22 , 320000 , tzinfo = pytz .timezone ('Asia/Shanghai' ))
384
+
385
+ cur .execute ("SELECT ?" , params = (params ,))
386
+
387
+
142
388
def test_array_query_param (trino_connection ):
143
389
cur = trino_connection .cursor ()
144
390
@@ -158,6 +404,38 @@ def test_array_query_param(trino_connection):
158
404
assert rows [0 ][0 ] == "array(integer)"
159
405
160
406
407
+ def test_array_timestamp_query_param (trino_connection ):
408
+ cur = trino_connection .cursor (experimental_python_types = True )
409
+
410
+ params = [datetime (2020 , 1 , 1 , 0 , 0 , 0 ), datetime (2020 , 1 , 2 , 0 , 0 , 0 )]
411
+
412
+ cur .execute ("SELECT ?" , params = (params ,))
413
+ rows = cur .fetchall ()
414
+
415
+ assert rows [0 ][0 ] == params
416
+
417
+ cur .execute ("SELECT TYPEOF(?)" , params = (params ,))
418
+ rows = cur .fetchall ()
419
+
420
+ assert rows [0 ][0 ] == "array(timestamp(6))"
421
+
422
+
423
+ def test_array_timestamp_with_timezone_query_param (trino_connection ):
424
+ cur = trino_connection .cursor (experimental_python_types = True )
425
+
426
+ params = [datetime (2020 , 1 , 1 , 0 , 0 , 0 , tzinfo = pytz .utc ), datetime (2020 , 1 , 2 , 0 , 0 , 0 , tzinfo = pytz .utc )]
427
+
428
+ cur .execute ("SELECT ?" , params = (params ,))
429
+ rows = cur .fetchall ()
430
+
431
+ assert rows [0 ][0 ] == params
432
+
433
+ cur .execute ("SELECT TYPEOF(?)" , params = (params ,))
434
+ rows = cur .fetchall ()
435
+
436
+ assert rows [0 ][0 ] == "array(timestamp(6) with time zone)"
437
+
438
+
161
439
def test_dict_query_param (trino_connection ):
162
440
cur = trino_connection .cursor ()
163
441
0 commit comments