3
3
import com .clickhouse .client .BaseIntegrationTest ;
4
4
import com .clickhouse .client .ClickHouseNode ;
5
5
import com .clickhouse .client .ClickHouseProtocol ;
6
+ import com .clickhouse .client .ClickHouseResponse ;
6
7
import com .clickhouse .client .ClickHouseServerForTest ;
7
8
import com .clickhouse .client .api .Client ;
9
+ import com .clickhouse .client .api .DataTypeUtils ;
8
10
import com .clickhouse .client .api .command .CommandSettings ;
9
11
import com .clickhouse .client .api .enums .Protocol ;
10
12
import com .clickhouse .client .api .insert .InsertSettings ;
11
13
import com .clickhouse .client .api .metadata .TableSchema ;
12
14
import com .clickhouse .client .api .query .GenericRecord ;
15
+ import com .clickhouse .client .api .query .QueryResponse ;
13
16
import com .clickhouse .data .ClickHouseDataType ;
14
17
import com .clickhouse .data .ClickHouseVersion ;
15
18
import lombok .AllArgsConstructor ;
24
27
import java .io .IOException ;
25
28
import java .lang .reflect .Method ;
26
29
import java .math .BigDecimal ;
30
+ import java .math .BigInteger ;
31
+ import java .sql .Time ;
27
32
import java .time .Duration ;
33
+ import java .time .Instant ;
28
34
import java .time .LocalDateTime ;
29
35
import java .time .Period ;
30
36
import java .time .temporal .ChronoUnit ;
38
44
import java .util .List ;
39
45
import java .util .Map ;
40
46
import java .util .Set ;
47
+ import java .util .concurrent .TimeUnit ;
41
48
import java .util .concurrent .atomic .AtomicInteger ;
42
49
import java .util .function .BiConsumer ;
43
50
@@ -189,6 +196,8 @@ public void testVariantWithSimpleDataTypes() throws Exception {
189
196
case LowCardinality : // virtual type
190
197
case LineString : // same as Ring
191
198
case MultiLineString : // same as MultiPolygon
199
+ case Time :
200
+ case Time64 :
192
201
// tested separately
193
202
continue dataTypesLoop ;
194
203
@@ -405,6 +414,29 @@ public void testVariantWithTuple() throws Exception {
405
414
});
406
415
}
407
416
417
+ @ Test (groups = {"integration" })
418
+ public void testVariantWithTimeTypes () throws Exception {
419
+ testVariantWith ("Time" , new String []{"field Variant(Time, String)" },
420
+ new Object []{
421
+ "30:33:30" ,
422
+ TimeUnit .HOURS .toSeconds (100 ) + TimeUnit .MINUTES .toSeconds (10 ) + 30
423
+ },
424
+ new String []{
425
+ "30:33:30" ,
426
+ "360630" , // Time stored as integer by default
427
+ });
428
+
429
+ testVariantWith ("Time64" , new String []{"field Variant(Time64, String)" },
430
+ new Object []{
431
+ "30:33:30" ,
432
+ TimeUnit .HOURS .toSeconds (100 ) + TimeUnit .MINUTES .toSeconds (10 ) + 30
433
+ },
434
+ new String []{
435
+ "30:33:30" ,
436
+ "360630" ,
437
+ });
438
+ }
439
+
408
440
@ Test (groups = {"integration" })
409
441
public void testDynamicWithPrimitives () throws Exception {
410
442
if (isVersionMatch ("(,24.8]" )) {
@@ -446,6 +478,8 @@ public void testDynamicWithPrimitives() throws Exception {
446
478
case Enum : // virtual type
447
479
case LineString : // same as Ring
448
480
case MultiLineString : // same as MultiPolygon
481
+ case Time :
482
+ case Time64 :
449
483
// no tests or tested in other tests
450
484
continue ;
451
485
default :
@@ -599,6 +633,29 @@ public void testDynamicWithMaps() throws Exception {
599
633
});
600
634
}
601
635
636
+ @ Test (groups = {"integration" })
637
+ public void testDynamicWithTimeTypes () throws Exception {
638
+ long _999_hours = TimeUnit .HOURS .toSeconds (999 );
639
+ testDynamicWith ("Time" ,
640
+ new Object []{
641
+ _999_hours
642
+ },
643
+ new String []{
644
+ String .valueOf (_999_hours ),
645
+ });
646
+
647
+ Instant maxTime64 = Instant .ofEpochSecond (TimeUnit .HOURS .toSeconds (999 ) + TimeUnit .MINUTES .toSeconds (59 ) + 59 ,
648
+ 999999999 );
649
+
650
+ testDynamicWith ("Time64" ,
651
+ new Object []{
652
+ maxTime64 ,
653
+ },
654
+ new String []{
655
+ "3958241016481971977"
656
+ });
657
+ }
658
+
602
659
@ Data
603
660
@ AllArgsConstructor
604
661
public static class DTOForDynamicPrimitivesTests {
@@ -629,6 +686,39 @@ public void testAllDataTypesKnown() {
629
686
Assert .assertTrue (unknowTypes .isEmpty (), "There are some unknown types: " + unknowTypes );
630
687
}
631
688
689
+ @ Test (groups = {"integration" })
690
+ public void testTimeType () throws Exception {
691
+ if (isVersionMatch ("(,25.4]" )) {
692
+ return ;
693
+ }
694
+
695
+ String table = "test_time_type" ;
696
+ client .execute ("DROP TABLE IF EXISTS " + table ).get ();
697
+ client .execute (tableDefinition (table , "o_num UInt32" , "time Time" ), (CommandSettings ) new CommandSettings ().serverSetting ("enable_time_time64_type" , "1" )).get ();
698
+
699
+ String insertSQL = "INSERT INTO " + table + " VALUES (1, '999:00:00'), (2, '999:59:00'), (3, '000:00:00')" ;
700
+ try (QueryResponse response = client .query (insertSQL ).get ()) {}
701
+
702
+
703
+ List <GenericRecord > records = client .queryAll ("SELECT * FROM " + table );
704
+
705
+ GenericRecord record = records .get (0 );
706
+ Assert .assertEquals (record .getInteger ("o_num" ), 1 );
707
+ Assert .assertEquals (record .getInteger ("time" ), TimeUnit .HOURS .toSeconds (999 ));
708
+ Assert .assertEquals (record .getInstant ("time" ), Instant .ofEpochSecond (TimeUnit .HOURS .toSeconds (999 )));
709
+
710
+ record = records .get (1 );
711
+ Assert .assertEquals (record .getInteger ("o_num" ), 2 );
712
+ Assert .assertEquals (record .getInteger ("time" ), TimeUnit .HOURS .toSeconds (999 ) + TimeUnit .MINUTES .toSeconds (59 ));
713
+ Assert .assertEquals (record .getInstant ("time" ), Instant .ofEpochSecond (TimeUnit .HOURS .toSeconds (999 ) + TimeUnit .MINUTES .toSeconds (59 )));
714
+
715
+ record = records .get (2 );
716
+ Assert .assertEquals (record .getInteger ("o_num" ), 3 );
717
+ Assert .assertEquals (record .getInteger ("time" ), 0 );
718
+ Assert .assertEquals (record .getInstant ("time" ), Instant .ofEpochSecond (0 ));
719
+ }
720
+
721
+
632
722
private void testDynamicWith (String withWhat , Object [] values , String [] expectedStrValues ) throws Exception {
633
723
if (isVersionMatch ("(,24.8]" )) {
634
724
return ;
@@ -637,7 +727,8 @@ private void testDynamicWith(String withWhat, Object[] values, String[] expected
637
727
String table = "test_dynamic_with_" + withWhat ;
638
728
client .execute ("DROP TABLE IF EXISTS " + table ).get ();
639
729
client .execute (tableDefinition (table , "rowId Int32" , "field Dynamic" ),
640
- (CommandSettings ) new CommandSettings ().serverSetting ("allow_experimental_dynamic_type" , "1" )).get ();
730
+ (CommandSettings ) new CommandSettings ().serverSetting ("allow_experimental_dynamic_type" , "1" )
731
+ .serverSetting ("enable_time_time64_type" , "1" )).get ();
641
732
642
733
client .register (DTOForDynamicPrimitivesTests .class , client .getTableSchema (table ));
643
734
@@ -664,7 +755,9 @@ private void testVariantWith(String withWhat, String[] fields, Object[] values,
664
755
System .arraycopy (fields , 0 , actualFields , 1 , fields .length );
665
756
client .execute ("DROP TABLE IF EXISTS " + table ).get ();
666
757
client .execute (tableDefinition (table , actualFields ),
667
- (CommandSettings ) new CommandSettings ().serverSetting ("allow_experimental_variant_type" , "1" )).get ();
758
+ (CommandSettings ) new CommandSettings ()
759
+ .serverSetting ("allow_experimental_variant_type" , "1" )
760
+ .serverSetting ("enable_time_time64_type" , "1" )).get ();
668
761
669
762
client .register (DTOForVariantPrimitivesTests .class , client .getTableSchema (table ));
670
763
0 commit comments