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

functions: support trunc() function with one or two args #6942

Merged
merged 10 commits into from
Jul 20, 2023

Conversation

Syleechan
Copy link
Contributor

@Syleechan Syleechan commented Jul 13, 2023

Which issue does this PR close?

Closes #.

Rationale for this change

before change the trunc function only with one arg and truncate the number after the decimal point
after change the trunc function with two args, and can truncate the decimal customarily, see the detail from the link below
https://www.postgresql.org/docs/current/functions-math.html#:~:text=trunc%20(%20numeric,2)%20%E2%86%92%2042.43

What changes are included in this PR?

Are these changes tested?

Are there any user-facing changes?

@github-actions github-actions bot added logical-expr Logical plan and expressions physical-expr Physical Expressions labels Jul 13, 2023
@liukun4515
Copy link
Contributor

can describe the issue?

@Syleechan
Copy link
Contributor Author

can describe the issue?

see the relationale for this change

@alamb
Copy link
Contributor

alamb commented Jul 16, 2023

THanks @Syleechan -- I plan to review this over the next day or two!

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution @Syleechan

I left some style suggestions, but overall I think this PR is close

The only thing I think is needed to merge is some SQL level tests -- perhaps you could add some sqllogic tests (readme is here)

https://github.com/apache/arrow-datafusion/blob/9338880d8f64f8143e348a60beee8af2789fa8ae/datafusion/core/tests/sqllogictests/test_files/scalar.slt#L892-L914 along side the 1 argument version

Also, I think it would be good to include a test of calling trunc(1, 2, 3) with more than two arguments and ensure we get a Planning or Execution error rather than an InternalError. Internal errors signal a bug in DataFusion

@@ -501,7 +501,7 @@ scalar_expr!(
scalar_expr!(Degrees, degrees, num, "converts radians to degrees");
scalar_expr!(Radians, radians, num, "converts degrees to radians");
nary_scalar_expr!(Round, round, "round to nearest integer");
scalar_expr!(Trunc, trunc, num, "truncate toward zero");
nary_scalar_expr!(Trunc, trunc, "truncate toward to precision");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this function truncates toward precision -- instead it truncates towards zero with an optional precision

Suggested change
nary_scalar_expr!(Trunc, trunc, "truncate toward to precision");
nary_scalar_expr!(Trunc, trunc, "truncate toward zero, with optional precision");

Comment on lines 511 to 516
let mut _precision = ColumnarValue::Scalar(Int32(Some(0)));

let num = &args[0];
if args.len() == 2 {
_precision = ColumnarValue::Array(args[1].clone());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of _ as a prefix of a variable is used to tell the compiler it can be unused. In this case I think it is used and thus the variable should be named precision

A more "idiomatic" rust way (and avoiding the mut) of writing this might be

Suggested change
let mut _precision = ColumnarValue::Scalar(Int32(Some(0)));
let num = &args[0];
if args.len() == 2 {
_precision = ColumnarValue::Array(args[1].clone());
}
let precision = if args.len() == 1 {
ColumnarValue::Scalar(Int32(Some(0)))
} else {
ColumnarValue::Array(args[1].clone())
};

}

fn compute_truncate32(x: f32, y: usize) -> f32 {
let s = format!("{:.precision$}", x, precision = y);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably make this quite a bit more efficient by avoiding strings, for example something like (untested):

let factor = 10.0f32.pow(precision);
(x * factor).round() / factor;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@Syleechan
Copy link
Contributor Author

Syleechan commented Jul 18, 2023

thanks for your suggestion.Now I try with sql level test.But it shows with the message:

Running "scalar.slt"
External error: query failed: DataFusion error: Error during planning: No function matches the given name and argument types 'trunc(Float64, Int64)'. You might need to add explicit type casts.
        Candidate functions:
        trunc(Float64/Float32)

I am not familiar with the sql test function, so can you tell me how to deal with the error. @alamb

@github-actions github-actions bot added core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) labels Jul 18, 2023
@alamb
Copy link
Contributor

alamb commented Jul 18, 2023

I am not familiar with the sql test function, so can you tell me how to deal with the error. @alamb

I can help, but probably not until tomorrow.

I don't think the error you are seeing is related to the testing function, it is related somehow to how the function is registered with datafusion

@Syleechan
Copy link
Contributor Author

I am not familiar with the sql test function, so can you tell me how to deal with the error. @alamb

I can help, but probably not until tomorrow.

I don't think the error you are seeing is related to the testing function, it is related somehow to how the function is registered with datafusion

thanks for your help.

@Syleechan
Copy link
Contributor Author

I have found the issue and fixed it, please help to review again, thanks @alamb

@Syleechan Syleechan requested a review from alamb July 20, 2023 04:11
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me @Syleechan -- thank you very much.

@@ -1072,6 +1072,15 @@ impl BuiltinScalarFunction {
],
self.volatility(),
),
BuiltinScalarFunction::Trunc => Signature::one_of(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@alamb alamb merged commit f05df7b into apache:main Jul 20, 2023
20 checks passed
@alamb
Copy link
Contributor

alamb commented Jul 20, 2023

here is a follow on PR #7042 with test and doc updates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Core DataFusion crate logical-expr Logical plan and expressions physical-expr Physical Expressions sqllogictest SQL Logic Tests (.slt)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants