mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 08:53:31 +03:00
Expand capabilities of Table.set
and better dropdown support, (#8005)
- Adds the ability to use numbers, date/time and Boolean values as constants in `set`. - `Table.set` can take a `Column_Operation`, allowing for deriving of a new column based on other columns. - Added `Column_Ref` type to refer to a column in `filter`.
This commit is contained in:
parent
a96f2d7aba
commit
fac9e7a420
@ -583,6 +583,8 @@
|
||||
- [Implemented Text.substring to easily select part of a Text field][7913]
|
||||
- [Implemented basic XML support][7947]
|
||||
- [Implemented `Table.lookup_and_replace` for the in-memory backend.][7979]
|
||||
- [Added `Column_Operation` to `Table.set` allowing for more streamlined flow of
|
||||
deriving column values in the GUI.][8005]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -830,6 +832,7 @@
|
||||
[7913]: https://github.com/enso-org/enso/pull/7913
|
||||
[7947]: https://github.com/enso-org/enso/pull/7947
|
||||
[7979]: https://github.com/enso-org/enso/pull/7979
|
||||
[8005]: https://github.com/enso-org/enso/pull/8005
|
||||
|
||||
#### Enso Compiler
|
||||
|
||||
|
@ -13,6 +13,7 @@ import Standard.Table.Internal.Java_Problems
|
||||
import Standard.Table.Internal.Problem_Builder.Problem_Builder
|
||||
import Standard.Table.Internal.Widget_Helpers
|
||||
from Standard.Table import Auto, Data_Formatter, Sort_Column, Value_Type
|
||||
from Standard.Table.Data.Column import default_date_period
|
||||
from Standard.Table.Errors import Conversion_Failure, Floating_Point_Equality, Inexact_Type_Coercion, Invalid_Value_Type
|
||||
from Standard.Table.Internal.Cast_Helpers import check_cast_compatibility
|
||||
|
||||
@ -1385,7 +1386,8 @@ type Column
|
||||
shift each date.
|
||||
- period: The period by which to shift. For `Date` columns it should be a
|
||||
`Date_Period` and for `Time` columns it should be a `Time_Period`. For
|
||||
`Date_Time` columns it can be either.
|
||||
`Date_Time` columns it can be either. It defaults to `Day` where
|
||||
possible and `Hour` for `Time` columns.
|
||||
|
||||
? Time Zone handling
|
||||
|
||||
@ -1395,7 +1397,7 @@ type Column
|
||||
unusual events like DST.
|
||||
@period Date_Time_Helpers.make_period_selector_for_column
|
||||
date_add : (Column | Integer) -> Date_Period | Time_Period -> Column ! Invalid_Value_Type | Illegal_Argument
|
||||
date_add self amount (period : Date_Period | Time_Period) =
|
||||
date_add self amount (period : Date_Period|Time_Period = default_date_period self) =
|
||||
Value_Type.expect_type self .is_date_or_time "date/time" <|
|
||||
my_type = self.inferred_precise_value_type
|
||||
Value_Type.expect_integer amount <|
|
||||
|
@ -11,6 +11,7 @@ import Standard.Base.Errors.Unimplemented.Unimplemented
|
||||
from Standard.Base.Metadata import make_single_choice
|
||||
from Standard.Base.Widget_Helpers import make_delimiter_selector
|
||||
|
||||
import Standard.Table.Data.Calculations.Column_Operation.Column_Operation
|
||||
import Standard.Table.Data.Expression.Expression
|
||||
import Standard.Table.Data.Expression.Expression_Error
|
||||
import Standard.Table.Data.Join_Condition.Join_Condition
|
||||
@ -21,9 +22,11 @@ import Standard.Table.Data.Report_Unmatched.Report_Unmatched
|
||||
import Standard.Table.Data.Row.Row
|
||||
import Standard.Table.Data.Table.Table as Materialized_Table
|
||||
import Standard.Table.Data.Type.Value_Type_Helpers
|
||||
import Standard.Table.Extensions.Table_Ref.Table_Ref
|
||||
import Standard.Table.Internal.Add_Row_Number
|
||||
import Standard.Table.Internal.Aggregate_Column_Helper
|
||||
import Standard.Table.Internal.Column_Naming_Helper.Column_Naming_Helper
|
||||
import Standard.Table.Internal.Constant_Column.Constant_Column
|
||||
import Standard.Table.Internal.Lookup_Helpers
|
||||
import Standard.Table.Internal.Problem_Builder.Problem_Builder
|
||||
import Standard.Table.Internal.Table_Helpers
|
||||
@ -549,6 +552,7 @@ type Table
|
||||
|
||||
people.filter "age" (age -> (age%10 == 0))
|
||||
@column Widget_Helpers.make_column_name_selector
|
||||
@filter Widget_Helpers.make_filter_condition_selector
|
||||
filter : (Column | Text | Integer) -> (Filter_Condition|(Any->Boolean)) -> Problem_Behavior -> Table ! No_Such_Column | Index_Out_Of_Bounds | Invalid_Value_Type
|
||||
filter self column (filter : Filter_Condition | Function = Filter_Condition.Equal True) on_problems=Report_Warning = case column of
|
||||
_ : Column ->
|
||||
@ -560,7 +564,9 @@ type Table
|
||||
new_ctx = self.context.set_where_filters new_filters
|
||||
self.updated_context new_ctx
|
||||
case filter of
|
||||
_ : Filter_Condition -> mask (make_filter_column column filter on_problems)
|
||||
_ : Filter_Condition ->
|
||||
resolved = (self:Table_Ref).resolve_condition filter
|
||||
mask (make_filter_column column resolved on_problems)
|
||||
## We check the `filter` predicate before reporting unsupported
|
||||
operation, because it may just be a Filter_Condition with
|
||||
missing arguments and then another error is more appropriate.
|
||||
@ -825,22 +831,22 @@ type Table
|
||||
table.set double_inventory new_name="total_stock"
|
||||
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
||||
@new_name Widget_Helpers.make_column_name_selector
|
||||
set : Column | Text | Array | Vector | Range | Date_Range -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||
set self column new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||
set : Column | Text | Array | Vector | Range | Date_Range | Constant_Column | Column_Operation -> Text -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||
set self column new_name="" set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||
resolved = case column of
|
||||
_ : Text -> self.evaluate_expression column on_problems
|
||||
_ : Column ->
|
||||
if Helpers.check_integrity self column then column else
|
||||
Error.throw (Integrity_Error.Error "Column "+column.name)
|
||||
_ : Constant_Column -> self.make_constant_column column
|
||||
_ : Column_Operation -> column.evaluate self (set_mode==Set_Mode.Update && new_name=="") on_problems
|
||||
_ : Vector -> Error.throw (Unsupported_Database_Operation.Error "Cannot use `Vector` for `set` in the database.")
|
||||
_ : Array -> Error.throw (Unsupported_Database_Operation.Error "Cannot use `Array` for `set` in the database.")
|
||||
_ : Range -> Error.throw (Unsupported_Database_Operation.Error "Cannot use `Range` for `set` in the database.")
|
||||
_ : Date_Range -> Error.throw (Unsupported_Database_Operation.Error "Cannot use `Date_Range` for `set` in the database.")
|
||||
_ -> Error.throw (Illegal_Argument.Error "Unsupported type for `Table.set`.")
|
||||
renamed = case new_name of
|
||||
Nothing -> resolved
|
||||
_ : Text -> resolved.rename new_name
|
||||
|
||||
renamed = if new_name == "" then resolved else resolved.rename new_name
|
||||
renamed.if_not_error <| self.column_naming_helper.check_ambiguity self.column_names new_name <|
|
||||
index = self.internal_columns.index_of (c -> c.name == renamed.name)
|
||||
check_add = case set_mode of
|
||||
@ -2486,3 +2492,6 @@ default_join_condition table join_kind = case join_kind of
|
||||
Materialized_Table.from (that:Table) =
|
||||
_ = [that]
|
||||
Error.throw (Illegal_Argument.Error "Currently cross-backend operations are not supported. Materialize the table using `.read` before mixing it with an in-memory Table.")
|
||||
|
||||
## PRIVATE
|
||||
Table_Ref.from (that:Table) = Table_Ref.Value that
|
||||
|
@ -10,10 +10,10 @@ import project.Connection.SSL_Mode.SSL_Mode
|
||||
import project.Data.Column_Description.Column_Description
|
||||
import project.Data.SQL_Query.SQL_Query
|
||||
import project.Data.Update_Action.Update_Action
|
||||
import project.Extensions.Upload_Database_Table
|
||||
import project.Extensions.Upload_In_Memory_Table
|
||||
from project.Connection.Postgres_Details.Postgres_Details import Postgres
|
||||
from project.Connection.SQLite_Details.SQLite_Details import SQLite
|
||||
from project.Extensions.Upload_Database_Table import all
|
||||
from project.Extensions.Upload_In_Memory_Table import all
|
||||
|
||||
export project.Connection.Client_Certificate.Client_Certificate
|
||||
export project.Connection.Connection_Options.Connection_Options
|
||||
@ -27,7 +27,7 @@ export project.Connection.SSL_Mode.SSL_Mode
|
||||
export project.Data.Column_Description.Column_Description
|
||||
export project.Data.SQL_Query.SQL_Query
|
||||
export project.Data.Update_Action.Update_Action
|
||||
export project.Extensions.Upload_Database_Table
|
||||
export project.Extensions.Upload_In_Memory_Table
|
||||
from project.Connection.Postgres_Details.Postgres_Details export Postgres
|
||||
from project.Connection.SQLite_Details.SQLite_Details export SQLite
|
||||
from project.Extensions.Upload_Database_Table export all
|
||||
from project.Extensions.Upload_In_Memory_Table export all
|
||||
|
@ -0,0 +1,151 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Metadata.Display
|
||||
import Standard.Base.Metadata.Widget
|
||||
from Standard.Base.Metadata.Choice import Option
|
||||
from Standard.Base.Metadata.Widget import Single_Choice
|
||||
|
||||
import project.Data.Column_Ref.Column_Ref
|
||||
import project.Extensions.Table_Ref.Table_Ref
|
||||
import project.Internal.Widget_Helpers
|
||||
from project.Internal.Filter_Condition_Helpers import make_filter_column
|
||||
|
||||
## Defines a column operation generally acting on each row producing a new
|
||||
column.
|
||||
type Column_Operation
|
||||
## Add two values/columns.
|
||||
Add (input : Column_Ref|Number|Text) (rhs : Column_Ref|Number|Text)
|
||||
|
||||
## Subtract two values/columns.
|
||||
Subtract (input : Column_Ref|Number) (rhs : Column_Ref|Number)
|
||||
|
||||
## Multiply two values/columns.
|
||||
Multiply (input : Column_Ref|Number) (rhs : Column_Ref|Number)
|
||||
|
||||
## Divide a fixed value or column by another value or column.
|
||||
Divide (input : Column_Ref|Number) (rhs : Column_Ref|Number)
|
||||
|
||||
## Compute the remainder of a fixed value or column divided by another
|
||||
value or column.
|
||||
Mod (input : Column_Ref|Number) (rhs : Column_Ref|Number)
|
||||
|
||||
## Raise a fixed value or column to the power of another value or column.
|
||||
Power (input : Column_Ref|Number) (rhs : Column_Ref|Number)
|
||||
|
||||
## Rounds values in the column to the specified precision.
|
||||
Round (input : Column_Ref|Number) (precision:Integer = 0) (use_bankers:Boolean = False)
|
||||
|
||||
## Rounds values in the column up to the nearest integer.
|
||||
Ceil (input : Column_Ref|Number)
|
||||
|
||||
## Rounds values in the column down to the nearest integer.
|
||||
Floor (input : Column_Ref|Number)
|
||||
|
||||
## Truncates the fractional part of values in the column.
|
||||
If a Date_Time, returns the Date.
|
||||
Truncate (input : Column_Ref|Number|Date_Time)
|
||||
|
||||
## Returns the minimum value of two columns.
|
||||
Min (input : Column_Ref|Any) (rhs : Column_Ref|Any)
|
||||
|
||||
## Returns the maximum value of two columns.
|
||||
Max (input : Column_Ref|Any) (rhs : Column_Ref|Any)
|
||||
|
||||
## Adds a period to a date/time column.
|
||||
Date_Add (input : Column_Ref|Date_Time|Date|Time_Of_Day) (length : Column_Ref|Integer) (period : Date_Period|Time_Period = Date_Period.Day)
|
||||
|
||||
## Returns part of a date/time column.
|
||||
Date_Part (input : Column_Ref|Date_Time|Date|Time_Of_Day) (period : Date_Period|Time_Period)
|
||||
|
||||
## Returns the difference between two date/time columns.
|
||||
Date_Diff (input : Column_Ref|Date_Time|Date|Time_Of_Day) (end : Column_Ref|Date_Time|Date|Time_Of_Day) (period:Date_Period|Time_Period = Date_Period.Day)
|
||||
|
||||
## Negate a boolean column.
|
||||
Not (input : Column_Ref|Boolean)
|
||||
|
||||
## Boolean AND on two boolean columns.
|
||||
And (input : Column_Ref|Boolean) (rhs : Column_Ref|Boolean)
|
||||
|
||||
## Boolean OR on two boolean columns.
|
||||
Or (input : Column_Ref|Boolean) (rhs : Column_Ref|Boolean)
|
||||
|
||||
## If input meets a condition return true value, otherwise false value.
|
||||
|
||||
The `true_value` and `false_value` can be either a constant or a column.
|
||||
If (input : Column_Ref|Any) (condition:Filter_Condition) (true_value:Column_Ref|Any = True) (false_value:Column_Ref|Any = False)
|
||||
|
||||
## Removes the specified characters, by default any whitespace, from the
|
||||
start, the end, or both ends of the input.
|
||||
Trim (input : Column_Ref|Text) (where:Location = Location.Both) (what:Text|Column_Ref = "")
|
||||
|
||||
## PRIVATE
|
||||
Interprets the `Column_Operation` as operation on columns of a provided
|
||||
table, resolving the column references.
|
||||
It creates a new column instance which can be added to the table.
|
||||
evaluate : Table_Ref -> Boolean -> Problem_Behavior -> Any
|
||||
evaluate self table:Table_Ref use_input_name:Boolean on_problems:Problem_Behavior =
|
||||
input_column = table.resolve_as_column self.input
|
||||
derived = case self of
|
||||
Column_Operation.Add _ rhs -> input_column + (table.resolve rhs)
|
||||
Column_Operation.Subtract _ rhs -> input_column - (table.resolve rhs)
|
||||
Column_Operation.Multiply _ rhs -> input_column * (table.resolve rhs)
|
||||
Column_Operation.Divide _ rhs -> input_column / (table.resolve rhs)
|
||||
Column_Operation.Mod _ rhs -> input_column % (table.resolve rhs)
|
||||
Column_Operation.Power _ rhs -> input_column ^ (table.resolve rhs)
|
||||
|
||||
Column_Operation.Round _ precision use_bankers ->
|
||||
input_column.round precision use_bankers
|
||||
Column_Operation.Ceil _ -> input_column.ceil
|
||||
Column_Operation.Floor _ -> input_column.floor
|
||||
Column_Operation.Truncate _ -> input_column.truncate
|
||||
|
||||
Column_Operation.Min _ rhs -> input_column.min (table.resolve rhs)
|
||||
Column_Operation.Max _ rhs -> input_column.max (table.resolve rhs)
|
||||
|
||||
Column_Operation.Date_Add _ length period ->
|
||||
input_column.date_add (table.resolve length) period
|
||||
Column_Operation.Date_Part _ period ->
|
||||
input_column.date_part period
|
||||
Column_Operation.Date_Diff _ end period ->
|
||||
input_column.date_diff (table.resolve end) period
|
||||
|
||||
Column_Operation.Not _ -> input_column.not
|
||||
Column_Operation.And _ rhs -> input_column && (table.resolve rhs)
|
||||
Column_Operation.Or _ rhs -> input_column || (table.resolve rhs)
|
||||
|
||||
Column_Operation.If _ condition true_value false_value ->
|
||||
condition_column = make_filter_column input_column (table.resolve_condition condition) on_problems
|
||||
condition_column.iif (table.resolve true_value) (table.resolve false_value)
|
||||
|
||||
Column_Operation.Trim _ where what ->
|
||||
input_column.trim where (table.resolve what)
|
||||
if use_input_name then derived.rename input_column.name else derived
|
||||
|
||||
## PRIVATE
|
||||
Create a widget for operation
|
||||
default_widget : Table_Ref -> Widget
|
||||
default_widget table:Table_Ref display=Display.Always =
|
||||
col_refs = Widget_Helpers.make_column_ref_by_name_selector table
|
||||
filter_cond = Widget_Helpers.make_filter_condition_selector table
|
||||
builder = Vector.new_builder
|
||||
fqn = Meta.get_qualified_type_name Column_Operation
|
||||
builder.append (Option "add" fqn+".Add" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "subtract" fqn+".Subtract" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "multiply" fqn+".Multiply" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "divide" fqn+".Divide" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "mod" fqn+".Mod" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "power" fqn+".Power" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "round" fqn+".Round" [["input", col_refs]])
|
||||
builder.append (Option "ceil" fqn+".Ceil" [["input", col_refs]])
|
||||
builder.append (Option "floor" fqn+".Floor" [["input", col_refs]])
|
||||
builder.append (Option "truncate" fqn+".Truncate" [["input", col_refs]])
|
||||
builder.append (Option "min" fqn+".Min" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "max" fqn+".Max" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "date add" fqn+".Date_Add" [["input", col_refs], ["length", col_refs]])
|
||||
builder.append (Option "date part" fqn+".Date_Part" [["input", col_refs]])
|
||||
builder.append (Option "date diff" fqn+".Date_Diff" [["start", col_refs], ["end", col_refs]])
|
||||
builder.append (Option "not" fqn+".Not" [["input", col_refs]])
|
||||
builder.append (Option "and" fqn+".And" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "or" fqn+".Or" [["input", col_refs], ["rhs", col_refs]])
|
||||
builder.append (Option "if" fqn+".If" [["input", col_refs], ["condition", filter_cond], ["true_value", col_refs], ["false_value", col_refs]])
|
||||
builder.append (Option "trim" fqn+".Trim" [["input", col_refs], ["what", col_refs]])
|
||||
Single_Choice builder.to_vector display=display
|
@ -1463,7 +1463,8 @@ type Column
|
||||
shift each date.
|
||||
- period: The period by which to shift. For `Date` columns it should be a
|
||||
`Date_Period` and for `Time` columns it should be a `Time_Period`. For
|
||||
`Date_Time` columns it can be either.
|
||||
`Date_Time` columns it can be either. It defaults to `Day` where
|
||||
possible and `Hour` for `Time` columns.
|
||||
|
||||
? Time Zone handling
|
||||
|
||||
@ -1473,7 +1474,7 @@ type Column
|
||||
unusual events like DST.
|
||||
@period Date_Time_Helpers.make_period_selector_for_column
|
||||
date_add : (Column | Integer) -> Date_Period | Time_Period -> Column ! Invalid_Value_Type | Illegal_Argument
|
||||
date_add self amount (period : Date_Period | Time_Period) =
|
||||
date_add self amount (period : Date_Period|Time_Period = default_date_period self) =
|
||||
Value_Type.expect_type self .is_date_or_time "date/time" <|
|
||||
my_type = self.inferred_precise_value_type
|
||||
Value_Type.expect_integer amount <|
|
||||
@ -2529,6 +2530,10 @@ cast_if_needed column value_type = if column.value_type == value_type then colum
|
||||
naming_helper : Column_Naming_Helper
|
||||
naming_helper = Column_Naming_Helper.in_memory
|
||||
|
||||
## PRIVATE
|
||||
Resolves the default date period for `date_add` depending on the source column value type.
|
||||
default_date_period column = if column.value_type.has_date then Date_Period.Day else Time_Period.Hour
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Column from a Vector.
|
||||
Column.from (that:Vector) (name:Text="Vector") = Column.from_vector name that
|
||||
|
@ -0,0 +1,9 @@
|
||||
from Standard.Base import all
|
||||
|
||||
## Reference to a column in a table.
|
||||
type Column_Ref
|
||||
## Reference to a column by name in a table.
|
||||
Name name:Text
|
||||
|
||||
## Reference to a column by index in a table.
|
||||
Index index:Integer
|
@ -14,6 +14,7 @@ from Standard.Base.Metadata import make_single_choice
|
||||
from Standard.Base.Widget_Helpers import make_delimiter_selector
|
||||
|
||||
import project.Data.Aggregate_Column.Aggregate_Column
|
||||
import project.Data.Calculations.Column_Operation.Column_Operation
|
||||
import project.Data.Column as Column_Module
|
||||
import project.Data.Column.Column
|
||||
import project.Data.Data_Formatter.Data_Formatter
|
||||
@ -28,11 +29,12 @@ import project.Data.Report_Unmatched.Report_Unmatched
|
||||
import project.Data.Row.Row
|
||||
import project.Data.Set_Mode.Set_Mode
|
||||
import project.Data.Sort_Column.Sort_Column
|
||||
import project.Data.Table_Conversions
|
||||
import project.Delimited.Delimited_Format.Delimited_Format
|
||||
import project.Extensions.Table_Ref.Table_Ref
|
||||
import project.Internal.Add_Row_Number
|
||||
import project.Internal.Aggregate_Column_Helper
|
||||
import project.Internal.Column_Naming_Helper.Column_Naming_Helper
|
||||
import project.Internal.Constant_Column.Constant_Column
|
||||
import project.Internal.Delimited_Reader
|
||||
import project.Internal.Delimited_Writer
|
||||
import project.Internal.Expand_Objects_Helpers
|
||||
@ -49,6 +51,7 @@ import project.Internal.Widget_Helpers
|
||||
from project.Data.Column import get_item_string, normalize_string_for_display
|
||||
from project.Data.Type.Value_Type import Auto, Value_Type
|
||||
from project.Errors import all
|
||||
from project.Extensions.Table_Conversions import all
|
||||
from project.Internal.Filter_Condition_Helpers import make_filter_column
|
||||
from project.Internal.Lookup_Helpers import make_java_lookup_column_description
|
||||
from project.Internal.Rows_View import Rows_View
|
||||
@ -1235,12 +1238,15 @@ type Table
|
||||
|
||||
people.filter "age" (age -> (age%10 == 0))
|
||||
@column Widget_Helpers.make_column_name_selector
|
||||
@filter Widget_Helpers.make_filter_condition_selector
|
||||
filter : (Column | Text | Integer) -> (Filter_Condition|(Any->Boolean)) -> Problem_Behavior -> Table ! No_Such_Column | Index_Out_Of_Bounds | Invalid_Value_Type
|
||||
filter self column (filter : Filter_Condition | Function = Filter_Condition.Equal True) on_problems=Report_Warning = case column of
|
||||
_ : Column ->
|
||||
mask filter_column = Table.Value (self.java_table.mask filter_column.java_column)
|
||||
case filter of
|
||||
_ : Filter_Condition -> mask (make_filter_column column filter on_problems)
|
||||
_ : Filter_Condition ->
|
||||
resolved = (self:Table_Ref).resolve_condition filter
|
||||
mask (make_filter_column column resolved on_problems)
|
||||
_ : Function -> Filter_Condition_Module.handle_constructor_missing_arguments filter <|
|
||||
mask (column.map filter)
|
||||
_ ->
|
||||
@ -1429,17 +1435,17 @@ type Table
|
||||
double_inventory = table.at "total_stock" * 2
|
||||
table.set double_inventory new_name="total_stock"
|
||||
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
||||
@new_name Widget_Helpers.make_column_name_selector
|
||||
set : Text | Column -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||
set self column:(Text | Column) new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||
@column Column_Operation.default_widget
|
||||
set : Text | Column -> Text -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||
set self column:(Text | Column | Constant_Column | Column_Operation) new_name="" set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||
resolved = case column of
|
||||
_ : Text -> self.evaluate_expression column on_problems
|
||||
_ : Column -> column
|
||||
_ : Constant_Column -> self.make_constant_column column.value
|
||||
_ : Column_Operation -> column.evaluate self (set_mode==Set_Mode.Update && new_name=="") on_problems
|
||||
_ -> Error.throw (Illegal_Argument.Error "Unsupported type for `Table.set`.")
|
||||
|
||||
renamed = case new_name of
|
||||
Nothing -> resolved
|
||||
_ : Text -> resolved.rename new_name
|
||||
renamed = if new_name == "" then resolved else resolved.rename new_name
|
||||
renamed.if_not_error <| self.column_naming_helper.check_ambiguity self.column_names new_name <|
|
||||
check_add_mode = case set_mode of
|
||||
Set_Mode.Add_Or_Update -> True
|
||||
|
@ -4,6 +4,7 @@ import Standard.Base.Errors.Common.Index_Out_Of_Bounds
|
||||
import Standard.Base.Errors.Common.Type_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Errors.Unimplemented.Unimplemented
|
||||
from Standard.Base.Metadata import make_single_choice
|
||||
|
||||
import project.Data.Match_Columns.Match_Columns
|
||||
import project.Data.Table.Table
|
@ -0,0 +1,90 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.Common.Index_Out_Of_Bounds
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
|
||||
import project.Data.Column_Ref.Column_Ref
|
||||
import project.Data.Expression.Expression_Error
|
||||
import project.Data.Set_Mode.Set_Mode
|
||||
import project.Data.Table.Table
|
||||
from project.Errors import No_Such_Column, Existing_Column, Missing_Column
|
||||
|
||||
|
||||
## PRIVATE
|
||||
A helper type allowing to resolve column references in a context of an underlying table.
|
||||
type Table_Ref
|
||||
## PRIVATE
|
||||
Value underlying
|
||||
|
||||
## PRIVATE
|
||||
Get a column.
|
||||
Column must implement all the expected calculations.
|
||||
This returns a Column, but the type is not known statically because it
|
||||
may be an in-memory or Database column.
|
||||
at : Text | Integer -> Any ! No_Such_Column | Index_Out_Of_Bounds
|
||||
at self selector=0 = self.underlying.at selector
|
||||
|
||||
## PRIVATE
|
||||
Resolve a Column_Ref to a Column, keeping any other values as-is.
|
||||
resolve : Any -> Any ! No_Such_Column | Index_Out_Of_Bounds
|
||||
resolve self value = case value of
|
||||
Column_Ref.Name name -> self.at name
|
||||
Column_Ref.Index index -> self.at index
|
||||
_ -> value
|
||||
|
||||
## PRIVATE
|
||||
Resolve a Column_Ref to a Column, converting any other values into
|
||||
a constant column.
|
||||
resolve_as_column : Any -> Any ! No_Such_Column | Index_Out_Of_Bounds
|
||||
resolve_as_column self value = case value of
|
||||
Column_Ref.Name name -> self.at name
|
||||
Column_Ref.Index index -> self.at index
|
||||
_ -> self.underlying.make_constant_column value
|
||||
|
||||
## PRIVATE
|
||||
Transforms a condition, changing any Column_Ref instances into Column instances resolved in this table.
|
||||
resolve_condition : Filter_Condition -> Filter_Condition
|
||||
resolve_condition self condition = case condition of
|
||||
Filter_Condition.Equal value -> Filter_Condition.Equal (self.resolve value)
|
||||
Filter_Condition.Not_Equal value -> Filter_Condition.Not_Equal (self.resolve value)
|
||||
Filter_Condition.Less value -> Filter_Condition.Less (self.resolve value)
|
||||
Filter_Condition.Equal_Or_Less value -> Filter_Condition.Equal_Or_Less (self.resolve value)
|
||||
Filter_Condition.Greater value -> Filter_Condition.Greater (self.resolve value)
|
||||
Filter_Condition.Equal_Or_Greater value -> Filter_Condition.Equal_Or_Greater (self.resolve value)
|
||||
Filter_Condition.Between lower upper -> Filter_Condition.Between (self.resolve lower) (self.resolve upper)
|
||||
Filter_Condition.Starts_With prefix case_sensitivity -> Filter_Condition.Starts_With (self.resolve prefix) case_sensitivity
|
||||
Filter_Condition.Ends_With prefix case_sensitivity -> Filter_Condition.Ends_With (self.resolve prefix) case_sensitivity
|
||||
Filter_Condition.Contains prefix case_sensitivity -> Filter_Condition.Contains (self.resolve prefix) case_sensitivity
|
||||
Filter_Condition.Not_Contains prefix case_sensitivity -> Filter_Condition.Not_Contains (self.resolve prefix) case_sensitivity
|
||||
Filter_Condition.Like pattern -> Filter_Condition.Like (self.resolve pattern)
|
||||
Filter_Condition.Not_Like pattern -> Filter_Condition.Not_Like (self.resolve pattern)
|
||||
Filter_Condition.Is_In values -> Filter_Condition.Is_In (check_is_in_values "Is_In" values)
|
||||
Filter_Condition.Not_In values -> Filter_Condition.Not_In (check_is_in_values "Not_In" values)
|
||||
_ -> condition
|
||||
|
||||
## PRIVATE
|
||||
Set a column.
|
||||
set : Any -> Set_Mode -> Problem_Behavior -> Table_Ref ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||
set self column new_name set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||
new_underlying = self.underlying.set column new_name set_mode=set_mode on_problems=on_problems
|
||||
Table_Ref.from new_underlying
|
||||
|
||||
## PRIVATE
|
||||
Gets a list of column names
|
||||
column_names : Vector Text
|
||||
column_names self = self.underlying.column_names
|
||||
|
||||
## PRIVATE
|
||||
Table_Ref.from (that:Table) = Table_Ref.Value that
|
||||
|
||||
## PRIVATE
|
||||
check_is_in_values : Text -> Vector -> Vector ! Illegal_Argument
|
||||
check_is_in_values operation_name values =
|
||||
check_value v = case v of
|
||||
_ : Column_Ref ->
|
||||
message = "Column_Ref is not allowed in "+operation_name+" to avoid unexpected behavior. As opposed to other operations, which operate on a row-by-row basis when passed a column, "+operation_name+" looks at the whole contents of the passed collection - thus usually expecting a Vector. If you want to filter the elements checking if they are present _anywhere_ in a passed column, you can pass a column by first getting it from the table using the `at` operator."
|
||||
Error.throw (Illegal_Argument.Error message)
|
||||
_ -> v
|
||||
case values of
|
||||
_ : Vector -> values.map check_value
|
||||
_ : Array -> values.map check_value
|
||||
_ -> check_value values
|
@ -0,0 +1,25 @@
|
||||
from Standard.Base import all
|
||||
|
||||
## PRIVATE
|
||||
type Constant_Column
|
||||
Value value:Any
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Table from a Number.
|
||||
Constant_Column.from (that:Number) = Constant_Column.Value that
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Table from a Date_Time.
|
||||
Constant_Column.from (that:Date_Time) = Constant_Column.Value that
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Table from a Date.
|
||||
Constant_Column.from (that:Date) = Constant_Column.Value that
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Table from a Time_Of_Day.
|
||||
Constant_Column.from (that:Time_Of_Day) = Constant_Column.Value that
|
||||
|
||||
## PRIVATE
|
||||
Conversion method to a Table from a Boolean.
|
||||
Constant_Column.from (that:Boolean) = Constant_Column.Value that
|
@ -8,10 +8,10 @@ from Standard.Base.System.File_Format import format_types
|
||||
import project.Data.Aggregate_Column.Aggregate_Column
|
||||
import project.Data.Join_Condition.Join_Condition
|
||||
import project.Data.Table.Table
|
||||
import project.Data.Table_Conversions
|
||||
import project.Data.Type.Value_Type.Auto
|
||||
import project.Data.Type.Value_Type.Value_Type
|
||||
import project.Internal.Parse_Values_Helper
|
||||
from project.Extensions.Table_Conversions import all
|
||||
|
||||
## PRIVATE
|
||||
Make an aggregate column selector.
|
||||
@ -80,6 +80,43 @@ make_column_name_vector_selector table display=Display.Always =
|
||||
item_editor = make_column_name_selector table display=Display.Always
|
||||
Vector_Editor item_editor=item_editor item_default=item_editor.values.first.value display=display
|
||||
|
||||
## PRIVATE
|
||||
Make a column reference by name selector.
|
||||
make_column_ref_by_name_selector : Table -> Display -> Widget
|
||||
make_column_ref_by_name_selector table display=Display.Always =
|
||||
col_names_options = table.column_names.map (name -> Option name "(Column_Ref.Name "+name.pretty+")")
|
||||
Single_Choice values=col_names_options display=display
|
||||
|
||||
## PRIVATE
|
||||
Make a filter condition selector.
|
||||
make_filter_condition_selector : Table -> Display -> Widget
|
||||
make_filter_condition_selector table display=Display.Always =
|
||||
col_names = make_column_ref_by_name_selector table
|
||||
builder = Vector.new_builder
|
||||
fqn = Meta.get_qualified_type_name Filter_Condition
|
||||
builder.append (Option "Equals" fqn+".Equal" [["to", col_names]])
|
||||
builder.append (Option "Not Equals" fqn+".Not_Equal" [["to", col_names]])
|
||||
builder.append (Option "Less Than" fqn+".Less" [["than", col_names]])
|
||||
builder.append (Option "Less Than Or Equal" fqn+".Equal_Or_Less" [["than", col_names]])
|
||||
builder.append (Option "Greater Than" fqn+".Greater" [["than", col_names]])
|
||||
builder.append (Option "Greater Than Or Equal" fqn+".Greater_Or_Less" [["than", col_names]])
|
||||
builder.append (Option "Between" fqn+".Between" [["lower", col_names], ["upper", col_names]])
|
||||
builder.append (Option "Starts With" fqn+".Starts_With" [["prefix", col_names]])
|
||||
builder.append (Option "Ends With" fqn+".Ends_With" [["suffix", col_names]])
|
||||
builder.append (Option "Contains" fqn+".Contains" [["substring", col_names]])
|
||||
builder.append (Option "Not Contains" fqn+".Not_Contains" [["substring", col_names]])
|
||||
builder.append (Option "Is Nothing" fqn+".Is_Nothing")
|
||||
builder.append (Option "Is Not Nothing" fqn+".Not_Nothing")
|
||||
builder.append (Option "Is True" fqn+".Is_True")
|
||||
builder.append (Option "Is False" fqn+".Is_False")
|
||||
builder.append (Option "Is Empty" fqn+".Is_Empty")
|
||||
builder.append (Option "Is Not Empty" fqn+".Not_Empty")
|
||||
builder.append (Option "Like" fqn+".Like" [["pattern", col_names]])
|
||||
builder.append (Option "Not Like" fqn+".Not_Like" [["pattern", col_names]])
|
||||
builder.append (Option "Is In" fqn+".Is_In")
|
||||
builder.append (Option "Not In" fqn+".Not_In")
|
||||
Single_Choice builder.to_vector display=display
|
||||
|
||||
## PRIVATE
|
||||
Make a join condition selector.
|
||||
make_join_condition_selector : Table -> Display -> Widget
|
||||
|
@ -1,7 +1,9 @@
|
||||
from Standard.Base import all
|
||||
|
||||
import project.Data.Aggregate_Column.Aggregate_Column
|
||||
import project.Data.Calculations.Column_Operation.Column_Operation
|
||||
import project.Data.Column.Column
|
||||
import project.Data.Column_Ref.Column_Ref
|
||||
import project.Data.Column_Vector_Extensions
|
||||
import project.Data.Data_Formatter.Data_Formatter
|
||||
import project.Data.Join_Condition.Join_Condition
|
||||
@ -12,7 +14,6 @@ import project.Data.Report_Unmatched.Report_Unmatched
|
||||
import project.Data.Set_Mode.Set_Mode
|
||||
import project.Data.Sort_Column.Sort_Column
|
||||
import project.Data.Table.Table
|
||||
import project.Data.Table_Conversions
|
||||
import project.Data.Type.Value_Type.Auto
|
||||
import project.Data.Type.Value_Type.Value_Type
|
||||
import project.Delimited.Delimited_Format.Delimited_Format
|
||||
@ -24,9 +25,12 @@ import project.Excel.Excel_Workbook.Excel_Workbook
|
||||
from project.Delimited.Delimited_Format.Delimited_Format import Delimited
|
||||
from project.Excel.Excel_Format.Excel_Format import Excel
|
||||
from project.Excel.Excel_Section.Excel_Section import Cell_Range, Range_Names, Sheet_Names, Worksheet
|
||||
from project.Extensions.Table_Conversions import all
|
||||
|
||||
export project.Data.Aggregate_Column.Aggregate_Column
|
||||
export project.Data.Calculations.Column_Operation.Column_Operation
|
||||
export project.Data.Column.Column
|
||||
export project.Data.Column_Ref.Column_Ref
|
||||
export project.Data.Column_Vector_Extensions
|
||||
export project.Data.Data_Formatter.Data_Formatter
|
||||
export project.Data.Join_Condition.Join_Condition
|
||||
@ -45,7 +49,7 @@ export project.Excel.Excel_Format.Excel_Format
|
||||
export project.Excel.Excel_Range.Excel_Range
|
||||
export project.Excel.Excel_Section.Excel_Section
|
||||
export project.Excel.Excel_Workbook.Excel_Workbook
|
||||
from project.Data.Table_Conversions export all
|
||||
from project.Delimited.Delimited_Format.Delimited_Format export Delimited
|
||||
from project.Excel.Excel_Format.Excel_Format export Excel
|
||||
from project.Excel.Excel_Section.Excel_Section export Cell_Range, Range_Names, Sheet_Names, Worksheet
|
||||
from project.Extensions.Table_Conversions export all
|
||||
|
@ -108,6 +108,29 @@ type Test
|
||||
if err.is_a matcher then Nothing else
|
||||
Test.fail ("Expected a " + matcher.to_text + ", but " + err.to_text + " was thrown instead.")
|
||||
|
||||
## Expect a function to fail with the provided panic.
|
||||
|
||||
An alternative API to `expect_panic_with` where the order of arguments is
|
||||
more natural - as it allows blocks without reordering the arguments.
|
||||
|
||||
Arguments:
|
||||
- matcher: The expected type of the panic thrown by `action`.
|
||||
- action: The action to evaluate that is expected to fail with a panic.
|
||||
|
||||
> Example
|
||||
Expect that a computation should panic as part of a test.
|
||||
|
||||
import Standard.Examples
|
||||
from Standard.Test import Test
|
||||
|
||||
example_expect_panic_with =
|
||||
Test.expect_panic_with Examples.My_Error <|
|
||||
IO.println 'hello'
|
||||
Examples.throw_panic
|
||||
IO.println 'this is not reached'
|
||||
expect_panic : Any -> Any -> Test_Result
|
||||
expect_panic matcher ~action = Test.expect_panic_with action matcher
|
||||
|
||||
|
||||
## Checks that the provided action returns without any errors or warnings.
|
||||
|
||||
|
@ -107,7 +107,6 @@ spec setup =
|
||||
t3.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "bar2", "bar3"]
|
||||
|
||||
Test.specify "should not allow illegal column names" <|
|
||||
table.set (table.get "bar") new_name="" . should_fail_with Invalid_Column_Names
|
||||
table.set (table.get "bar") new_name='a\0b' . should_fail_with Invalid_Column_Names
|
||||
|
||||
Test.specify "should allow replacing a column" <|
|
||||
|
@ -421,8 +421,11 @@ spec setup =
|
||||
(t3.at "X").date_add (t3.at "Y") Time_Period.Day . to_vector . should_fail_with Illegal_Argument
|
||||
(t3.at "X").date_add 1 Date_Period.Month . to_vector . should_fail_with Illegal_Argument
|
||||
|
||||
# There is no default period.
|
||||
(t1.at "X").date_add (t1.at "Y") . should_be_a Function
|
||||
# Date period defaults to Day for date/date-time
|
||||
(t1.at "X").date_add (t1.at "Y") . to_vector . should_equal [Date.new 2021 02 05, Date.new 2020 12 31, Date.new 2021 12 31]
|
||||
(t2.at "X").date_add (t2.at "Y") . to_vector . should_equal_tz_agnostic [Date_Time.new 2021 02 05 12 30 0, Date_Time.new 2020 12 31 12 30 0, Date_Time.new 2021 12 31 12 30 0]
|
||||
# and defaults to Hour for time-of-day
|
||||
(t3.at "X").date_add (t3.at "Y") . to_vector . should_equal [Time_Of_Day.new 17 30 0, Time_Of_Day.new 22 45 0, Time_Of_Day.new 1 30 0]
|
||||
|
||||
Test.specify "should check shift_amount type in date_add" <|
|
||||
t = table_builder [["X", [Date.new 2021 01 31]]]
|
||||
|
@ -0,0 +1,199 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.Common.Index_Out_Of_Bounds
|
||||
import Standard.Base.Errors.Common.Type_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
|
||||
from Standard.Table import all
|
||||
from Standard.Table.Errors import all
|
||||
|
||||
from Standard.Test import Test, Problems
|
||||
import Standard.Test.Extensions
|
||||
|
||||
from project.Common_Table_Operations.Util import all
|
||||
|
||||
main = run_default_backend spec
|
||||
|
||||
spec setup =
|
||||
prefix = setup.prefix
|
||||
table_builder = setup.table_builder
|
||||
pending_datetime = if setup.test_selection.date_time.not then "Date/Time operations are not supported by this backend."
|
||||
Test.group prefix+"Table.set with Column_Operation" <|
|
||||
Test.specify "arithmetics" <|
|
||||
t = table_builder [["A", [1, 2]], ["B", [10, 40]]]
|
||||
t.set (Column_Operation.Add (Column_Ref.Name "A") (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [11, 42]
|
||||
t.set (Column_Operation.Add 100 (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [110, 140]
|
||||
t.set (Column_Operation.Add (Column_Ref.Name "A") 100) "C" . at "C" . to_vector . should_equal [101, 102]
|
||||
t.set (Column_Operation.Add 23 100) "C" . at "C" . to_vector . should_equal [123, 123]
|
||||
|
||||
t.set (Column_Operation.Subtract (Column_Ref.Name "A") (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [-9, -38]
|
||||
t.set (Column_Operation.Subtract 100 (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [90, 60]
|
||||
t.set (Column_Operation.Subtract (Column_Ref.Name "A") 100) "C" . at "C" . to_vector . should_equal [-99, -98]
|
||||
t.set (Column_Operation.Subtract 23 100) "C" . at "C" . to_vector . should_equal [-77, -77]
|
||||
|
||||
t.set (Column_Operation.Multiply (Column_Ref.Name "A") (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [10, 80]
|
||||
t.set (Column_Operation.Multiply 100 (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [1000, 4000]
|
||||
t.set (Column_Operation.Multiply (Column_Ref.Name "A") 100) "C" . at "C" . to_vector . should_equal [100, 200]
|
||||
t.set (Column_Operation.Multiply 23 100) "C" . at "C" . to_vector . should_equal [2300, 2300]
|
||||
|
||||
t.set (Column_Operation.Divide (Column_Ref.Name "B") (Column_Ref.Name "A")) "C" . at "C" . to_vector . should_equal [10, 20]
|
||||
t.set (Column_Operation.Divide (Column_Ref.Name "A") (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [0.1, 0.05]
|
||||
t.set (Column_Operation.Divide 1 (Column_Ref.Name "A")) "C" . at "C" . to_vector . should_equal [1, 0.5]
|
||||
t.set (Column_Operation.Divide 1 2) "C" . at "C" . to_vector . should_equal [0.5, 0.5]
|
||||
|
||||
t2 = table_builder [["A", [23, 42]], ["B", [10, 3]]]
|
||||
t2.set (Column_Operation.Mod (Column_Ref.Name "A") (Column_Ref.Name "B")) "C" . at "C" . to_vector . should_equal [3, 0]
|
||||
t2.set (Column_Operation.Mod (Column_Ref.Name "A") 10) "C" . at "C" . to_vector . should_equal [3, 2]
|
||||
t2.set (Column_Operation.Mod 7 5) "C" . at "C" . to_vector . should_equal [2, 2]
|
||||
|
||||
t.set (Column_Operation.Power (Column_Ref.Name "B") (Column_Ref.Name "A")) "C" . at "C" . to_vector . should_equal [10, 1600]
|
||||
t.set (Column_Operation.Power (Column_Ref.Name "A") 3) "C" . at "C" . to_vector . should_equal [1, 8]
|
||||
t.set (Column_Operation.Power 2 (Column_Ref.Name "A")) "C" . at "C" . to_vector . should_equal [2, 4]
|
||||
t.set (Column_Operation.Power 3 4) "C" . at "C" . to_vector . should_equal [81, 81]
|
||||
|
||||
Test.expect_panic Type_Error <| t.set (Column_Operation.Subtract "x" "y")
|
||||
t.set (Column_Operation.Add 42 "y") . should_fail_with Illegal_Argument
|
||||
|
||||
Test.specify "rounding" <|
|
||||
t = table_builder [["A", [1.13333, 122.74463, 32.52424, -12.7]]]
|
||||
t.set (Column_Operation.Round (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [1, 123, 33, -13]
|
||||
t.set (Column_Operation.Round (Column_Ref.Name "A") precision=1) "Z" . at "Z" . to_vector . should_equal [1.1, 122.7, 32.5, -12.7]
|
||||
t.set (Column_Operation.Round (Column_Ref.Name "A") precision=-1) "Z" . at "Z" . to_vector . should_equal [0, 120, 30, -10]
|
||||
|
||||
t.set (Column_Operation.Ceil (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [2, 123, 33, -12]
|
||||
t.set (Column_Operation.Floor (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [1, 122, 32, -13]
|
||||
t.set (Column_Operation.Truncate (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [1, 122, 32, -12]
|
||||
|
||||
Test.expect_panic Type_Error <| t.set (Column_Operation.Round "1.23")
|
||||
Test.expect_panic Type_Error <| t.set (Column_Operation.Truncate "1.23")
|
||||
|
||||
Test.specify "date/time" pending=pending_datetime <|
|
||||
t = table_builder [["A", [Date_Time.new 2023 1 12 12 45, Date_Time.new 2020 5 12 1 45]], ["B", [Date_Time.new 2023 1 15 18 45, Date_Time.new 2020 6 12 22 20]], ["x", [1, 3]]]
|
||||
|
||||
# TODO ticket for truncate for DB
|
||||
if setup.is_database.not then
|
||||
t.set (Column_Operation.Truncate (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [Date.new 2023 1 12, Date.new 2020 5 12]
|
||||
t.set (Column_Operation.Truncate (Date_Time.new 1999 12 10 14 55 11)) "Z" . at "Z" . to_vector . should_equal [Date.new 1999 12 10, Date.new 1999 12 10]
|
||||
|
||||
t.set (Column_Operation.Date_Add (Column_Ref.Name "A") (Column_Ref.Name "x")) "Z" . at "Z" . to_vector . should_equal_tz_agnostic [Date_Time.new 2023 1 13 12 45, Date_Time.new 2020 5 15 1 45]
|
||||
t.set (Column_Operation.Date_Add (Column_Ref.Name "A") 10 Date_Period.Year) "Z" . at "Z" . to_vector . should_equal_tz_agnostic [Date_Time.new 2033 1 12 12 45, Date_Time.new 2030 5 12 1 45]
|
||||
t.set (Column_Operation.Date_Add (Date_Time.new 2001 12 15 11 00) 10 Time_Period.Minute) "Z" . at "Z" . to_vector . should_equal_tz_agnostic [Date_Time.new 2001 12 15 11 10, Date_Time.new 2001 12 15 11 10]
|
||||
|
||||
t.set (Column_Operation.Date_Diff (Column_Ref.Name "A") (Column_Ref.Name "B") Date_Period.Day) "Z" . at "Z" . to_vector . should_equal [3, 31]
|
||||
t.set (Column_Operation.Date_Part (Column_Ref.Name "A") Date_Period.Year) "Z" . at "Z" . to_vector . should_equal [2023, 2020]
|
||||
t.set (Column_Operation.Date_Part (Column_Ref.Name "A") Time_Period.Minute) "Z" . at "Z" . to_vector . should_equal [45, 45]
|
||||
|
||||
t2 = table_builder [["C", [Date.new 2002 12 10, Date.new 2005 01 01]], ["D", [Time_Of_Day.new 12 45, Time_Of_Day.new 01 01]]]
|
||||
t2.set (Column_Operation.Date_Add (Column_Ref.Name "C") 5 Date_Period.Month) "Z" . at "Z" . to_vector . should_equal [Date.new 2003 5 10, Date.new 2005 6 01]
|
||||
t2.set (Column_Operation.Date_Add (Column_Ref.Name "D") 15 Time_Period.Hour) "Z" . at "Z" . to_vector . should_equal [Time_Of_Day.new 03 45, Time_Of_Day.new 16 01]
|
||||
|
||||
t2.set (Column_Operation.Date_Diff (Column_Ref.Name "C") (Date.new 2003) Date_Period.Year) "Z" . at "Z" . to_vector . should_equal [0, -2]
|
||||
t2.set (Column_Operation.Date_Diff (Column_Ref.Name "D") (Time_Of_Day.new 13) Time_Period.Minute) "Z" . at "Z" . to_vector . should_equal [15, 59+(60*11)]
|
||||
|
||||
t2.set (Column_Operation.Date_Part (Column_Ref.Name "C") Date_Period.Year) "Z" . at "Z" . to_vector . should_equal [2002, 2005]
|
||||
t2.set (Column_Operation.Date_Part (Column_Ref.Name "D") Time_Period.Minute) "Z" . at "Z" . to_vector . should_equal [45, 1]
|
||||
|
||||
# error handling
|
||||
t2.set (Column_Operation.Date_Part (Column_Ref.Name "C") Time_Period.Second) . should_fail_with Illegal_Argument
|
||||
t2.set (Column_Operation.Date_Add (Column_Ref.Name "D") 5 Date_Period.Year) . should_fail_with Illegal_Argument
|
||||
t.set (Column_Operation.Date_Part (Column_Ref.Name "x") Date_Period.Year) . should_fail_with Invalid_Value_Type
|
||||
Test.expect_panic Type_Error <| t2.set (Column_Operation.Date_Diff 42 "x" Date_Period.Year)
|
||||
|
||||
Test.specify "boolean" <|
|
||||
t = table_builder [["A", [True, False]], ["T", [True, True]]]
|
||||
|
||||
t.set (Column_Operation.And (Column_Ref.Name "A") (Column_Ref.Name "T")) "Z" . at "Z" . to_vector . should_equal [True, False]
|
||||
t.set (Column_Operation.And (Column_Ref.Name "A") False) "Z" . at "Z" . to_vector . should_equal [False, False]
|
||||
t.set (Column_Operation.And True True) "Z" . at "Z" . to_vector . should_equal [True, True]
|
||||
|
||||
t.set (Column_Operation.Or (Column_Ref.Name "A") (Column_Ref.Name "T")) "Z" . at "Z" . to_vector . should_equal [True, True]
|
||||
t.set (Column_Operation.Or False (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [True, False]
|
||||
t.set (Column_Operation.Or False False) "Z" . at "Z" . to_vector . should_equal [False, False]
|
||||
|
||||
t.set (Column_Operation.Not (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal [False, True]
|
||||
t.set (Column_Operation.Not False) "Z" . at "Z" . to_vector . should_equal [True, True]
|
||||
|
||||
Test.expect_panic_with (t.set (Column_Operation.And 42 True)) Type_Error
|
||||
Test.expect_panic_with (t.set (Column_Operation.Or (Column_Ref.Name "A") "x")) Type_Error
|
||||
|
||||
Test.specify "if" <|
|
||||
t = table_builder [["A", [1, 100]], ["B", [10, 40]], ["C", [23, 55]]]
|
||||
t.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Greater than=(Column_Ref.Name "B"))) "Z" . at "Z" . to_vector . should_equal [False, True]
|
||||
t.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Greater than=20) "T" "F") "Z" . at "Z" . to_vector . should_equal ["F", "T"]
|
||||
t.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Less than=20) (Column_Ref.Name "B") (Column_Ref.Name "C")) "Z" . at "Z" . to_vector . should_equal [10, 55]
|
||||
|
||||
t.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Greater than="X") "T" "F") . should_fail_with Invalid_Value_Type
|
||||
|
||||
t2 = table_builder [["A", ["a", "c"]], ["B", ["c", "b"]], ["C", [23, 55]]]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Greater than=(Column_Ref.Name "B"))) "Z" . at "Z" . to_vector . should_equal [False, True]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Greater than=(Column_Ref.Name "B")) (Column_Ref.Name "C") 0) "Z" . at "Z" . to_vector . should_equal [0, 55]
|
||||
t2.set (Column_Operation.If "A" (Filter_Condition.Greater than="B") (Column_Ref.Name "C") 0) "Z" . at "Z" . to_vector . should_equal [0, 0]
|
||||
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Is_In ["x", "a", "dd"]) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["TT", "FF"]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Not_In ["x", "a", "dd"]) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["FF", "TT"]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Is_In []) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["FF", "FF"]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Not_In []) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["TT", "TT"]
|
||||
|
||||
# Passing a column does not work row-by-row, but looks at whole column contents.
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Is_In (t2.at "B")) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["FF", "TT"]
|
||||
t3 = table_builder [["x", ["e", "e", "a"]]]
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Is_In (t3.at "x")) "TT" "FF") "Z" . at "Z" . to_vector . should_equal ["TT", "FF"]
|
||||
|
||||
# Thus, passing a Column_Ref into Is_In/Not_In is not allowed as it would be confusing.
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Is_In (Column_Ref.Name "B")) "TT" "FF") . should_fail_with Illegal_Argument
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Not_In (Column_Ref.Name "B")) "TT" "FF") . should_fail_with Illegal_Argument
|
||||
t2.set (Column_Operation.If (Column_Ref.Name "A") (Filter_Condition.Not_In [Column_Ref.Name "B", "X"]) "TT" "FF") . should_fail_with Illegal_Argument
|
||||
|
||||
Test.specify "text" <|
|
||||
t = table_builder [["A", [" a ", "b"]], ["B", ["c", " d "]]]
|
||||
|
||||
t.set (Column_Operation.Trim (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal ["a", "b"]
|
||||
t.set (Column_Operation.Trim (Column_Ref.Name "A") Location.End) "Z" . at "Z" . to_vector . should_equal [" a", "b"]
|
||||
t.set (Column_Operation.Trim (Column_Ref.Name "A") Location.Start) "Z" . at "Z" . to_vector . should_equal ["a ", "b"]
|
||||
t.set (Column_Operation.Trim (Column_Ref.Name "A") Location.Both "abc") "Z" . at "Z" . to_vector . should_equal [" a ", ""]
|
||||
t.set (Column_Operation.Trim "bb aaaa" Location.Both (Column_Ref.Name "A")) "Z" . at "Z" . to_vector . should_equal ["bb", " aaaa"]
|
||||
|
||||
t.set (Column_Operation.Add (Column_Ref.Name "A") (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal [" a c", "b d "]
|
||||
t.set (Column_Operation.Add "prefix_" (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal ["prefix_c", "prefix_ d "]
|
||||
t.set (Column_Operation.Add (Column_Ref.Name "A") "!") "Z" . at "Z" . to_vector . should_equal [" a !", "b!"]
|
||||
t.set (Column_Operation.Add "O" "!") "Z" . at "Z" . to_vector . should_equal ["O!", "O!"]
|
||||
|
||||
t2 = table_builder [["A", [42]]]
|
||||
t2.set (Column_Operation.Trim (Column_Ref.Name "A")) . should_fail_with Invalid_Value_Type
|
||||
|
||||
Test.specify "min/max" <|
|
||||
t = table_builder [["A", [1, 20]], ["B", [10, 2]]]
|
||||
|
||||
t.set (Column_Operation.Min (Column_Ref.Name "A") (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal [1, 2]
|
||||
t.set (Column_Operation.Min (Column_Ref.Name "A") 5) "Z" . at "Z" . to_vector . should_equal [1, 5]
|
||||
|
||||
t.set (Column_Operation.Max (Column_Ref.Name "A") (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal [10, 20]
|
||||
t.set (Column_Operation.Max (Column_Ref.Name "A") 5) "Z" . at "Z" . to_vector . should_equal [5, 20]
|
||||
|
||||
t.set (Column_Operation.Max 2 5) "Z" . at "Z" . to_vector . should_equal [5, 5]
|
||||
t.set (Column_Operation.Min 2 5) "Z" . at "Z" . to_vector . should_equal [2, 2]
|
||||
|
||||
t2 = table_builder [["A", ["aardvark", "zebra"]], ["B", ["cat", "dog"]], ["x", [1, 20]]]
|
||||
t2.set (Column_Operation.Min (Column_Ref.Name "A") (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal ["aardvark", "dog"]
|
||||
t2.set (Column_Operation.Max (Column_Ref.Name "A") (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal ["cat", "zebra"]
|
||||
t2.set (Column_Operation.Min (Column_Ref.Name "A") "animal") "Z" . at "Z" . to_vector . should_equal ["aardvark", "animal"]
|
||||
t2.set (Column_Operation.Max "coyote" (Column_Ref.Name "B")) "Z" . at "Z" . to_vector . should_equal ["coyote", "dog"]
|
||||
|
||||
# mixed types result in an error
|
||||
t2.set (Column_Operation.Min (Column_Ref.Name "A") 42) . should_fail_with Invalid_Value_Type
|
||||
t2.set (Column_Operation.Min (Column_Ref.Name "x") "x") . should_fail_with Invalid_Value_Type
|
||||
t2.set (Column_Operation.Min (Column_Ref.Name "x") (Column_Ref.Name "A")) . should_fail_with Invalid_Value_Type
|
||||
|
||||
if pending_datetime.is_nothing then
|
||||
t3 = table_builder [["A", [Date.new 2002 12 10, Date.new 2005 01 01]]]
|
||||
t3.set (Column_Operation.Min (Column_Ref.Name "A") (Date.new 2003)) "Z" . at "Z" . to_vector . should_equal [Date.new 2002 12 10, Date.new 2003 01 01]
|
||||
t3.set (Column_Operation.Max (Column_Ref.Name "A") (Date.new 2003)) "Z" . at "Z" . to_vector . should_equal [Date.new 2003 01 01, Date.new 2005 01 01]
|
||||
|
||||
Test.specify "allows also indexing columns numerically" <|
|
||||
t = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
||||
t.set (Column_Operation.Add (Column_Ref.Index 0) (Column_Ref.Index 1)) "Z" . at "Z" . to_vector . should_equal [4, 6]
|
||||
|
||||
Test.specify "will forward column resolution errors" <|
|
||||
t = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
||||
t.set (Column_Operation.Add (Column_Ref.Name "X") (Column_Ref.Name "Z")) . should_fail_with No_Such_Column
|
||||
t.set (Column_Operation.Not (Column_Ref.Name "zzz")) . should_fail_with No_Such_Column
|
||||
t.set (Column_Operation.Not (Column_Ref.Index 42)) . should_fail_with Index_Out_Of_Bounds
|
@ -5,9 +5,9 @@ import Standard.Base.Errors.Common.Type_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Errors.Illegal_State.Illegal_State
|
||||
|
||||
import Standard.Table.Data.Type.Value_Type.Value_Type
|
||||
import Standard.Table.Data.Expression.Expression_Error
|
||||
from Standard.Table import all hiding Table
|
||||
from Standard.Table.Errors import all
|
||||
import Standard.Table.Data.Expression.Expression_Error
|
||||
|
||||
from Standard.Database.Errors import SQL_Error
|
||||
|
||||
@ -58,12 +58,20 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Greater than=(t.at "Y")) . at "X" . to_vector . should_equal [12]
|
||||
t.filter "Y" (Filter_Condition.Between (t.at "ix") 100) . at "Y" . to_vector . should_equal [100, 4, 11]
|
||||
|
||||
t.filter "X" (Filter_Condition.Equal to=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [100]
|
||||
t.filter "X" (Filter_Condition.Less than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [3]
|
||||
t.filter "X" (Filter_Condition.Equal_Or_Less than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [100, 3]
|
||||
t.filter "X" (Filter_Condition.Equal_Or_Greater than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [100, 12]
|
||||
t.filter "X" (Filter_Condition.Greater than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [12]
|
||||
t.filter "Y" (Filter_Condition.Between (Column_Ref.Name "ix") 100) . at "Y" . to_vector . should_equal [100, 4, 11]
|
||||
|
||||
Test.specify "Not_Equal test cases" pending="Specification needs clarifying, see: https://github.com/enso-org/enso/issues/5241#issuecomment-1480167927" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", [100, 3, Nothing, 4, 12]], ["Y", [100, 4, 2, Nothing, 11]]]
|
||||
t3 = t.filter "X" (Filter_Condition.Not_Equal to=100)
|
||||
t3 . at "X" . to_vector . should_equal [3, Nothing, 4, 12]
|
||||
t3 . at "ix" . to_vector . should_equal [2, 3, 4, 5]
|
||||
t.filter "X" (Filter_Condition.Not_Equal to=(t.at "Y")) . at "X" . to_vector . should_equal [3, Nothing, 4, 12]
|
||||
t.filter "X" (Filter_Condition.Not_Equal to=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal [3, Nothing, 4, 12]
|
||||
|
||||
Test.specify "by text comparisons" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", ["abb", "baca", "b", Nothing, "c"]], ["Y", ["a", "b", "b", "c", "c"]]]
|
||||
@ -87,6 +95,13 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Equal to=(t.at "Y")) . at "X" . to_vector . should_equal ["b", "c"]
|
||||
t.filter "X" (Filter_Condition.Between (t.at "Y") "bzzzz") . at "X" . to_vector . should_equal ["abb", "baca", "b"]
|
||||
|
||||
t.filter "X" (Filter_Condition.Greater than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal ["abb", "baca"]
|
||||
t.filter "X" (Filter_Condition.Equal_Or_Greater than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal ["abb", "baca", "b", "c"]
|
||||
t.filter "X" (Filter_Condition.Equal_Or_Less than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal ["b", "c"]
|
||||
t.filter "X" (Filter_Condition.Less than=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal []
|
||||
t.filter "X" (Filter_Condition.Equal to=(Column_Ref.Name "Y")) . at "X" . to_vector . should_equal ["b", "c"]
|
||||
t.filter "X" (Filter_Condition.Between (Column_Ref.Name "Y") "bzzzz") . at "X" . to_vector . should_equal ["abb", "baca", "b"]
|
||||
|
||||
Test.specify "by text search (contains, starts_with, ends_with, not_contains)" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", ["abb", "bacb", "banana", Nothing, "nana"]], ["Y", ["a", "B", "d", "c", "a"]], ["Z", ["aaaaa", "bbbbb", "[ab]", "[ab]aaaa", "[ab]ccc"]]]
|
||||
|
||||
@ -116,6 +131,11 @@ spec setup =
|
||||
t.filter "X" (Filter_Condition.Not_Contains (t.at "Y") Case_Sensitivity.Sensitive) . at "X" . to_vector . should_equal ["bacb", "banana"]
|
||||
t.filter "X" (Filter_Condition.Not_Contains (t.at "Y") Case_Sensitivity.Insensitive) . at "X" . to_vector . should_equal ["banana"]
|
||||
|
||||
t.filter "X" (Filter_Condition.Starts_With (Column_Ref.Name "Y")) . at "X" . to_vector . should_equal ["abb"]
|
||||
t.filter "X" (Filter_Condition.Ends_With (Column_Ref.Name "Y") Case_Sensitivity.Insensitive) . at "X" . to_vector . should_equal ["bacb", "nana"]
|
||||
t.filter "X" (Filter_Condition.Contains (Column_Ref.Name "Y") Case_Sensitivity.Insensitive) . at "X" . to_vector . should_equal ["abb", "bacb", "nana"]
|
||||
t.filter "X" (Filter_Condition.Not_Contains (Column_Ref.Name "Y") Case_Sensitivity.Insensitive) . at "X" . to_vector . should_equal ["banana"]
|
||||
|
||||
Test.specify "by text search (like, not_like)" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["X", ["abb", "bacb", "banana", Nothing, "nana"]], ["Y", ["a", "B", "d", "c", "a"]], ["Z", ["aaaaa", "bbbbb", "[ab]", "[ab]aaaa", "[ab]ccc"]]]
|
||||
|
||||
@ -175,6 +195,13 @@ spec setup =
|
||||
check_problem (t.filter "X" (Filter_Condition.Not_Like (t.at "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Not_Contains (t.at "ix")))
|
||||
|
||||
check_problem (t.filter "X" (Filter_Condition.Starts_With (Column_Ref.Name "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Ends_With (Column_Ref.Name "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Contains (Column_Ref.Name "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Like (Column_Ref.Name "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Not_Like (Column_Ref.Name "ix")))
|
||||
check_problem (t.filter "X" (Filter_Condition.Not_Contains (Column_Ref.Name "ix")))
|
||||
|
||||
check_problem (t.filter "ix" (Filter_Condition.Starts_With "A"))
|
||||
check_problem (t.filter "ix" (Filter_Condition.Ends_With "A"))
|
||||
check_problem (t.filter "ix" (Filter_Condition.Contains "A"))
|
||||
@ -247,6 +274,18 @@ spec setup =
|
||||
t2.filter "B" (Filter_Condition.Is_In [False]) . at "B" . to_vector . should_equal [False, False, False]
|
||||
t2.filter "C" (Filter_Condition.Is_In [False, False]) . at "C" . to_vector . should_equal [False]
|
||||
|
||||
Test.specify "does not allow Column_Ref in Is_In/Not_In because that would be confusing" <|
|
||||
## Is In and Not In check if a value is contained anywhere in a provided collection (e.g. column),
|
||||
NOT on a row-by-row basis like all other operations. Column_Ref is used with row-by-row ops,
|
||||
so this would only cause confusion. Very rarely someone wants to filter a column by Is_In
|
||||
within the same table - and that's the only approach Column_Ref would support.
|
||||
t = table_builder [["A", [1, 2, 3]], ["B", [2, 3, 4]]]
|
||||
|
||||
t.filter "A" (Filter_Condition.Is_In (Column_Ref.Name "B")) . should_fail_with Illegal_Argument
|
||||
|
||||
# If the user really wants this, they pass it as a raw column:
|
||||
t.filter "A" (Filter_Condition.Is_In (t.at "B")) . at "A" . to_vector . should_equal [2, 3]
|
||||
|
||||
Test.specify "by a boolean mask" <|
|
||||
t = table_builder [["ix", [1, 2, 3, 4, 5]], ["b", [True, False, Nothing, True, True]]]
|
||||
t.filter "b" . at "ix" . to_vector . should_equal [1, 4, 5]
|
||||
|
@ -10,6 +10,7 @@ import project.Common_Table_Operations.Core_Spec
|
||||
import project.Common_Table_Operations.Cross_Tab_Spec
|
||||
import project.Common_Table_Operations.Conversion_Spec
|
||||
import project.Common_Table_Operations.Date_Time_Spec
|
||||
import project.Common_Table_Operations.Derived_Columns_Spec
|
||||
import project.Common_Table_Operations.Distinct_Spec
|
||||
import project.Common_Table_Operations.Expression_Spec
|
||||
import project.Common_Table_Operations.Filter_Spec
|
||||
@ -117,6 +118,7 @@ spec setup =
|
||||
Select_Columns_Spec.spec setup
|
||||
Column_Name_Edge_Cases_Spec.spec setup
|
||||
Column_Operations_Spec.spec setup
|
||||
Derived_Columns_Spec.spec setup
|
||||
Date_Time_Spec.spec setup
|
||||
Conversion_Spec.spec setup
|
||||
Aggregate_Spec.spec setup
|
||||
|
@ -3,8 +3,8 @@ import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Delimited
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
from Standard.Table.Errors import all
|
||||
|
||||
from Standard.Test import Test, Test_Suite, Problems
|
||||
|
@ -1,6 +1,6 @@
|
||||
from Standard.Base import all
|
||||
from Standard.Table import Table
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
@ -3,12 +3,12 @@ from Standard.Base import all
|
||||
import Standard.Base.Data.Text.Regex.Regex_Syntax_Error
|
||||
import Standard.Base.Errors.Common.Type_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
import Standard.Test.Extensions
|
||||
|
||||
from Standard.Table import Table
|
||||
from Standard.Table.Data.Type.Value_Type import Bits, Value_Type
|
||||
from Standard.Table.Errors import Invalid_Value_Type, Column_Count_Exceeded, Duplicate_Output_Column_Names, Missing_Input_Columns
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
from Standard.Test import Test, Test_Suite, Problems
|
||||
from project.Util import all
|
||||
|
||||
|
@ -2,7 +2,7 @@ from Standard.Base import all
|
||||
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
from Standard.Table import Table, Column
|
||||
|
||||
from Standard.Test import Test, Test_Suite, Problems
|
||||
|
@ -1,8 +1,8 @@
|
||||
from Standard.Base import all
|
||||
|
||||
from Standard.Table import Table, Column, Delimited, Data_Formatter
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
import Standard.Table.Data.Type.Value_Type.Value_Type
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
@ -1,8 +1,8 @@
|
||||
from Standard.Base import all
|
||||
|
||||
from Standard.Table import Table, Delimited, Column, Data_Formatter
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
import Standard.Table.Data.Type.Value_Type.Value_Type
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
@ -1,8 +1,8 @@
|
||||
from Standard.Base import all
|
||||
|
||||
from Standard.Table import Table, Delimited, Column, Data_Formatter
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
import Standard.Table.Data.Type.Value_Type.Value_Type
|
||||
from Standard.Table.Extensions.Table_Conversions import all
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
Loading…
Reference in New Issue
Block a user