Skip to content

Commit 92c964b

Browse files
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 of the resultant decimal type is one greater than the precision of the input decimal to allow for rounding up to the next decimal digit. The scale of the resultant decimal type is the same as the input type since the result of rounding cannot add any further decimal places. Signed-off-by: Andrew Coleman <[email protected]>
1 parent 273f6ce commit 92c964b

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
%YAML 1.2
2+
---
3+
scalar_functions:
4+
-
5+
name: "ceil"
6+
description: >
7+
Rounding to the ceiling of the value `x`.
8+
impls:
9+
- args:
10+
- value: decimal<P,S>
11+
name: x
12+
return: |-
13+
integral_least_num_digits = P - S + 1
14+
precision = min(integral_least_num_digits, 38)
15+
decimal?<precision, 0>
16+
-
17+
name: "floor"
18+
description: >
19+
Rounding to the floor of the value `x`.
20+
impls:
21+
- args:
22+
- value: decimal<P,S>
23+
name: x
24+
return: |-
25+
integral_least_num_digits = P - S + 1
26+
precision = min(integral_least_num_digits, 38)
27+
decimal?<precision, 0>
28+
-
29+
name: "round"
30+
description: >
31+
Rounding the value `x` to `s` decimal places.
32+
impls:
33+
- args:
34+
- value: decimal<P,S>
35+
name: x
36+
description: >
37+
Numerical expression to be rounded.
38+
- value: i32
39+
name: s
40+
description: >
41+
Number of decimal places to be rounded to.
42+
43+
When `s` is a positive number, the rounding
44+
is performed to a `s` number of decimal places.
45+
46+
When `s` is a negative number, the rounding is
47+
performed to the left side of the decimal point
48+
as specified by `s`.
49+
50+
The precision of the resultant decimal type is one
51+
more than the precision of the input decimal type to
52+
allow for numbers that round up or down to the next
53+
decimal magnitude.
54+
E.g. `round(9.9, 0)` -> `10.0`.
55+
The scale of the resultant decimal type cannot be
56+
larger than the scale of the input decimal type.
57+
options:
58+
rounding:
59+
description: >
60+
When a boundary is computed to lie somewhere between two values,
61+
and this value cannot be exactly represented, this specifies how
62+
to round it.
63+
64+
- TIE_TO_EVEN: round to nearest value; if exactly halfway, tie
65+
to the even option.
66+
- TIE_AWAY_FROM_ZERO: round to nearest value; if exactly
67+
halfway, tie away from zero.
68+
- TRUNCATE: always round toward zero.
69+
- CEILING: always round toward positive infinity.
70+
- FLOOR: always round toward negative infinity.
71+
- AWAY_FROM_ZERO: round negative values with FLOOR rule, round positive values with CEILING rule
72+
- TIE_DOWN: round ties with FLOOR rule
73+
- TIE_UP: round ties with CEILING rule
74+
- TIE_TOWARDS_ZERO: round ties with TRUNCATE rule
75+
- TIE_TO_ODD: round to nearest value; if exactly halfway, tie
76+
to the odd option.
77+
values: [ TIE_TO_EVEN, TIE_AWAY_FROM_ZERO, TRUNCATE, CEILING, FLOOR,
78+
AWAY_FROM_ZERO, TIE_DOWN, TIE_UP, TIE_TOWARDS_ZERO, TIE_TO_ODD ]
79+
nullability: DECLARED_OUTPUT
80+
return: |-
81+
precision = min(P + 1, 38)
82+
decimal?<precision, S>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### SUBSTRAIT_SCALAR_TEST: v1.0
2+
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
3+
4+
# basic: Basic examples without any special cases
5+
ceil(2.25::dec<3,2>) = 3::dec<2,0>
6+
ceil(-65.5::dec<3,1>) = -65::dec<3,0>
7+
ceil(9.9::dec<2,1>) = 10::dec<2,0>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
### SUBSTRAIT_SCALAR_TEST: v1.0
2+
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
3+
4+
# basic: Basic examples without any special cases
5+
floor(2.25::dec<3,2>) = 2::dec<2,0>
6+
floor(-65.5::dec<3,1>) = -66::dec<3,0>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
### SUBSTRAIT_SCALAR_TEST: v1.0
2+
### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
3+
4+
# basic: Basic examples without any special cases
5+
round(2.0::dec<2,1>, 2::i32) = 2::dec<3,1>
6+
round(2.75::dec<3,2>, 1::i32) = 2.8::dec<4,2>
7+
8+
# negative_rounding: Examples with negative rounding
9+
round(2.0::dec<2,1>, -2::i32) = 0::dec<3,1>
10+
round(123::dec<3,0>, -2::i32) = 100::dec<4,0>
11+
round(8793.5::dec<5,1>, -2::i32) = 8800::dec<6,1>

0 commit comments

Comments
 (0)