Skip to content

Commit e393b06

Browse files
committed
fix(cubesql): Ignore timestamps which can't be represented as nanoseconds instead of failing
1 parent ada0afd commit e393b06

File tree

1 file changed

+31
-13
lines changed
  • rust/cubesql/cubesql/src/compile/engine/df

1 file changed

+31
-13
lines changed

rust/cubesql/cubesql/src/compile/engine/df/scan.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
transport::{CubeStreamReceiver, LoadRequestMeta, TransportService},
3131
CubeError,
3232
};
33-
use chrono::{TimeZone, Utc};
33+
use chrono::NaiveDateTime;
3434
use 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

Comments
 (0)