Skip to content

Commit 7e2c8ed

Browse files
committed
readyset-data: Handle parsing and returning more invalid dates
A schema with a DEFAULT '0000-00-00 00:00:00' revealed another parsing location that needed to take invalid dates into account. Release-Note-Core: Handle invalid '0000-00-00 00:00:00' date when it appears as as a default column value in the schema. Change-Id: I676f9e8c4af8c1fbb4df8be78f7741e5c127590d Reviewed-on: https://gerrit.readyset.name/c/readyset/+/9079 Reviewed-by: Marcelo Altmann <marcelo@readyset.io> Tested-by: Buildkite CI
1 parent 860925e commit 7e2c8ed

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

readyset-data/src/timestamp.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use chrono::{
77
DateTime, Datelike, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Timelike,
88
};
99
use proptest::arbitrary::Arbitrary;
10-
use readyset_errors::{internal_err, ReadySetError, ReadySetResult};
10+
use readyset_errors::{internal, internal_err, ReadySetError, ReadySetResult};
1111
use serde::{Deserialize, Serialize};
1212

1313
use crate::{DfType, DfValue};
@@ -24,6 +24,9 @@ pub const TIMESTAMP_TZ_FORMAT: &str = "%Y-%m-%d %H:%M:%S%:z";
2424
/// The format for dates when parsed as text
2525
pub const DATE_FORMAT: &str = "%Y-%m-%d";
2626

27+
/// The format for times when parsed as text
28+
pub const TIME_PARSE_FORMAT: &str = "%H:%M:%S%.f";
29+
2730
/// An optimized storage for date and datetime SQL formats. The possible inner data
2831
/// may be:
2932
///
@@ -397,12 +400,29 @@ impl TimestampTz {
397400
}
398401
} else if let Ok(dt) = NaiveDateTime::parse_from_str(ts, TIMESTAMP_PARSE_FORMAT) {
399402
dt.into()
400-
} else {
403+
} else if let Ok(dt) = NaiveDate::parse_from_str(ts, DATE_FORMAT) {
401404
// Make TimestampTz object with time portion 00:00:00
402-
NaiveDate::parse_from_str(ts, DATE_FORMAT)?
403-
.and_hms_opt(0, 0, 0)
405+
dt.and_hms_opt(0, 0, 0)
404406
.ok_or(internal_err!("Invalid date format"))?
405407
.into()
408+
} else if ts.starts_with("+0000-00-00") {
409+
const ZERO_TIME: NaiveTime = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
410+
match ts.split_once(' ') {
411+
None | Some((_, "")) => Self::zero(),
412+
Some((_, time)) => {
413+
if let Ok(time) = NaiveTime::parse_from_str(time, TIME_PARSE_FORMAT) {
414+
if time == ZERO_TIME {
415+
Self::zero()
416+
} else {
417+
internal!("Invalid date format")
418+
}
419+
} else {
420+
internal!("Invalid date format")
421+
}
422+
}
423+
}
424+
} else {
425+
internal!("Invalid date format")
406426
},
407427
)
408428
}

0 commit comments

Comments
 (0)