@@ -30,7 +30,7 @@ use crate::{
3030 transport:: { CubeStreamReceiver , LoadRequestMeta , TransportService } ,
3131 CubeError ,
3232} ;
33- use chrono:: { TimeZone , Utc } ;
33+ use chrono:: NaiveDateTime ;
3434use datafusion:: {
3535 arrow:: { array:: TimestampNanosecondBuilder , datatypes:: TimeUnit } ,
3636 execution:: context:: TaskContext ,
@@ -726,18 +726,21 @@ pub fn transform_response<V: ValueObject>(
726726 field_name,
727727 {
728728 ( FieldValue :: String ( s) , builder) => {
729- let timestamp = Utc
730- . datetime_from_str( s. as_str( ) , "%Y-%m-%dT%H:%M:%S.%f" )
731- . or_else( |_| Utc
732- . datetime_from_str( s. as_str( ) , "%Y-%m-%d %H:%M:%S.%f" )
729+ let timestamp = NaiveDateTime :: parse_from_str( s. as_str( ) , "%Y-%m-%dT%H:%M:%S.%f" )
730+ . or_else( |_| NaiveDateTime :: parse_from_str( s. as_str( ) , "%Y-%m-%d %H:%M:%S.%f" )
733731 )
734732 . map_err( |e| {
735733 DataFusionError :: Execution ( format!(
736734 "Can't parse timestamp: '{}': {}" ,
737735 s, e
738736 ) )
739737 } ) ?;
740- builder. append_value( timestamp. timestamp_nanos( ) ) ?;
738+ // TODO switch parsing to microseconds
739+ if timestamp. timestamp_millis( ) > ( ( ( 1 as i64 ) << 62 ) / 1_000_000 ) {
740+ builder. append_null( ) ?;
741+ } else {
742+ builder. append_value( timestamp. timestamp_nanos( ) ) ?;
743+ }
741744 } ,
742745 } ,
743746 {
@@ -770,7 +773,7 @@ mod tests {
770773 use cubeclient:: models:: V1LoadResponse ;
771774 use datafusion:: {
772775 arrow:: {
773- array:: { BooleanArray , Float64Array , StringArray } ,
776+ array:: { BooleanArray , Float64Array , StringArray , TimestampNanosecondArray } ,
774777 datatypes:: { Field , Schema } ,
775778 } ,
776779 execution:: {
@@ -817,11 +820,11 @@ mod tests {
817820 "timeDimensions": []
818821 },
819822 "data": [
820- {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": null},
821- {"KibanaSampleDataEcommerce.count": 5, "KibanaSampleDataEcommerce.maxPrice": 5.05, "KibanaSampleDataEcommerce.isBool": true},
822- {"KibanaSampleDataEcommerce.count": "5", "KibanaSampleDataEcommerce.maxPrice": "5.05", "KibanaSampleDataEcommerce.isBool": false},
823- {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": "true"},
824- {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": "false"}
823+ {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": null, "KibanaSampleDataEcommerce.orderDate": null },
824+ {"KibanaSampleDataEcommerce.count": 5, "KibanaSampleDataEcommerce.maxPrice": 5.05, "KibanaSampleDataEcommerce.isBool": true, "KibanaSampleDataEcommerce.orderDate": "2022-01-01 00:00:00.000" },
825+ {"KibanaSampleDataEcommerce.count": "5", "KibanaSampleDataEcommerce.maxPrice": "5.05", "KibanaSampleDataEcommerce.isBool": false, "KibanaSampleDataEcommerce.orderDate": "2023-01-01 00:00:00.000" },
826+ {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": "true", "KibanaSampleDataEcommerce.orderDate": "9999-12-31 00:00:00.000" },
827+ {"KibanaSampleDataEcommerce.count": null, "KibanaSampleDataEcommerce.maxPrice": null, "KibanaSampleDataEcommerce.isBool": "false", "KibanaSampleDataEcommerce.orderDate": null }
825828 ]
826829 }
827830 "# ;
@@ -861,6 +864,11 @@ mod tests {
861864 DataType :: Float64 ,
862865 false ,
863866 ) ,
867+ Field :: new(
868+ "KibanaSampleDataEcommerce.orderDate" ,
869+ DataType :: Timestamp ( TimeUnit :: Nanosecond , None ) ,
870+ false ,
871+ ) ,
864872 Field :: new( "KibanaSampleDataEcommerce.isBool" , DataType :: Boolean , false ) ,
865873 Field :: new(
866874 "KibanaSampleDataEcommerce.is_female" ,
@@ -887,7 +895,10 @@ mod tests {
887895 "KibanaSampleDataEcommerce.count" . to_string( ) ,
888896 "KibanaSampleDataEcommerce.maxPrice" . to_string( ) ,
889897 ] ) ,
890- dimensions : Some ( vec ! [ "KibanaSampleDataEcommerce.isBool" . to_string( ) ] ) ,
898+ dimensions : Some ( vec ! [
899+ "KibanaSampleDataEcommerce.isBool" . to_string( ) ,
900+ "KibanaSampleDataEcommerce.orderDate" . to_string( ) ,
901+ ] ) ,
891902 segments : None ,
892903 time_dimensions : None ,
893904 order : None ,
@@ -947,6 +958,13 @@ mod tests {
947958 None ,
948959 None
949960 ] ) ) as ArrayRef ,
961+ Arc :: new( TimestampNanosecondArray :: from( vec![
962+ None ,
963+ Some ( 1640995200000000000 ) ,
964+ Some ( 1672531200000000000 ) ,
965+ None ,
966+ None
967+ ] ) ) as ArrayRef ,
950968 Arc :: new( BooleanArray :: from( vec![
951969 None ,
952970 Some ( true ) ,
0 commit comments