diff --git a/src/util/codec/mysql/duration.rs b/src/util/codec/mysql/duration.rs index a0243f21d72..c3c8d989d70 100644 --- a/src/util/codec/mysql/duration.rs +++ b/src/util/codec/mysql/duration.rs @@ -94,35 +94,29 @@ impl Duration { if self.neg { -nanos } else { nanos } } - pub fn from_nanos(nanos: i64, fsp: u8) -> Result { + pub fn from_nanos(nanos: i64, fsp: i8) -> Result { let neg = nanos < 0; let nanos = nanos.abs(); let dur = StdDuration::new((nanos / NANOS_PER_SEC) as u64, (nanos % NANOS_PER_SEC) as u32); - try!(check_dur(&dur)); - - Ok(Duration { - dur: dur, - neg: neg, - fsp: fsp, - }) + Duration::new(dur, neg, fsp) } - pub fn new(dur: StdDuration, neg: bool, fsp: u8) -> Result { + pub fn new(dur: StdDuration, neg: bool, fsp: i8) -> Result { try!(check_dur(&dur)); Ok(Duration { dur: dur, neg: neg, - fsp: fsp, + fsp: try!(check_fsp(fsp)), }) } // `parse` parses the time form a formatted string with a fractional seconds part, // returns the duration type Time value. // See: http://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html - pub fn parse(mut s: &[u8], fsp: u8) -> Result { - try!(check_fsp(fsp)); + pub fn parse(mut s: &[u8], fsp: i8) -> Result { + let fsp = try!(check_fsp(fsp)); let (mut neg, mut day, mut frac) = (false, None, 0); @@ -182,13 +176,7 @@ impl Duration { } let dur = StdDuration::new(secs, frac); - try!(check_dur(&dur)); - - Ok(Duration { - dur: dur, - neg: neg, - fsp: fsp, - }) + Duration::new(dur, neg, fsp as i8) } pub fn to_decimal(&self) -> Result { @@ -262,7 +250,7 @@ mod test { #[test] fn test_parse() { - let cases: Vec<(&'static [u8], u8, Option<&'static str>)> = vec![ + let cases: Vec<(&'static [u8], i8, Option<&'static str>)> = vec![ (b"10:11:12", 0, Some("10:11:12")), (b"101112", 0, Some("10:11:12")), (b"10:11", 0, Some("10:11:00")), diff --git a/src/util/codec/mysql/mod.rs b/src/util/codec/mysql/mod.rs index 825073be3a0..6e4800be170 100644 --- a/src/util/codec/mysql/mod.rs +++ b/src/util/codec/mysql/mod.rs @@ -14,17 +14,24 @@ use util::codec::Result; use util::escape; +/// `UN_SPECIFIED_FSP` is the unspecified fractional seconds part. +const UN_SPECIFIED_FSP: i8 = -1; /// `MAX_FSP` is the maximum digit of fractional seconds part. -pub const MAX_FSP: u8 = 6; +pub const MAX_FSP: i8 = 6; +/// `MIN_FSP` is the minimum digit of fractional seconds part. +pub const MIN_FSP: i8 = 0; /// `DEFAULT_FSP` is the default digit of fractional seconds part. /// `MySQL` use 0 as the default Fsp. -pub const DEFAULT_FSP: u8 = 0; +pub const DEFAULT_FSP: i8 = 0; -fn check_fsp(fsp: u8) -> Result<()> { - if fsp > MAX_FSP { +fn check_fsp(fsp: i8) -> Result { + if fsp == UN_SPECIFIED_FSP { + return Ok(DEFAULT_FSP as u8); + } + if fsp > MAX_FSP || fsp < MIN_FSP { return Err(invalid_type!("Invalid fsp {}", fsp)); } - Ok(()) + Ok(fsp as u8) } /// Parse string as if it's a fraction part of a number and keep diff --git a/src/util/codec/mysql/time.rs b/src/util/codec/mysql/time.rs index 60e35a868ee..30b5bea5fa7 100644 --- a/src/util/codec/mysql/time.rs +++ b/src/util/codec/mysql/time.rs @@ -109,11 +109,11 @@ pub struct Time { } impl Time { - pub fn new(time: NaiveDateTime, tp: u8, fsp: u8) -> Result