From 5805e8d4b60068db96bfb8c531dbee6ba7e276d5 Mon Sep 17 00:00:00 2001 From: Wei <47681251+QuenKar@users.noreply.github.com> Date: Mon, 18 Sep 2023 22:25:38 +0800 Subject: [PATCH] feat: type conversion between Values (#2394) * feat: add cast() in datatype trait. * feat: add cast for primitive type * feat: add unit test cases * test: add datetime/time cases. * refactor: time_type cast function. * chore: typos. * refactor code. * feat: add can_cast_type func. * chore: rename cast to try_cast * feat: impl cast_with_opt * chore: pub use cast_with_opt * chore: add timezone for test * Update src/common/time/src/date.rs Co-authored-by: dennis zhuang * chore: duration type --------- Co-authored-by: dennis zhuang --- src/common/time/src/date.rs | 14 + src/common/time/src/datetime.rs | 8 +- src/common/time/src/time.rs | 13 + src/common/time/src/timestamp.rs | 18 +- src/datatypes/src/data_type.rs | 24 ++ src/datatypes/src/types.rs | 2 + src/datatypes/src/types/binary_type.rs | 8 + src/datatypes/src/types/boolean_type.rs | 134 ++++++++ src/datatypes/src/types/cast.rs | 298 +++++++++++++++++ src/datatypes/src/types/date_type.rs | 47 +++ src/datatypes/src/types/datetime_type.rs | 44 +++ src/datatypes/src/types/dictionary_type.rs | 4 + src/datatypes/src/types/duration_type.rs | 5 + src/datatypes/src/types/interval_type.rs | 5 + src/datatypes/src/types/list_type.rs | 7 + src/datatypes/src/types/null_type.rs | 5 + src/datatypes/src/types/primitive_type.rs | 357 ++++++++++++++++++++- src/datatypes/src/types/string_type.rs | 32 ++ src/datatypes/src/types/time_type.rs | 74 ++++- src/datatypes/src/types/timestamp_type.rs | 61 ++++ 20 files changed, 1143 insertions(+), 17 deletions(-) create mode 100644 src/datatypes/src/types/cast.rs diff --git a/src/common/time/src/date.rs b/src/common/time/src/date.rs index e9b1d76246..b94c483e30 100644 --- a/src/common/time/src/date.rs +++ b/src/common/time/src/date.rs @@ -82,6 +82,10 @@ impl Date { pub fn to_chrono_date(&self) -> Option { NaiveDate::from_num_days_from_ce_opt(UNIX_EPOCH_FROM_CE + self.0) } + + pub fn to_secs(&self) -> i64 { + (self.0 as i64) * 24 * 3600 + } } #[cfg(test)] @@ -132,4 +136,14 @@ mod tests { let d: Date = 42.into(); assert_eq!(42, d.val()); } + + #[test] + fn test_to_secs() { + let d = Date::from_str("1970-01-01").unwrap(); + assert_eq!(d.to_secs(), 0); + let d = Date::from_str("1970-01-02").unwrap(); + assert_eq!(d.to_secs(), 24 * 3600); + let d = Date::from_str("1970-01-03").unwrap(); + assert_eq!(d.to_secs(), 2 * 24 * 3600); + } } diff --git a/src/common/time/src/datetime.rs b/src/common/time/src/datetime.rs index 426d3f1069..05d4884e95 100644 --- a/src/common/time/src/datetime.rs +++ b/src/common/time/src/datetime.rs @@ -50,6 +50,12 @@ impl From for serde_json::Value { } } +impl From for DateTime { + fn from(value: NaiveDateTime) -> Self { + DateTime::from(value.timestamp()) + } +} + impl FromStr for DateTime { type Err = Error; @@ -88,7 +94,7 @@ impl DateTime { } pub fn to_chrono_datetime(&self) -> Option { - NaiveDateTime::from_timestamp_millis(self.0) + NaiveDateTime::from_timestamp_opt(self.0, 0) } } diff --git a/src/common/time/src/time.rs b/src/common/time/src/time.rs index 7400e22c0f..8c3aeba866 100644 --- a/src/common/time/src/time.rs +++ b/src/common/time/src/time.rs @@ -77,6 +77,19 @@ impl Time { self.value } + /// Convert a time to given time unit. + /// Return `None` if conversion causes overflow. + pub fn convert_to(&self, unit: TimeUnit) -> Option