-
Notifications
You must be signed in to change notification settings - Fork 166
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add decimal argument support to round function
The round function has a number of variants to support different numeric types. This commit adds support for rounding decimals. The precision and scale of the resultant decimal type is calculated from the input decimal parameters and the scale argument according to the logic in the Spark implementation: https://github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala#L1492 Signed-off-by: Andrew Coleman <[email protected]>
- Loading branch information
1 parent
5932eb9
commit 1dbdb4b
Showing
4 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
%YAML 1.2 | ||
--- | ||
scalar_functions: | ||
- | ||
name: "ceil" | ||
description: > | ||
Rounding to the ceiling of the value `x`. | ||
impls: | ||
- args: | ||
- value: decimal<P,S> | ||
name: x | ||
return: |- | ||
integral_least_num_digits = P - S + 1 | ||
precision = min(integral_least_num_digits, 38) | ||
decimal?<precision, 0> | ||
- | ||
name: "floor" | ||
description: > | ||
Rounding to the floor of the value `x`. | ||
impls: | ||
- args: | ||
- value: decimal<P,S> | ||
name: x | ||
return: |- | ||
integral_least_num_digits = P - S + 1 | ||
precision = min(integral_least_num_digits, 38) | ||
decimal?<precision, 0> | ||
- | ||
name: "round" | ||
description: > | ||
Rounding the value `x` to `s` decimal places. | ||
impls: | ||
- args: | ||
- value: decimal<P1,S1> | ||
name: x | ||
description: > | ||
Numerical expression to be rounded. | ||
- value: i32 | ||
name: s | ||
description: > | ||
Number of decimal places to be rounded to. | ||
When `s` is a positive number, the rounding | ||
is performed to a `s` number of decimal places. | ||
When `s` is a negative number, the rounding is | ||
performed to the left side of the decimal point | ||
as specified by `s`. | ||
The precision and scale of the resultant decimal | ||
type will be adjusted from the input decimal type | ||
dependent on the value of `s`. | ||
options: | ||
rounding: | ||
description: > | ||
When a boundary is computed to lie somewhere between two values, | ||
and this value cannot be exactly represented, this specifies how | ||
to round it. | ||
- TIE_TO_EVEN: round to nearest value; if exactly halfway, tie | ||
to the even option. | ||
- TIE_AWAY_FROM_ZERO: round to nearest value; if exactly | ||
halfway, tie away from zero. | ||
- TRUNCATE: always round toward zero. | ||
- CEILING: always round toward positive infinity. | ||
- FLOOR: always round toward negative infinity. | ||
- AWAY_FROM_ZERO: round negative values with FLOOR rule, round positive values with CEILING rule | ||
- TIE_DOWN: round ties with FLOOR rule | ||
- TIE_UP: round ties with CEILING rule | ||
- TIE_TOWARDS_ZERO: round ties with TRUNCATE rule | ||
- TIE_TO_ODD: round to nearest value; if exactly halfway, tie | ||
to the odd option. | ||
values: [ TIE_TO_EVEN, TIE_AWAY_FROM_ZERO, TRUNCATE, CEILING, FLOOR, | ||
AWAY_FROM_ZERO, TIE_DOWN, TIE_UP, TIE_TOWARDS_ZERO, TIE_TO_ODD ] | ||
nullability: DECLARED_OUTPUT | ||
return: |- | ||
integral_digits = P1 - S1 + 1 | ||
scale = s > 0 ? min(s, S1) : 0 | ||
precision = s > 0 ? min(integral_digits + scale, 38) : min(max(integral_num_digits, 1- s), 38) | ||
decimal?<precision, scale> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
### SUBSTRAIT_SCALAR_TEST: v1.0 | ||
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml' | ||
|
||
# basic: Basic examples without any special cases | ||
ceil(2.25::dec<8,2>) = 3::dec<7,0> | ||
ceil(-65.5::dec<8,2>) = -65::dec<7,0> | ||
ceil(9.9::dec<2,1>) = 10::dec<2,0> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
### SUBSTRAIT_SCALAR_TEST: v1.0 | ||
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml' | ||
|
||
# basic: Basic examples without any special cases | ||
floor(2.25::dec<8,2>) = 2::dec<7,0> | ||
floor(-65.5::dec<8,2>) = -66::dec<7,0> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
### SUBSTRAIT_SCALAR_TEST: v1.0 | ||
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml' | ||
|
||
# basic: Basic examples without any special cases | ||
round(2::dec<2,0>, 2::i32) = 2::dec<3,0> | ||
round(2.75::dec<8,2>, 1::i32) = 2.8::dec<8,1> | ||
|
||
# negative_rounding: Examples with negative rounding | ||
round(2::dec<2,0>, -2::i32) = 0::dec<2,0> | ||
round(123::dec<2,0>, -2::i32) = 100::dec<2,0> | ||
round(8793::dec<2,0>, -2::i32) = 8800::dec<2,0> |