From 021b103cbd3529d1b1acecdc79f7311277c2f0ee Mon Sep 17 00:00:00 2001
From: Colin Ho <colin.ho99@gmail.com>
Date: Fri, 7 Jun 2024 12:03:40 -0700
Subject: [PATCH] [CHORE] Bump chrono to 0.4.38  (#2352)

This PR updates the chrono version to 0.4.38 and fixes deprecation
warnings
---
 Cargo.toml                           |  2 +-
 src/daft-core/src/array/ops/time.rs  | 65 +++++++++++++++++++---------
 src/daft-decoding/src/deserialize.rs | 16 +++----
 src/daft-json/src/decoding.rs        | 15 +++----
 src/daft-json/src/read.rs            |  3 +-
 5 files changed, 57 insertions(+), 44 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index fd017e64b5..a1e19e0ccb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -109,7 +109,7 @@ async-compression = {version = "0.4.10", features = [
 ]}
 async-stream = "0.3.5"
 bytes = "1.6.0"
-chrono = "0.4.26"
+chrono = "0.4.38"
 chrono-tz = "0.8.4"
 comfy-table = "7.1.1"
 futures = "0.3.30"
diff --git a/src/daft-core/src/array/ops/time.rs b/src/daft-core/src/array/ops/time.rs
index b83a26aa1d..331fb49717 100644
--- a/src/daft-core/src/array/ops/time.rs
+++ b/src/daft-core/src/array/ops/time.rs
@@ -54,24 +54,6 @@ fn process_interval(interval: &str, timeunit: TimeUnit) -> DaftResult<i64> {
     }
 }
 
-macro_rules! datetime_to_timestamp {
-    ($dt:expr, $tu:expr) => {{
-        // chrono changed their function signature AGAIN
-        #[allow(deprecated)]
-        match $tu {
-            TimeUnit::Seconds => Ok($dt.timestamp()),
-            TimeUnit::Milliseconds => Ok($dt.timestamp_millis()),
-            TimeUnit::Microseconds => Ok($dt.timestamp_micros()),
-            TimeUnit::Nanoseconds => {
-                $dt.timestamp_nanos_opt()
-                    .ok_or(DaftError::ValueError(format!(
-                        "Error converting datetime to nanoseconds timestamp: {{dt}}"
-                    )))
-            }
-        }
-    }};
-}
-
 impl DateArray {
     pub fn day(&self) -> DaftResult<UInt32Array> {
         let input_array = self
@@ -263,14 +245,44 @@ impl TimestampArray {
                     let tu_arrow = tu.to_arrow();
                     let original_dt =
                         arrow2::temporal_conversions::timestamp_to_datetime(ts, tu_arrow, &tz);
-                    let naive_ts = datetime_to_timestamp!(original_dt.naive_local(), tu)?;
+                    let naive_ts = match tu {
+                        TimeUnit::Seconds => original_dt.naive_local().and_utc().timestamp(),
+                        TimeUnit::Milliseconds => {
+                            original_dt.naive_local().and_utc().timestamp_millis()
+                        }
+                        TimeUnit::Microseconds => {
+                            original_dt.naive_local().and_utc().timestamp_micros()
+                        }
+                        TimeUnit::Nanoseconds => original_dt
+                            .naive_local()
+                            .and_utc()
+                            .timestamp_nanos_opt()
+                            .ok_or(DaftError::ValueError(format!(
+                                "Error truncating timestamp {ts} in nanosecond units"
+                            )))?,
+                    };
 
                     let mut truncate_by_amount = match relative_to {
                         Some(rt) => {
                             let rt_dt = arrow2::temporal_conversions::timestamp_to_datetime(
                                 *rt, tu_arrow, &tz,
                             );
-                            let naive_rt_ts = datetime_to_timestamp!(rt_dt.naive_local(), tu)?;
+                            let naive_rt_ts = match tu {
+                                TimeUnit::Seconds => rt_dt.naive_local().and_utc().timestamp(),
+                                TimeUnit::Milliseconds => {
+                                    rt_dt.naive_local().and_utc().timestamp_millis()
+                                }
+                                TimeUnit::Microseconds => {
+                                    rt_dt.naive_local().and_utc().timestamp_micros()
+                                }
+                                TimeUnit::Nanoseconds => {
+                                    rt_dt.naive_local().and_utc().timestamp_nanos_opt().ok_or(
+                                        DaftError::ValueError(format!(
+                                            "Error truncating timestamp {ts} in nanosecond units"
+                                        )),
+                                    )?
+                                }
+                            };
                             (naive_ts - naive_rt_ts) % duration
                         }
                         None => naive_ts % duration,
@@ -286,7 +298,18 @@ impl TimestampArray {
                     };
 
                     let truncated_dt = original_dt - truncate_by_duration;
-                    datetime_to_timestamp!(truncated_dt, tu)
+                    match tu {
+                        TimeUnit::Seconds => Ok(truncated_dt.timestamp()),
+                        TimeUnit::Milliseconds => Ok(truncated_dt.timestamp_millis()),
+                        TimeUnit::Microseconds => Ok(truncated_dt.timestamp_micros()),
+                        TimeUnit::Nanoseconds => {
+                            truncated_dt
+                                .timestamp_nanos_opt()
+                                .ok_or(DaftError::ValueError(format!(
+                                    "Error truncating timestamp {ts} in nanosecond units"
+                                )))
+                        }
+                    }
                 }
                 None => {
                     let mut truncate_by_amount = match relative_to {
diff --git a/src/daft-decoding/src/deserialize.rs b/src/daft-decoding/src/deserialize.rs
index 43b6cc1f0b..dd3c56292e 100644
--- a/src/daft-decoding/src/deserialize.rs
+++ b/src/daft-decoding/src/deserialize.rs
@@ -284,13 +284,11 @@ pub fn deserialize_column<B: ByteRecordGeneric>(
                 .and_then(|x| deserialize_naive_date(x, &mut last_fmt_idx))
                 .map(|x| x.num_days_from_ce() - temporal_conversions::EPOCH_DAYS_FROM_CE)
         }),
-        // chrono changed their function signature AGAIN
-        #[allow(deprecated)]
         Date64 => deserialize_primitive(rows, column, datatype, |bytes| {
             let mut last_fmt_idx = 0;
             to_utf8(bytes)
                 .and_then(|x| deserialize_naive_datetime(x, &mut last_fmt_idx))
-                .map(|x| x.timestamp_millis())
+                .map(|x| x.and_utc().timestamp_millis())
         }),
         Time32(time_unit) => deserialize_primitive(rows, column, datatype, |bytes| {
             let factor = get_factor_from_timeunit(time_unit);
@@ -315,23 +313,19 @@ pub fn deserialize_column<B: ByteRecordGeneric>(
                         as i64
                 })
         }),
-        // chrono changed their function signature AGAIN
-        #[allow(deprecated)]
         Timestamp(time_unit, None) => {
             let mut last_fmt_idx = 0;
             deserialize_primitive(rows, column, datatype, |bytes| {
                 to_utf8(bytes)
                     .and_then(|s| deserialize_naive_datetime(s, &mut last_fmt_idx))
                     .and_then(|dt| match time_unit {
-                        TimeUnit::Second => Some(dt.timestamp()),
-                        TimeUnit::Millisecond => Some(dt.timestamp_millis()),
-                        TimeUnit::Microsecond => Some(dt.timestamp_micros()),
-                        TimeUnit::Nanosecond => dt.timestamp_nanos_opt(),
+                        TimeUnit::Second => Some(dt.and_utc().timestamp()),
+                        TimeUnit::Millisecond => Some(dt.and_utc().timestamp_millis()),
+                        TimeUnit::Microsecond => Some(dt.and_utc().timestamp_micros()),
+                        TimeUnit::Nanosecond => dt.and_utc().timestamp_nanos_opt(),
                     })
             })
         }
-        // chrono changed their function signature AGAIN
-        #[allow(deprecated)]
         Timestamp(time_unit, Some(ref tz)) => {
             let tz = temporal_conversions::parse_offset(tz)?;
             let mut last_fmt_idx = 0;
diff --git a/src/daft-json/src/decoding.rs b/src/daft-json/src/decoding.rs
index 12814ccba7..9eccd0304c 100644
--- a/src/daft-json/src/decoding.rs
+++ b/src/daft-json/src/decoding.rs
@@ -286,8 +286,6 @@ fn deserialize_date_into<'a, A: Borrow<BorrowedValue<'a>>>(
     });
     target.extend_trusted_len(iter);
 }
-// chrono changed their function signature AGAIN
-#[allow(deprecated)]
 fn deserialize_datetime_into<'a, A: Borrow<BorrowedValue<'a>>>(
     target: &mut Box<dyn MutableArray>,
     rows: &[A],
@@ -312,15 +310,14 @@ fn deserialize_datetime_into<'a, A: Borrow<BorrowedValue<'a>>>(
                         as i64
                 })
             }
-            DataType::Date64 => {
-                deserialize_naive_datetime(v, &mut last_fmt_idx).map(|x| x.timestamp_millis())
-            }
+            DataType::Date64 => deserialize_naive_datetime(v, &mut last_fmt_idx)
+                .map(|x| x.and_utc().timestamp_millis()),
             DataType::Timestamp(tu, None) => deserialize_naive_datetime(v, &mut last_fmt_idx)
                 .and_then(|dt| match tu {
-                    TimeUnit::Second => Some(dt.timestamp()),
-                    TimeUnit::Millisecond => Some(dt.timestamp_millis()),
-                    TimeUnit::Microsecond => Some(dt.timestamp_micros()),
-                    TimeUnit::Nanosecond => dt.timestamp_nanos_opt(),
+                    TimeUnit::Second => Some(dt.and_utc().timestamp()),
+                    TimeUnit::Millisecond => Some(dt.and_utc().timestamp_millis()),
+                    TimeUnit::Microsecond => Some(dt.and_utc().timestamp_micros()),
+                    TimeUnit::Nanosecond => dt.and_utc().timestamp_nanos_opt(),
                 }),
             DataType::Timestamp(tu, Some(ref tz)) => {
                 let tz = if tz == "Z" { "UTC" } else { tz };
diff --git a/src/daft-json/src/read.rs b/src/daft-json/src/read.rs
index 82d2f714f7..798baf8dc1 100644
--- a/src/daft-json/src/read.rs
+++ b/src/daft-json/src/read.rs
@@ -525,11 +525,10 @@ mod tests {
             .map(|f| (f.name.clone(), f.clone()))
             .collect::<IndexMap<_, _>>();
         let (schema, is_projection) = match &projection {
-            #[allow(deprecated)]
             Some(projection) => (
                 projection
                     .iter()
-                    .map(|c| field_map.remove(c.as_str()).unwrap())
+                    .map(|c| field_map.swap_remove(c.as_str()).unwrap())
                     .collect::<Vec<_>>()
                     .into(),
                 true,