Skip to content
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

Merged
merged 28 commits into from
Aug 19, 2021
Merged

Add Floor, Ceil, Round Function #291

merged 28 commits into from
Aug 19, 2021

Conversation

tmdgusya
Copy link
Contributor

I'm done to add the functions below.

Ceil Func : Nearest integer greater than or equal to argument

  • example ) 11.2 -> 12
  • example ) -11.3 -> 11

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

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.
@panarch panarch self-requested a review August 16, 2021 11:18
@panarch panarch added the enhancement New feature or request label Aug 16, 2021
Modify to pass cargo clipy
Copy link
Member

@panarch panarch left a 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!

Comment on lines 15 to 38
(
"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()
)),
),
Copy link
Member

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)

Copy link
Contributor Author

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()
    )),
),

Comment on lines 286 to 317
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()),
}
}
Copy link
Member

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.

Comment on lines 321 to 324
Value::Str(s) => match f64::from_str(&s) {
Ok(f) => Some(f),
Err(_) => None,
},
Copy link
Member

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)

Comment on lines 84 to 107
"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)
}
Copy link
Member

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)

Copy link
Member

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

Copy link
Contributor Author

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

@tmdgusya tmdgusya requested a review from panarch August 18, 2021 15:49
Copy link
Member

@panarch panarch left a 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! 🥇

@panarch panarch merged commit 35636a5 into gluesql:main Aug 19, 2021
@panarch
Copy link
Member

panarch commented Aug 20, 2021

resolve #264

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants