@@ -617,3 +617,85 @@ def test_binding_identifier(conn_cnx, db_parameters):
617
617
""" ,
618
618
(db_parameters ["name" ],),
619
619
)
620
+
621
+
622
+ def create_or_replace_table (cur , table_name : str , columns ):
623
+ sql = f"CREATE OR REPLACE TEMP TABLE { table_name } ({ ',' .join (columns )} )"
624
+ cur .execute (sql )
625
+
626
+
627
+ def insert_multiple_records (
628
+ cur ,
629
+ table_name : str ,
630
+ ts : str ,
631
+ row_count : int ,
632
+ should_bind : bool ,
633
+ ):
634
+ sql = f"INSERT INTO { table_name } values (?)"
635
+ dates = [[ts ] for _ in range (row_count )]
636
+ cur .executemany (sql , dates )
637
+ is_bind_sql_scoped = "SHOW stages like 'SNOWPARK_TEMP_STAGE_BIND'"
638
+ is_bind_sql_non_scoped = "SHOW stages like 'SYSTEMBIND'"
639
+ res1 = cur .execute (is_bind_sql_scoped ).fetchall ()
640
+ res2 = cur .execute (is_bind_sql_non_scoped ).fetchall ()
641
+ if should_bind :
642
+ assert len (res1 ) != 0 or len (res2 ) != 0
643
+ else :
644
+ assert len (res1 ) == 0 and len (res2 ) == 0
645
+
646
+
647
+ @pytest .mark .skipolddriver
648
+ @pytest .mark .parametrize (
649
+ "timestamp_type, timestamp_precision, timestamp, expected_style" ,
650
+ [
651
+ ("TIMESTAMPTZ" , 6 , "2023-03-15 13:17:29.207 +05:00" , "%Y-%m-%d %H:%M:%S.%f %z" ),
652
+ ("TIMESTAMP" , 6 , "2023-03-15 13:17:29.207" , "%Y-%m-%d %H:%M:%S.%f" ),
653
+ (
654
+ "TIMESTAMPLTZ" ,
655
+ 6 ,
656
+ "2023-03-15 13:17:29.207 +05:00" ,
657
+ "%Y-%m-%d %H:%M:%S.%f %z" ,
658
+ ),
659
+ (
660
+ "TIMESTAMPTZ" ,
661
+ None ,
662
+ "2023-03-15 13:17:29.207 +05:00" ,
663
+ "%Y-%m-%d %H:%M:%S.%f %z" ,
664
+ ),
665
+ ("TIMESTAMP" , None , "2023-03-15 13:17:29.207" , "%Y-%m-%d %H:%M:%S.%f" ),
666
+ (
667
+ "TIMESTAMPLTZ" ,
668
+ None ,
669
+ "2023-03-15 13:17:29.207 +05:00" ,
670
+ "%Y-%m-%d %H:%M:%S.%f %z" ,
671
+ ),
672
+ ("TIMESTAMPNTZ" , 6 , "2023-03-15 13:17:29.207" , "%Y-%m-%d %H:%M:%S.%f" ),
673
+ ("TIMESTAMPNTZ" , None , "2023-03-15 13:17:29.207" , "%Y-%m-%d %H:%M:%S.%f" ),
674
+ ],
675
+ )
676
+ def test_timestamp_bindings (
677
+ conn_cnx , timestamp_type , timestamp_precision , timestamp , expected_style
678
+ ):
679
+ column_name = (
680
+ f"ts { timestamp_type } ({ timestamp_precision } )"
681
+ if timestamp_precision is not None
682
+ else f"ts { timestamp_type } "
683
+ )
684
+ table_name = f"TEST_TIMESTAMP_BINDING_{ random_string (10 )} "
685
+ binding_threshold = 65280
686
+
687
+ with conn_cnx (paramstyle = "qmark" ) as cnx :
688
+ with cnx .cursor () as cur :
689
+ create_or_replace_table (cur , table_name , [column_name ])
690
+ insert_multiple_records (cur , table_name , timestamp , 2 , False )
691
+ insert_multiple_records (
692
+ cur , table_name , timestamp , binding_threshold + 1 , True
693
+ )
694
+ res = cur .execute (f"select ts from { table_name } " ).fetchall ()
695
+ expected = datetime .strptime (timestamp , expected_style )
696
+ assert len (res ) == 65283
697
+ for r in res :
698
+ if timestamp_type == "TIMESTAMP" :
699
+ assert r [0 ].replace (tzinfo = None ) == expected .replace (tzinfo = None )
700
+ else :
701
+ assert r [0 ] == expected
0 commit comments