diff --git a/postgres-protocol/src/types/mod.rs b/postgres-protocol/src/types/mod.rs index 03bd90799..e8f16b2e2 100644 --- a/postgres-protocol/src/types/mod.rs +++ b/postgres-protocol/src/types/mod.rs @@ -421,6 +421,27 @@ pub fn time_from_sql(mut buf: &[u8]) -> Result Result> { + let v = buf.read_i128::()?; + if !buf.is_empty() { + return Err("invalid message length: interval not drained".into()); + } + Ok(v) +} + + /// Serializes a `MACADDR` value. #[inline] pub fn macaddr_to_sql(v: [u8; 6], buf: &mut BytesMut) { diff --git a/postgres-types/src/chrono_04.rs b/postgres-types/src/chrono_04.rs index d599bde02..74df53738 100644 --- a/postgres-types/src/chrono_04.rs +++ b/postgres-types/src/chrono_04.rs @@ -1,6 +1,7 @@ use bytes::BytesMut; use chrono_04::{ - DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc, + DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeDelta, + TimeZone, Utc, }; use postgres_protocol::types; use std::error::Error; @@ -158,3 +159,29 @@ impl ToSql for NaiveTime { accepts!(TIME); to_sql_checked!(); } + +impl<'a> FromSql<'a> for TimeDelta { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let usec = types::interval_from_sql(raw)?; + if usec > i128::from(i64::max_value()) || jd < i128::from(i64::min_value()) { + return Err("value too large to transmit".into()); + } + Ok(TimeDelta::microseconds(usec as i64)) + } + + accepts!(INTERVAL); +} + +impl ToSql for TimeDelta { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + let usec = match self.num_microseconds() { + Some(usec) => usec, + None => return Err("value too large to transmit".into()), + }; + types::interval_to_sql(i128::from(usec), w); + Ok(IsNull::No) + } + + accepts!(INTERVAL); + to_sql_checked!(); +}