Skip to content

Commit

Permalink
expr/builtin_time: Implement AddDurationAndString (#4010)
Browse files Browse the repository at this point in the history
* expr/builtin_time: Implement AddDurationAndString

Signed-off-by: DCjanus <DCjanus@dcjanus.com>
  • Loading branch information
DCjanus authored and huachaohuang committed Jan 7, 2019
1 parent 1f43235 commit 3074818
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
88 changes: 88 additions & 0 deletions src/coprocessor/dag/expr/builtin_time.rs
Expand Up @@ -390,6 +390,27 @@ impl ScalarFunc {
};
Ok(Some(Cow::Owned(res)))
}

#[inline]
pub fn add_duration_and_string<'a, 'b: 'a>(
&'b self,
ctx: &mut EvalContext,
row: &'a [Datum],
) -> Result<Option<Cow<'a, MyDuration>>> {
let arg0: Cow<'a, MyDuration> = try_opt!(self.children[0].eval_duration(ctx, row));

let cow_s: Cow<'a, [u8]> = try_opt!(self.children[1].eval_string(ctx, row));
let s: &str = box_try!(::std::str::from_utf8(cow_s.as_ref()));
let arg1 = MyDuration::parse(s.as_bytes(), Time::parse_fsp(s))?;

let add: i64 = match arg0.to_nanos().checked_add(arg1.to_nanos()) {
Some(result) => result,
None => return Err(box_err!("add duration {} and string {} overflow", arg0, s)),
};

let res = MyDuration::from_nanos(add, arg0.get_fsp().max(arg1.get_fsp()) as i8)?;
Ok(Some(Cow::Owned(res)))
}
}

#[cfg(test)]
Expand Down Expand Up @@ -1318,4 +1339,71 @@ mod tests {
}
}

#[test]
fn test_duration_and_string() {
let cases = vec![
("01:00:00.999999", "02:00:00.999998", "03:00:01.999997"),
("23:59:59", "00:00:01", "24:00:00"),
("235959", "00:00:01", "24:00:00"),
("110:00:00", "1 02:00:00", "136:00:00"),
("-110:00:00", "1 02:00:00", "-84:00:00"),
("00:00:01", "-00:00:01", "00:00:00"),
("00:00:03", "-00:00:01", "00:00:02"),
];
let mut ctx = EvalContext::default();
for (arg1, arg2, exp) in cases {
test_ok_case_two_arg(
&mut ctx,
ScalarFuncSig::AddDurationAndString,
Datum::Dur(Duration::parse(arg1.as_ref(), 6).unwrap()),
Datum::Bytes(arg2.as_bytes().to_vec()),
Datum::Dur(Duration::parse(exp.as_ref(), 6).unwrap()),
);
}

let zero_duration = Datum::Dur(Duration::zero());
let zero_duration_string = Datum::Bytes(Vec::new());
let cases = vec![
(
Datum::Dur(Duration::parse(b"1 01:00:00", 6).unwrap()),
Datum::Null,
Datum::Null,
),
(
Datum::Null,
Datum::Bytes(b"11:30:45.123456".to_vec()),
Datum::Null,
),
(Datum::Null, Datum::Null, Datum::Null),
(
zero_duration.clone(),
zero_duration_string.clone(),
zero_duration.clone(),
),
(
zero_duration.clone(),
Datum::Bytes(b"01:00:00".to_vec()),
Datum::Dur(Duration::parse(b"01:00:00", 6).unwrap()),
),
(
Datum::Dur(Duration::parse(b"01:00:00", 6).unwrap()),
zero_duration_string.clone(),
Datum::Dur(Duration::parse(b"01:00:00", 6).unwrap()),
),
(
Datum::Dur(Duration::parse(b"01:00:00", 6).unwrap()),
Datum::Bytes(b"-01:00:00".to_vec()),
zero_duration.clone(),
),
];
for (arg1, arg2, exp) in cases {
test_ok_case_two_arg(
&mut ctx,
ScalarFuncSig::AddDurationAndString,
arg1,
arg2,
exp,
);
}
}
}
6 changes: 4 additions & 2 deletions src/coprocessor/dag/expr/scalar_function.rs
Expand Up @@ -133,6 +133,7 @@ impl ScalarFunc {
| ScalarFuncSig::SubstringBinary2Args
| ScalarFuncSig::DateDiff
| ScalarFuncSig::AddDurationAndDuration
| ScalarFuncSig::AddDurationAndString
| ScalarFuncSig::Strcmp => (2, 2),

ScalarFuncSig::CastIntAsInt
Expand Down Expand Up @@ -365,7 +366,6 @@ impl ScalarFunc {
| ScalarFuncSig::AddDateStringDecimal
| ScalarFuncSig::AddDateStringInt
| ScalarFuncSig::AddDateStringString
| ScalarFuncSig::AddDurationAndString
| ScalarFuncSig::AddStringAndDuration
| ScalarFuncSig::AddStringAndString
| ScalarFuncSig::AddTimeDurationNull
Expand Down Expand Up @@ -1019,6 +1019,7 @@ dispatch_call! {
CaseWhenDuration => case_when_duration,

AddDurationAndDuration => add_duration_and_duration,
AddDurationAndString => add_duration_and_string,
}
JSON_CALLS {
CastIntAsJson => cast_int_as_json,
Expand Down Expand Up @@ -1158,6 +1159,8 @@ mod tests {
ScalarFuncSig::Substring2Args,
ScalarFuncSig::SubstringBinary2Args,
ScalarFuncSig::Strcmp,
ScalarFuncSig::AddDurationAndString,
ScalarFuncSig::AddDurationAndDuration,
],
2,
2,
Expand Down Expand Up @@ -1432,7 +1435,6 @@ mod tests {
ScalarFuncSig::AddDateStringDecimal,
ScalarFuncSig::AddDateStringInt,
ScalarFuncSig::AddDateStringString,
ScalarFuncSig::AddDurationAndString,
ScalarFuncSig::AddStringAndDuration,
ScalarFuncSig::AddStringAndString,
ScalarFuncSig::AddTimeDurationNull,
Expand Down

0 comments on commit 3074818

Please sign in to comment.