-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Floor, Ceil, Round Function #291
Conversation
The ceil query receives one numeric parameter and executes ceil().
An error that will be ejected when a value other than the value that can be converted to float is received.
If the given value is convertible to float, then execute ceil(), if not convertible, return FunctionRequiresFloatValue error.
If the given value is convertible to float, then run round(), and if not convert, return the FunctionRequiresFloatValue error.
The round() function takes one argument that can be converted to a plot and runs round(), and returns an error if there are more than one or more non-convertible.
if the given value is convertible to float, then excute floor(), and if not convertible, return the FunctionRequiresFloatValue error.
Modify to pass cargo clipy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, clean and minimal 👍 👍 👍
Let's change little bit and merge it into the main!
src/tests/function/floor.rs
Outdated
( | ||
"SELECT FLOOR(0.3) AS floor FROM SingleItem", | ||
Ok(select!( | ||
"floor"; | ||
F64; | ||
0.3_f64.floor() | ||
)), | ||
), | ||
( | ||
"SELECT FLOOR(-0.8) AS floor FROM SingleItem", | ||
Ok(select!( | ||
"floor"; | ||
F64; | ||
(-0.8_f64).floor() | ||
)), | ||
), | ||
( | ||
"SELECT FLOOR(10) AS floor FROM SingleItem", | ||
Ok(select!( | ||
"floor"; | ||
F64; | ||
f64::from(10).floor() | ||
)), | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test cases are identical from the view of our project.
It would be good to consider merging into a one. SELECT FLOOR(0.3), FLOOR(-0.8), FLOOR(10) FROM SingleItem
ref #289 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I resolve that problem
(
r#"
SELECT
FLOOR(0.3) as floor1,
FLOOR(-0.8) as floor2,
FLOOR(10) as floor3,
FLOOR(6.87421) as floor4
FROM SingleItem"#,
Ok(select!(
floor1 | floor2 | floor3 | floor4
F64 | F64 | F64 | F64;
0.3_f64.floor() f64::floor(-0.8_f64) f64::from(10).floor() 6.87421_f64.floor()
)),
),
src/executor/evaluate/mod.rs
Outdated
Function::Ceil(expr) => { | ||
let number = match eval(expr).await?.try_into()? { | ||
Value::F64(number) => Some(number), | ||
Value::Str(s) => match f64::from_str(&s) { | ||
Ok(f) => Some(f), | ||
Err(_) => None, | ||
}, | ||
Value::I64(number) => f64::from_i64(number), | ||
_ => None, | ||
}; | ||
|
||
match number { | ||
Some(number) => Ok(Evaluated::from(Value::F64(number.ceil()))), | ||
None => Err(EvaluateError::FunctionRequiresFloatValue("CEIL".to_owned()).into()), | ||
} | ||
} | ||
Function::Round(expr) => { | ||
let number = match eval(expr).await?.try_into()? { | ||
Value::F64(number) => Some(number), | ||
Value::Str(s) => match f64::from_str(&s) { | ||
Ok(f) => Some(f), | ||
Err(_) => None, | ||
}, | ||
Value::I64(number) => f64::from_i64(number), | ||
_ => None, | ||
}; | ||
|
||
match number { | ||
Some(number) => Ok(Evaluated::from(Value::F64(number.round()))), | ||
None => Err(EvaluateError::FunctionRequiresFloatValue("ROUND".to_owned()).into()), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start! I think you also recognize there are some redundant codes which could be wrapped by a function.
Let's reduce redundancy in Ceil
, Round
and Floor
.
Not just less redundancy helps programmers to write less codes, but also it is better because there's also less stuffs to be tested.
src/executor/evaluate/mod.rs
Outdated
Value::Str(s) => match f64::from_str(&s) { | ||
Ok(f) => Some(f), | ||
Err(_) => None, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's handle Str
input as an error FunctionRequiresFloatValue
.
We can accept, I64 to F64 because it is also natively supported by Rust lang itself, but Str is not.
Users who need to run FLOOR
using Str
value, then they can use CAST
function.
It is also better not to convert Err
into non Err
types.
ref #289 (comment)
rust native not support str to f64
use eval_to_float
src/translate/function.rs
Outdated
"CEIL" => { | ||
check_len(name, args.len(), 1)?; | ||
|
||
translate_expr(args[0]) | ||
.map(Function::Ceil) | ||
.map(Box::new) | ||
.map(Expr::Function) | ||
} | ||
"ROUND" => { | ||
check_len(name, args.len(), 1)?; | ||
|
||
translate_expr(args[0]) | ||
.map(Function::Round) | ||
.map(Box::new) | ||
.map(Expr::Function) | ||
} | ||
"FLOOR" => { | ||
check_len(name, args.len(), 1)?; | ||
|
||
translate_expr(args[0]) | ||
.map(Function::Floor) | ||
.map(Box::new) | ||
.map(Expr::Function) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a macro called func_with_one_arg.
You can add it comfortably.
Rebase and use the master.
Below is an example of usage.
func_with_one_arg!(Function::Ceil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be used when it's a function and only has one argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh thank you, i'll use that macro that can remove redundant code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, eval_to_float
looks really, really good :)
Thanks a lot! 🥇
resolve #264 |
I'm done to add the functions below.
Ceil Func : Nearest integer greater than or equal to argument
Floor Func : Nearest integer less than or equal to argument
example ) 11.3 -> 11
example ) -11.3 -> -12
Rounds Func : v to s decimal places. Ties are broken by rounding away from zero.
example ) 11.6 -> 12
exmaple ) 11.2 -> 11