Skip to content

Commit

Permalink
Fix ToSql
Browse files Browse the repository at this point in the history
This sets the smallest unit to microseconds when calculating time deltas.

Previously, the number of microseconds was expressed improperly because
the rounding was not set.
  • Loading branch information
allan2 committed Aug 14, 2024
1 parent e19b3dc commit c96342d
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions postgres-types/src/jiff_01.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bytes::BytesMut;
use jiff_01::{
civil::{Date, DateTime, Time},
Span, Timestamp,
Span, SpanRound, Timestamp, Unit,
};
use postgres_protocol::types;
use std::error::Error;
Expand All @@ -12,13 +12,17 @@ const fn base() -> DateTime {
DateTime::constant(2000, 1, 1, 0, 0, 0, 0)
}

/// The number of seconds from the Unix epoch to 2000-01-01 00:00:00 UTC.
/// The number of seconds from the Unix epoch to 2000-01-01 00:00:00 UTC.
const PG_EPOCH: i64 = 946684800;

fn base_ts() -> Timestamp {
Timestamp::new(PG_EPOCH, 0).unwrap()
}

fn round_us<'a>() -> SpanRound<'a> {
SpanRound::new().largest(Unit::Microsecond)
}

impl<'a> FromSql<'a> for DateTime {
fn from_sql(_: &Type, raw: &[u8]) -> Result<DateTime, Box<dyn Error + Sync + Send>> {
let t = types::timestamp_from_sql(raw)?;
Expand All @@ -30,7 +34,8 @@ impl<'a> FromSql<'a> for DateTime {

impl ToSql for DateTime {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
types::timestamp_to_sql(self.since(base())?.get_microseconds(), w);
let span = self.since(base())?.round(round_us())?;
types::timestamp_to_sql(span.get_microseconds(), w);
Ok(IsNull::No)
}

Expand All @@ -49,7 +54,8 @@ impl<'a> FromSql<'a> for Timestamp {

impl ToSql for Timestamp {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
types::timestamp_to_sql(self.since(base_ts())?.get_microseconds(), w);
let span = self.since(base_ts())?.round(round_us())?;
types::timestamp_to_sql(span.get_microseconds(), w);
Ok(IsNull::No)
}

Expand Down Expand Up @@ -88,8 +94,8 @@ impl<'a> FromSql<'a> for Time {

impl ToSql for Time {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let delta = self.since(Time::midnight())?;
types::time_to_sql(delta.get_microseconds(), w);
let span = self.since(Time::midnight())?.round(round_us())?;
types::time_to_sql(span.get_microseconds(), w);
Ok(IsNull::No)
}

Expand Down

0 comments on commit c96342d

Please sign in to comment.