Skip to content

Commit a283f02

Browse files
committed
in memory PoC
1 parent 8c72af1 commit a283f02

File tree

8 files changed

+154
-26
lines changed

8 files changed

+154
-26
lines changed

distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Type_Refinements/Column_Refinements.enso

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,46 @@ from Standard.Base import all
44

55
import project.Column.Column
66
import project.Internal.Value_Type_Helpers
7+
import project.Refined_Types.Numeric_Column.Numeric_Column
78
import project.Value_Type.Value_Type
89
from project.Internal.Type_Refinements.Single_Value_Column_Conversions import all
910
from project.Internal.Type_Refinements.Typed_Column_Conversions import all
1011

1112
refine_column (column : Column) =
1213
## We treat a column as single value if it contains a single not-nothing value.
13-
if is_single_value column . not then column else
14-
inferred_value_type = column.inferred_precise_value_type
15-
case inferred_value_type of
16-
Value_Type.Integer _ ->
17-
# `inferred_precise_value_type` will return Integer if the column was Float (or Mixed) but contained integral values - e.g. [2.0]
18-
# We inspect the actual value to correctly deal with both Float and Mixed base type.
19-
value = column.at 0
20-
case value of
21-
# If the value was really a float, we preserve that.
22-
_ : Float -> (column : Column & Numeric_Column & Float)
23-
# Otherwise we treat it as an integer.
24-
_ -> (column : Column & Numeric_Column & Integer)
25-
Value_Type.Float _ -> (column : Column & Numeric_Column & Float)
26-
Value_Type.Char _ _ -> (column : Column & Text)
27-
Value_Type.Boolean -> (column : Column & Boolean)
28-
Value_Type.Date -> (column : Column & Date)
29-
Value_Type.Time -> (column : Column & Time_Of_Day)
30-
Value_Type.Date_Time True -> (column : Column & Date_Time)
31-
Value_Type.Decimal _ _ ->
32-
is_integer = Value_Type_Helpers.is_decimal_integer inferred_value_type
33-
if is_integer then (column : Column & Numeric_Column & Integer) else (column : Column & Numeric_Column & Decimal)
34-
# Other types (e.g. Mixed) are not supported.
35-
_ -> column
14+
if is_single_value column then _refine_single_value_column column else _refine_column column
15+
16+
private _refine_column column =
17+
inferred_value_type = column.inferred_precise_value_type
18+
case inferred_value_type of
19+
Value_Type.Integer _ -> (column : Column & Numeric_Column)
20+
Value_Type.Float _ -> (column : Column & Numeric_Column)
21+
Value_Type.Decimal _ _ -> (column : Column & Numeric_Column)
22+
_ -> column
23+
24+
private _refine_single_value_column column =
25+
inferred_value_type = column.inferred_precise_value_type
26+
case inferred_value_type of
27+
Value_Type.Integer _ ->
28+
# `inferred_precise_value_type` will return Integer if the column was Float (or Mixed) but contained integral values - e.g. [2.0]
29+
# We inspect the actual value to correctly deal with both Float and Mixed base type.
30+
value = column.at 0
31+
case value of
32+
# If the value was really a float, we preserve that.
33+
_ : Float -> (column : Column & Numeric_Column & Float)
34+
# Otherwise we treat it as an integer.
35+
_ -> (column : Column & Numeric_Column & Integer)
36+
Value_Type.Float _ -> (column : Column & Numeric_Column & Float)
37+
Value_Type.Char _ _ -> (column : Column & Text)
38+
Value_Type.Boolean -> (column : Column & Boolean)
39+
Value_Type.Date -> (column : Column & Date)
40+
Value_Type.Time -> (column : Column & Time_Of_Day)
41+
Value_Type.Date_Time True -> (column : Column & Date_Time)
42+
Value_Type.Decimal _ _ ->
43+
is_integer = Value_Type_Helpers.is_decimal_integer inferred_value_type
44+
if is_integer then (column : Column & Numeric_Column & Integer) else (column : Column & Numeric_Column & Decimal)
45+
# Other types (e.g. Mixed) are not supported.
46+
_ -> column
3647

3748
is_single_value column:Column -> Boolean =
3849
(column.length == 1) && (column.at 0 . is_nothing . not)

distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Type_Refinements/Table_Refinements.enso

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ from Standard.Base import all
44

55
import project.Column.Column
66
import project.Internal.Value_Type_Helpers
7+
import project.Refined_Types.Numeric_Column.Numeric_Column
78
import project.Table.Table
89
import project.Value_Type.Value_Type
910
from project.Internal.Type_Refinements.Single_Column_Table_Conversions import all
Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
private
22

3+
from Standard.Base import all
4+
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
5+
6+
import project.Column.Column
7+
import project.Internal.Type_Refinements.Typed_Column_Helpers
8+
import project.Refined_Types.Numeric_Column.Numeric_Column
9+
import project.Value_Type.Value_Type
10+
from project.Column import apply_unary_operation, naming_helper
11+
12+
polyglot java import org.enso.table.data.column.operation.unary.AbsOperation
13+
polyglot java import org.enso.table.data.column.operation.unary.SignumOperation
14+
315
## This conversion is internal and should never be exported.
416
Numeric_Column.from (that : Column) =
5-
...
17+
if that.value_type.is_numeric.not then
18+
Error.throw (Illegal_Argument.Error "Cannot convert a "+that.value_type.to_display_text+" column to a numeric column.")
19+
Typed_Column_Helpers.make_numeric_column that In_Memory_Numeric_Column_Implementation
20+
21+
type In_Memory_Numeric_Column_Implementation
22+
abs column =
23+
Value_Type.expect_numeric column <|
24+
new_name = naming_helper.concat ["abs", naming_helper.to_expression_text column]
25+
apply_unary_operation column AbsOperation.INSTANCE new_name
26+
27+
signum column =
28+
Value_Type.expect_numeric column <|
29+
new_name = naming_helper.concat ["signum", naming_helper.to_expression_text column]
30+
apply_unary_operation column SignumOperation.INSTANCE new_name
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import project.Refined_Types.Numeric_Column.Numeric_Column
2+
3+
## PRIVATE
4+
For internal use only, this function should be used by implementations to
5+
provide a hidden conversion to `Numeric_Column` that allows the type refinement.
6+
make_numeric_column base_column numeric_operations_implementation =
7+
Numeric_Column.Value base_column numeric_operations_implementation

distribution/lib/Standard/Table/0.0.0-dev/src/Main.enso

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export project.Position.Position
4747

4848
export project.Prefix_Name.Prefix_Name
4949

50+
export project.Refined_Types.Numeric_Column.Numeric_Column
51+
5052
export project.Set_Mode.Set_Mode
5153

5254
export project.Simple_Expression.Simple_Calculation
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
1+
## A column that contains numeric values.
12
type Numeric_Column
23
private Value column operations_implementation
34

5+
## GROUP Standard.Base.Operators
6+
ICON operators
7+
Computes the absolute value of each element in the column.
8+
9+
> Example
10+
Compute the absolute value of values in a column.
11+
12+
import Standard.Examples
13+
14+
example_abs = Examples.decimal_column.abs
415
abs self -> Numeric_Column =
5-
"TODO"
16+
self.operations_implementation.abs self.column
17+
18+
## GROUP Standard.Base.Operators
19+
ICON operators
20+
Computes the sign of each element in the column.
21+
22+
It will return -1, 0 or 1 depending on the sign of the value.
23+
24+
> Example
25+
Compute the signum of values in a column.
26+
27+
import Standard.Examples
628

29+
example_signum = Examples.decimal_column.signum
730
signum self -> Numeric_Column =
8-
"TODO"
31+
self.operations_implementation.signum self.column

test/Table_Tests/src/Common_Table_Operations/Main.enso

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import project.Common_Table_Operations.Map_Spec
2929
import project.Common_Table_Operations.Map_To_Table_Spec
3030
import project.Common_Table_Operations.Missing_Values_Spec
3131
import project.Common_Table_Operations.Nothing_Spec
32+
import project.Common_Table_Operations.Numeric_Column_Spec
3233
import project.Common_Table_Operations.Offset_Spec
3334
import project.Common_Table_Operations.Order_By_Spec
3435
import project.Common_Table_Operations.Select_Columns_Spec
@@ -141,6 +142,7 @@ add_specs suite_builder setup =
141142
Map_To_Table_Spec.add_specs suite_builder setup
142143
Missing_Values_Spec.add_specs suite_builder setup
143144
Nothing_Spec.add_specs suite_builder setup
145+
Numeric_Column_Spec.add_specs suite_builder setup
144146
Offset_Spec.add_specs suite_builder setup
145147
Order_By_Spec.add_specs suite_builder setup
146148
Replace_Spec.add_specs suite_builder setup
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from Standard.Base import all
2+
import Standard.Base.Errors.Common.Type_Error
3+
4+
from Standard.Table import all
5+
from Standard.Table.Errors import all
6+
7+
import Standard.Database.Feature.Feature
8+
9+
from Standard.Test import all
10+
11+
import project.Common_Table_Operations.Util
12+
from project.Common_Table_Operations.Util import run_default_backend
13+
14+
type Lazy_Ref
15+
Value ~get
16+
17+
main filter=Nothing = run_default_backend add_specs filter
18+
19+
add_specs suite_builder setup =
20+
if setup.is_feature_supported Feature.Column_Operations then (add_numeric_columns_specs suite_builder setup)
21+
22+
add_numeric_columns_specs suite_builder setup =
23+
prefix = setup.prefix
24+
table_builder = setup.light_table_builder
25+
build_sorted_table = Util.build_sorted_table setup
26+
suite_builder.group prefix+"Numeric_Column" group_builder->
27+
numeric_column = Lazy_Ref.Value <| build_sorted_table [["X", [-10, 0, 1, 12]]] . at "X"
28+
group_builder.specify "a numeric column can be cast to Numeric_Column" <|
29+
column = numeric_column.get
30+
column.value_type.is_numeric . should_be_true
31+
column:Numeric_Column
32+
33+
group_builder.specify "a text column cannot be cast to Numeric_Column" <|
34+
column = table_builder [["X", ["txt"]]] . at "X"
35+
column.value_type.is_numeric . should_be_false
36+
Test.expect_panic Type_Error (column:Numeric_Column)
37+
38+
group_builder.specify "a numeric column supports abs operation" <|
39+
column = numeric_column.get
40+
abs_column = (column:Numeric_Column).abs
41+
abs_column.to_vector . should_equal [10, 0, 1, 12]
42+
43+
group_builder.specify "a numeric column supports signum operation" <|
44+
column = numeric_column.get
45+
signum_column = (column:Numeric_Column).signum
46+
signum_column.to_vector . should_equal [-1, 0, 1, 1]
47+
48+
group_builder.specify "floating-point columns support abs and signum" <|
49+
column = build_sorted_table [["X", [-1.5, 0.0, -0.0, 1.0, 200.25]]] . at "X"
50+
abs_column = (column:Numeric_Column).abs
51+
abs_column.to_vector . should_equal [1.5, 0.0, 0.0, 1.0, 200.25]
52+
signum_column = (column:Numeric_Column).signum
53+
signum_column.to_vector . should_equal [-1, 0, 0, 1, 1]
54+
55+
group_builder.specify "a single value column can also be Numeric_Column" <|
56+
column = table_builder [["X", [1]]] . at "X"
57+
column:Numeric_Column

0 commit comments

Comments
 (0)