-
Notifications
You must be signed in to change notification settings - Fork 0
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
Fix truncate() function #188
Conversation
Signed-off-by: Margarit Hakobyan <[email protected]>
Codecov Report
@@ Coverage Diff @@
## integ-fix-truncate #188 +/- ##
========================================================
- Coverage 98.31% 95.81% -2.50%
- Complexity 3521 3525 +4
========================================================
Files 342 352 +10
Lines 8700 9362 +662
Branches 554 677 +123
========================================================
+ Hits 8553 8970 +417
- Misses 142 334 +192
- Partials 5 58 +53
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
* @param numberOfDecimals required decimal places | ||
* @return truncated number as {@link BigDecimal} | ||
*/ | ||
public static BigDecimal truncateNumber(double numberToTruncate, int numberOfDecimals) { |
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.
Please, add unit tests with different numberOfDecimals
values. The test should use another function to validate the result, for example, substring
:
assertEquals(value.toString().subString(...), truncateNumber(value, scale).toString())
import java.math.RoundingMode; | ||
import lombok.experimental.UtilityClass; | ||
|
||
@UtilityClass |
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.
This could be troublesome: opensearch-project#1045 (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'm not sure if MathUtil is necessary. Let's include private
function truncateNumber
in MathematicalFunction.java
.
* @return truncated number as {@link BigDecimal} | ||
*/ | ||
public static BigDecimal truncateNumber(double numberToTruncate, int numberOfDecimals) { | ||
if (numberToTruncate > 0) { |
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.
Better to use a conditional instead of if...else:
return new BigDecimal(String.valueOf(numberToTruncate)).setScale(numberOfDecimals,
numberToTruncate > 1.0 ? RoundingMode.FLOOR : RoundingMode.CEILING);
or
RoundingMode roundingMode = numberToTruncate > 1.0 ? RoundingMode.FLOOR : RoundingMode.CEILING;
BigDecimal bd = new BigDecimal(String.valueOf(numberToTruncate)).setScale(numberOfDecimals, roundingMode);
import java.math.RoundingMode; | ||
import lombok.experimental.UtilityClass; | ||
|
||
@UtilityClass |
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'm not sure if MathUtil is necessary. Let's include private
function truncateNumber
in MathematicalFunction.java
.
...src/test/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctionTest.java
Outdated
Show resolved
Hide resolved
@@ -500,26 +500,22 @@ private static DefaultFunctionResolver truncate() { | |||
FunctionDSL.impl( | |||
FunctionDSL.nullMissingHandling( | |||
(x, y) -> new ExprLongValue( | |||
new BigDecimal(x.integerValue()).setScale(y.integerValue(), | |||
RoundingMode.DOWN).longValue())), | |||
MathUtil.truncateNumber(x.integerValue(), y.integerValue()).longValue())), |
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.
this is going to convert x.integerValue()
into a double
since truncateNumber
only accepts double
. We should have a truncateNumber
function for int
, long
, float
, etc. I'm not sure this saves much effort/code?
Signed-off-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan <[email protected]>
* @return truncated number as double | ||
*/ | ||
public static double truncateDouble(double numberToTruncate, int numberOfDecimals) { | ||
return new BigDecimal(String.valueOf(numberToTruncate)).setScale(numberOfDecimals, |
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'm not sure it worthwhile to have this class. These are all single-line calls used a single time. I would prefer to remove this file and include the code in the MathematicalFunction.java
code.
Like:
FunctionDSL.nullMissingHandling(
(x, y) -> new ExprLongValue(
new BigDecimal(String.valueOf(numberToTruncate)).setScale(numberOfDecimals, numberToTruncate > 0 ? RoundingMode.FLOOR : RoundingMode.CEILING).doubleValue()),
LONG, INTEGER, INTEGER),
Signed-off-by: Margarit Hakobyan <[email protected]>
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.
Try adding tests where second arg is not 1, e.g:
truncate(1.1, 2)
truncate(x, 0)
truncate(x, -1)
truncate(x, 100)
truncate(Math.PI, 4)
and so on...
Signed-off-by: Margarit Hakobyan <[email protected]>
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.
@margarit-h one suggestion I had is to use BigDecimal.valueOf
instead of new BigDecimal(String.valueOf(...))
.
Everything else looks good.
LONG, INTEGER, INTEGER), | ||
FunctionDSL.impl( | ||
FunctionDSL.nullMissingHandling( | ||
(x, y) -> new ExprLongValue( | ||
new BigDecimal(x.integerValue()).setScale(y.integerValue(), | ||
RoundingMode.DOWN).longValue())), | ||
new BigDecimal(String.valueOf(x.longValue())).setScale(y.integerValue(), |
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.
new BigDecimal(String.valueOf(x.longValue())).setScale(y.integerValue(), | |
BigDecimal.valueOf(x.longValue()).setScale(y.integerValue(), |
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.
Addressed in 21619b4
@@ -500,26 +500,30 @@ private static DefaultFunctionResolver truncate() { | |||
FunctionDSL.impl( | |||
FunctionDSL.nullMissingHandling( | |||
(x, y) -> new ExprLongValue( | |||
new BigDecimal(x.integerValue()).setScale(y.integerValue(), | |||
RoundingMode.DOWN).longValue())), | |||
new BigDecimal(String.valueOf(x.integerValue())).setScale(y.integerValue(), |
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.
new BigDecimal(String.valueOf(x.integerValue())).setScale(y.integerValue(), | |
BigDecimal.valueOf(x.integerValue()).setScale(y.integerValue(), |
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.
Addressed in 21619b4
LONG, LONG, INTEGER), | ||
FunctionDSL.impl( | ||
FunctionDSL.nullMissingHandling( | ||
(x, y) -> new ExprDoubleValue( | ||
new BigDecimal(x.floatValue()).setScale(y.integerValue(), | ||
RoundingMode.DOWN).doubleValue())), | ||
new BigDecimal(String.valueOf(x.floatValue())).setScale(y.integerValue(), |
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.
new BigDecimal(String.valueOf(x.floatValue())).setScale(y.integerValue(), | |
BigDecimal.valueOf(x.floatValue()).setScale(y.integerValue(), |
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.
Addressed in 21619b4
DOUBLE, FLOAT, INTEGER), | ||
FunctionDSL.impl( | ||
FunctionDSL.nullMissingHandling( | ||
(x, y) -> new ExprDoubleValue( | ||
new BigDecimal(x.doubleValue()).setScale(y.integerValue(), | ||
RoundingMode.DOWN).doubleValue())), | ||
new BigDecimal(String.valueOf(x.doubleValue())).setScale(y.integerValue(), |
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.
new BigDecimal(String.valueOf(x.doubleValue())).setScale(y.integerValue(), | |
new BigDecimal.valueOf(x.doubleValue()).setScale(y.integerValue(), |
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.
Addressed in 21619b4
public void truncate_int_value(Integer value) { | ||
FunctionExpression truncate = DSL.truncate(DSL.literal(value), DSL.literal(1)); | ||
assertThat( | ||
truncate.valueOf(valueEnv()), allOf(hasType(LONG), | ||
hasValue(new BigDecimal(value).setScale(1, RoundingMode.DOWN).longValue()))); | ||
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, |
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.
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, | |
hasValue(BigDecimal.valueOf(value).setScale(1, |
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.
Addressed in 21619b4
public void truncate_long_value(Long value) { | ||
FunctionExpression truncate = DSL.truncate(DSL.literal(value), DSL.literal(1)); | ||
assertThat( | ||
truncate.valueOf(valueEnv()), allOf(hasType(LONG), | ||
hasValue(new BigDecimal(value).setScale(1, RoundingMode.DOWN).longValue()))); | ||
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, |
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.
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, | |
hasValue(BigDecimal.valueOf(value).setScale(1, |
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.
Addressed in 21619b4
public void truncate_float_value(Float value) { | ||
FunctionExpression truncate = DSL.truncate(DSL.literal(value), DSL.literal(1)); | ||
assertThat( | ||
truncate.valueOf(valueEnv()), allOf(hasType(DOUBLE), | ||
hasValue(new BigDecimal(value).setScale(1, RoundingMode.DOWN).doubleValue()))); | ||
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, |
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.
hasValue(new BigDecimal(String.valueOf(value)).setScale(1, | |
hasValue(BigDecimal.valueOf(value).setScale(1, |
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.
Addressed in 21619b4
integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java
Outdated
Show resolved
Hide resolved
...src/test/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctionTest.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan <[email protected]>
* Fix truncate() function (#188) Signed-off-by: Margarit Hakobyan <[email protected]> Signed-off-by: Margarit Hakobyan <[email protected]>
…#1213) * Fix truncate() function (#188) Signed-off-by: Margarit Hakobyan <[email protected]> Signed-off-by: Margarit Hakobyan <[email protected]> (cherry picked from commit 7714819) Co-authored-by: Margarit Hakobyan <[email protected]>
Signed-off-by: Margarit Hakobyan [email protected]
Description
Fixes
truncate()
returning incorrect results for some input data issue.Example of a query result after the proposed fix:
Issues Resolved
opensearch-project#1043
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.