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 round, ceil, floor, truncate to the In-Database Column type #6988

Merged
merged 89 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
bbc5cff
one test
GregoryTravis Jun 7, 2023
e6bed7b
function_name
GregoryTravis Jun 7, 2023
347b46e
expression_spec
GregoryTravis Jun 7, 2023
c78560d
gmt test
GregoryTravis Jun 7, 2023
2fa1846
sl
GregoryTravis Jun 7, 2023
8291ce3
Merge branch 'develop' into wip/gmt/6886-truncate
GregoryTravis Jun 7, 2023
b16d9ee
trunc tests
GregoryTravis Jun 8, 2023
be81b60
ceil floor
GregoryTravis Jun 8, 2023
3b486b9
by hand rounding, sqlite parser stack overflow
GregoryTravis Jun 8, 2023
9fe0841
wip
GregoryTravis Jun 8, 2023
f649b73
pg maybe smaller
GregoryTravis Jun 8, 2023
2f68d35
works in sqlite too
GregoryTravis Jun 8, 2023
7f7324b
col math works
GregoryTravis Jun 9, 2023
9c4e0ff
clean up
GregoryTravis Jun 12, 2023
abaab2a
tests, cast to int column
GregoryTravis Jun 12, 2023
e20161a
rounding tests
GregoryTravis Jun 12, 2023
f42285e
round expression spec
GregoryTravis Jun 12, 2023
d802271
int in int out
GregoryTravis Jun 13, 2023
f05f9e3
full col tests
GregoryTravis Jun 13, 2023
ccda6aa
round to float
GregoryTravis Jun 13, 2023
4ff6fa7
dp out of range
GregoryTravis Jun 13, 2023
5b41821
const tests
GregoryTravis Jun 13, 2023
93f4403
rename to const, name test
GregoryTravis Jun 13, 2023
c60d354
nulls
GregoryTravis Jun 13, 2023
a25e3d5
remove pow_flip
GregoryTravis Jun 13, 2023
5283255
make trunc, ceil, floor generic
GregoryTravis Jun 13, 2023
4aed89c
do not restrict const arg
GregoryTravis Jun 14, 2023
50b78eb
Merge branch 'develop' into wip/gmt/6886-truncate
GregoryTravis Jun 14, 2023
fbecfd8
review
GregoryTravis Jun 14, 2023
593982b
nan/inf docs
GregoryTravis Jun 14, 2023
3ff04b5
changelog
GregoryTravis Jun 14, 2023
05fc15e
decimal too
GregoryTravis Jun 14, 2023
3fe8280
restore deleted test, restore integrity check
GregoryTravis Jun 15, 2023
31874a8
const not an op, using make_constant
GregoryTravis Jun 15, 2023
9256930
wip
GregoryTravis Jun 15, 2023
03f3e05
in-mem const
GregoryTravis Jun 15, 2023
78aa29f
share with eval exp
GregoryTravis Jun 15, 2023
92b4d49
factor out dp check
GregoryTravis Jun 15, 2023
8d19564
only test decimal on pg-like
GregoryTravis Jun 15, 2023
91d58b2
column arithmetic for in-mem too
GregoryTravis Jun 15, 2023
ea10375
wip
GregoryTravis Jun 15, 2023
b7b6d3e
symmetric
GregoryTravis Jun 15, 2023
e8dbf9f
symmetric for in-mem
GregoryTravis Jun 16, 2023
218f2e2
symmetric for db
GregoryTravis Jun 16, 2023
570756d
wip
GregoryTravis Jun 16, 2023
afd21ac
integer impl
GregoryTravis Jun 19, 2023
b0c771e
wip
GregoryTravis Jun 19, 2023
bbd7033
col col
GregoryTravis Jun 19, 2023
e891c44
unstable
GregoryTravis Jun 19, 2023
511a627
review
GregoryTravis Jun 19, 2023
9769faf
pg/sl return type
GregoryTravis Jun 20, 2023
41bd417
more type checks for in-mem
GregoryTravis Jun 20, 2023
4d0627b
input check for in-mem round
GregoryTravis Jun 21, 2023
0ad7ef4
use make_function
GregoryTravis Jun 21, 2023
0a350c2
wip
GregoryTravis Jun 21, 2023
d6fe5ce
wrapper
GregoryTravis Jun 22, 2023
395a3b6
round_decimal
GregoryTravis Jun 22, 2023
10fa61c
sl
GregoryTravis Jun 22, 2023
086fb18
round etc return types
GregoryTravis Jun 26, 2023
c6fed25
rename round_with
GregoryTravis Jun 26, 2023
6351dce
cleanup
GregoryTravis Jun 26, 2023
c27b52d
docs
GregoryTravis Jun 26, 2023
314546d
decimal test
GregoryTravis Jun 26, 2023
7fcb5c7
specialize
GregoryTravis Jun 26, 2023
3bac313
remove max_long test
GregoryTravis Jun 26, 2023
05620e4
p flag for dp restriction
GregoryTravis Jun 26, 2023
307f9f0
rs too
GregoryTravis Jun 26, 2023
021a2f4
return type tests
GregoryTravis Jun 26, 2023
6ed5154
bankers
GregoryTravis Jun 26, 2023
519f329
cleanup
GregoryTravis Jun 26, 2023
c6d7974
merge
GregoryTravis Jun 26, 2023
934f974
Merge branch 'develop' into wip/gmt/6886-truncate
GregoryTravis Jun 27, 2023
35fe5b1
literal for dp
GregoryTravis Jun 27, 2023
076172a
changelog chronological
GregoryTravis Jun 27, 2023
3a9b1d7
review
GregoryTravis Jun 27, 2023
819e75f
undo changelog
GregoryTravis Jun 27, 2023
bfce3b7
precision too high
GregoryTravis Jun 27, 2023
e13e178
Merge branch 'develop' into wip/gmt/6886-truncate
GregoryTravis Jun 27, 2023
9d3f548
wip
GregoryTravis Jun 28, 2023
4895366
trunc
GregoryTravis Jun 28, 2023
6342238
DoubleLongMapOpWithSpecialNumericHandling
GregoryTravis Jun 28, 2023
c22364e
wip
GregoryTravis Jun 28, 2023
7b16564
fmt
GregoryTravis Jun 28, 2023
2ca4084
Merge branch 'develop' into wip/gmt/6886-truncate
GregoryTravis Jun 28, 2023
bc6f8fa
precision limit tests
GregoryTravis Jun 29, 2023
9905ac3
fixed
GregoryTravis Jun 29, 2023
74f00d3
cleanup
GregoryTravis Jun 29, 2023
40d2376
epsilon
GregoryTravis Jun 29, 2023
9ff2ef6
another epsilon
GregoryTravis Jun 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,10 @@
- [Speed improvements to `Column` `.truncate`, `.ceil`, and `.floor`.][6941]
- [Implemented addition and subtraction for `Date_Period` and
`Time_Period`.][6956]
- [Implemented `Table.update_database_table`.][7035]
- [Added AWS credential support and initial S3 list buckets API.][6973]
- [Added `round`, `ceil`, `floor`, `truncate` to the In-Database Column type]
[6988]
- [Implemented `Table.update_database_table`.][7035]
- [Removed `module` argument from `enso_project` and other minor tweaks.][7052]
- [Integrated Database write operations with Execution Contexts.][7072]

Expand Down Expand Up @@ -720,6 +722,7 @@
[6941]: https://github.com/enso-org/enso/pull/6941
[6956]: https://github.com/enso-org/enso/pull/6956
[6973]: https://github.com/enso-org/enso/pull/6973
[6988]: https://github.com/enso-org/enso/pull/6988
[7035]: https://github.com/enso-org/enso/pull/7035
[7052]: https://github.com/enso-org/enso/pull/7052
[7072]: https://github.com/enso-org/enso/pull/7072
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ type Redshift_Dialect
supports_separate_nan : Boolean
supports_separate_nan self = True

## PRIVATE
supports_negative_round_decimal_places : Boolean
supports_negative_round_decimal_places self = True

## PRIVATE
rounding_decimal_places_not_allowed_for_floats : Boolean
rounding_decimal_places_not_allowed_for_floats self = True

## PRIVATE
adapt_unified_column : Internal_Column -> Value_Type -> (SQL_Expression -> SQL_Type_Reference) -> Internal_Column
adapt_unified_column self column approximate_result_type infer_result_type_from_database_callback =
Expand Down
55 changes: 7 additions & 48 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import project.Any.Any
import project.Internal.Rounding_Helpers
import project.Data.Text.Text
import project.Data.Locale.Locale
import project.Errors.Common.Arithmetic_Error
Expand Down Expand Up @@ -609,20 +610,20 @@ type Decimal
2.5 . round use_bankers=True == 2
round : Integer -> Boolean -> Integer | Decimal ! Illegal_Argument
round self decimal_places=0 use_bankers=False =
check_decimal_places decimal_places <|
Rounding_Helpers.check_decimal_places decimal_places <|
case self.is_nan || self.is_infinite of
True ->
msg = "round cannot accept " + self.to_text
Error.throw (Arithmetic_Error.Error msg)
False -> check_round_input self <|
False -> Rounding_Helpers.check_round_input self <|
decimal_result =
# Algorithm taken from https://stackoverflow.com/a/7211688
scale = 10 ^ decimal_places
scaled = self * scale
round_base = scaled.floor
round_midpoint = (round_base + 0.5) / scale
even_is_up = if self >= 0 then (scaled.truncate % 2) != 0 else (scaled.truncate % 2) == 0
half_goes_up = if use_bankers then even_is_up else True
half_goes_up = if use_bankers then even_is_up else self >= 0
do_round_up = if half_goes_up then self >= round_midpoint else self > round_midpoint
if do_round_up then ((round_base + 1.0) / scale) else (round_base / scale)
# Convert to integer if it's really an integer anyway.
Expand Down Expand Up @@ -936,19 +937,19 @@ type Integer
## It's already an integer so unless decimal_places is
negative, the value is unchanged.
if decimal_places >= 0 then self else
check_decimal_places decimal_places <| check_round_input self <|
Rounding_Helpers.check_decimal_places decimal_places <| Rounding_Helpers.check_round_input self <|
scale = 10 ^ -decimal_places
halfway = scale.div 2
remainder = self % scale
scaled_down = self.div scale
result_unnudged = scaled_down * scale
case self >= 0 of
True ->
half_goes_up = if use_bankers then (scaled_down % 2) != 0 else True
half_goes_up = if use_bankers then (scaled_down % 2) != 0 else self >= 0
round_up = if half_goes_up then remainder >= halfway else remainder > halfway
if round_up then result_unnudged + scale else result_unnudged
False ->
half_goes_up = if use_bankers then (scaled_down % 2) == 0 else True
half_goes_up = if use_bankers then (scaled_down % 2) == 0 else self >= 0
round_up = if half_goes_up then remainder < -halfway else remainder <= -halfway
if round_up then result_unnudged - scale else result_unnudged

Expand Down Expand Up @@ -1119,45 +1120,3 @@ type Number_Parse_Error
to_display_text : Text
to_display_text =
"Could not parse " + self.text.to_text + " as a double."

## PRIVATE
The smallest allowed value for the `decimal_places` argument to `round`
round_min_decimal_places : Integer
round_min_decimal_places = -15

## PRIVATE
The largest allowed value for the `decimal_places` argument to `round`
round_max_decimal_places : Integer
round_max_decimal_places = 15

## PRIVATE
The largest smallInteger (Long) that integer round can handle. Above 14
digits, it is possible that the underlying long, converted to double in the
rounding process, would lose precision in the least significant bits.
(See https://en.wikipedia.org/wiki/Double-precision_floating-point_format.)
round_max_long : Integer
round_max_long = 99999999999999

## PRIVATE
The largest smallInteger (Long) that integer round can handle. Above 14
digits, it is possible that the underlying long, converted to double in the
rounding process, would lose precision in the least significant bits.
(See https://en.wikipedia.org/wiki/Double-precision_floating-point_format.)
round_min_long : Integer
round_min_long = -99999999999999

## PRIVATE
Restrict rounding decimal_places parameter.
check_decimal_places : Integer -> Any -> Any ! Illegal_Argument
check_decimal_places decimal_places ~action =
if decimal_places >= round_min_decimal_places && decimal_places <= round_max_decimal_places then action else
msg = "round: decimal_places must be between " + round_min_decimal_places.to_text + " and " + round_max_decimal_places.to_text + " (inclusive), but was " + decimal_places.to_text
Error.throw (Illegal_Argument.Error msg)

## PRIVATE
Restrict allowed range of input to rounding methods.
check_round_input : Number -> Function -> Any ! Illegal_Argument
check_round_input n ~action =
if n >= round_min_long && n <= round_max_long then action else
msg = "Error: `round` can only accept values between " + round_min_long.to_text + " and " + round_max_long.to_text + " (inclusive), but was " + n.to_text
Error.throw (Illegal_Argument.Error msg)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import project.Any.Any
import project.Data.Numbers.Number
import project.Data.Numbers.Integer
import project.Error.Error
import project.Errors.Illegal_Argument.Illegal_Argument
import project.Function.Function

## PRIVATE
The largest smallInteger (Long) that integer round can handle. Above 14
digits, it is possible that the underlying long, converted to double in the
rounding process, would lose precision in the least significant bits.
(See https://en.wikipedia.org/wiki/Double-precision_floating-point_format.)
round_max_long : Integer
round_max_long = 99999999999999

## PRIVATE
The largest smallInteger (Long) that integer round can handle. Above 14
digits, it is possible that the underlying long, converted to double in the
rounding process, would lose precision in the least significant bits.
(See https://en.wikipedia.org/wiki/Double-precision_floating-point_format.)
round_min_long : Integer
round_min_long = -99999999999999

## PRIVATE
Restrict allowed range of input to rounding methods.
check_round_input : Number -> Function -> Any ! Illegal_Argument
check_round_input n ~action =
if n >= round_min_long && n <= round_max_long then action else
msg = "Error: `round` can only accept values between " + round_min_long.to_text + " and " + round_max_long.to_text + " (inclusive), but was " + n.to_text
Error.throw (Illegal_Argument.Error msg)

## PRIVATE
The smallest allowed value for the `decimal_places` argument to `round`
round_min_decimal_places : Integer
round_min_decimal_places = -15

## PRIVATE
The largest allowed value for the `decimal_places` argument to `round`
round_max_decimal_places : Integer
round_max_decimal_places = 15

## PRIVATE
Restrict rounding decimal_places parameter.
check_decimal_places : Integer -> Any -> Any ! Illegal_Argument
check_decimal_places decimal_places ~action =
if decimal_places >= round_min_decimal_places && decimal_places <= round_max_decimal_places then action else
msg = "round: decimal_places must be between " + round_min_decimal_places.to_text + " and " + round_max_decimal_places.to_text + " (inclusive), but was " + decimal_places.to_text
Error.throw (Illegal_Argument.Error msg)
2 changes: 2 additions & 0 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import project.Data.Vector.Vector
import project.Error.Error
import project.Errors
import project.Function
import project.Internal.Rounding_Helpers
import project.IO
import project.Math
import project.Meta
Expand Down Expand Up @@ -44,6 +45,7 @@ export project.Data.Text.Text
export project.Data.Vector.Vector
export project.Error.Error
export project.Errors
export project.Internal.Rounding_Helpers
export project.IO
export project.Math
export project.Meta
Expand Down
Loading