Bugfix - time::ceil function edge case. (#1976)
This commit is contained in:
parent
01b280623c
commit
db345a2ce7
2 changed files with 34 additions and 13 deletions
|
@ -3,20 +3,31 @@ use crate::sql::datetime::Datetime;
|
||||||
use crate::sql::duration::Duration;
|
use crate::sql::duration::Duration;
|
||||||
use crate::sql::value::Value;
|
use crate::sql::value::Value;
|
||||||
use chrono::offset::TimeZone;
|
use chrono::offset::TimeZone;
|
||||||
use chrono::Datelike;
|
use chrono::{DateTime, Datelike, DurationRound, Local, Timelike, Utc};
|
||||||
use chrono::DurationRound;
|
|
||||||
use chrono::Local;
|
|
||||||
use chrono::Timelike;
|
|
||||||
use chrono::Utc;
|
|
||||||
|
|
||||||
pub fn ceil((val, duration): (Datetime, Duration)) -> Result<Value, Error> {
|
pub fn ceil((val, duration): (Datetime, Duration)) -> Result<Value, Error> {
|
||||||
match chrono::Duration::from_std(*duration) {
|
match chrono::Duration::from_std(*duration) {
|
||||||
Ok(d) => match val.duration_trunc(d).ok().and_then(|floor| floor.checked_add_signed(d)) {
|
Ok(d) => {
|
||||||
Some(v) => Ok(v.into()),
|
let floor_to_ceil = |floor: DateTime<Utc>| -> Option<DateTime<Utc>> {
|
||||||
_ => Err(Error::InvalidArguments {
|
if floor == *val {
|
||||||
name: String::from("time::ceil"),
|
Some(floor)
|
||||||
message: String::from("The second argument must be a duration, and must be able to be represented as nanoseconds."),
|
} else {
|
||||||
}),
|
floor.checked_add_signed(d)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = val
|
||||||
|
.duration_trunc(d)
|
||||||
|
.ok()
|
||||||
|
.and_then(floor_to_ceil);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Some(v) => Ok(v.into()),
|
||||||
|
_ => Err(Error::InvalidArguments {
|
||||||
|
name: String::from("time::ceil"),
|
||||||
|
message: String::from("The second argument must be a duration, and must be able to be represented as nanoseconds."),
|
||||||
|
}),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => Err(Error::InvalidArguments {
|
_ => Err(Error::InvalidArguments {
|
||||||
name: String::from("time::ceil"),
|
name: String::from("time::ceil"),
|
||||||
|
|
|
@ -3559,11 +3559,12 @@ async fn function_time_ceil() -> Result<(), Error> {
|
||||||
let sql = r#"
|
let sql = r#"
|
||||||
RETURN time::ceil("1987-06-22T08:30:45Z", 1w);
|
RETURN time::ceil("1987-06-22T08:30:45Z", 1w);
|
||||||
RETURN time::ceil("1987-06-22T08:30:45Z", 1y);
|
RETURN time::ceil("1987-06-22T08:30:45Z", 1y);
|
||||||
|
RETURN time::ceil("2023-05-11T03:09:00Z", 1s);
|
||||||
"#;
|
"#;
|
||||||
let dbs = Datastore::new("memory").await?;
|
let dbs = Datastore::new("memory").await?;
|
||||||
let ses = Session::for_kv().with_ns("test").with_db("test");
|
let ses = Session::for_kv().with_ns("test").with_db("test");
|
||||||
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
||||||
assert_eq!(res.len(), 2);
|
assert_eq!(res.len(), 3);
|
||||||
//
|
//
|
||||||
let tmp = res.remove(0).result?;
|
let tmp = res.remove(0).result?;
|
||||||
let val = Value::parse("'1987-06-25T00:00:00Z'");
|
let val = Value::parse("'1987-06-25T00:00:00Z'");
|
||||||
|
@ -3573,6 +3574,10 @@ async fn function_time_ceil() -> Result<(), Error> {
|
||||||
let val = Value::parse("'1987-12-28T00:00:00Z'");
|
let val = Value::parse("'1987-12-28T00:00:00Z'");
|
||||||
assert_eq!(tmp, val);
|
assert_eq!(tmp, val);
|
||||||
//
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::parse("'2023-05-11T03:09:00Z'");
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3602,11 +3607,12 @@ async fn function_time_floor() -> Result<(), Error> {
|
||||||
let sql = r#"
|
let sql = r#"
|
||||||
RETURN time::floor("1987-06-22T08:30:45Z", 1w);
|
RETURN time::floor("1987-06-22T08:30:45Z", 1w);
|
||||||
RETURN time::floor("1987-06-22T08:30:45Z", 1y);
|
RETURN time::floor("1987-06-22T08:30:45Z", 1y);
|
||||||
|
RETURN time::floor("2023-05-11T03:09:00Z", 1s);
|
||||||
"#;
|
"#;
|
||||||
let dbs = Datastore::new("memory").await?;
|
let dbs = Datastore::new("memory").await?;
|
||||||
let ses = Session::for_kv().with_ns("test").with_db("test");
|
let ses = Session::for_kv().with_ns("test").with_db("test");
|
||||||
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
||||||
assert_eq!(res.len(), 2);
|
assert_eq!(res.len(), 3);
|
||||||
//
|
//
|
||||||
let tmp = res.remove(0).result?;
|
let tmp = res.remove(0).result?;
|
||||||
let val = Value::parse("'1987-06-18T00:00:00Z'");
|
let val = Value::parse("'1987-06-18T00:00:00Z'");
|
||||||
|
@ -3616,6 +3622,10 @@ async fn function_time_floor() -> Result<(), Error> {
|
||||||
let val = Value::parse("'1986-12-28T00:00:00Z'");
|
let val = Value::parse("'1986-12-28T00:00:00Z'");
|
||||||
assert_eq!(tmp, val);
|
assert_eq!(tmp, val);
|
||||||
//
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::parse("'2023-05-11T03:09:00Z'");
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue