Rename order_by to sort for Table and DB_Table. (#10372)

- Rename `order_by` to `sort` for `Table` and `DB_Table`.
- Added deprecated placeholder.
- Fixed a couple of minor deprecated mistakes.

![image](https://github.com/enso-org/enso/assets/4699705/96c32fa7-33e5-400a-9d3a-ebf330886911)
This commit is contained in:
James Dunkerley 2024-06-26 18:46:09 +01:00 committed by GitHub
parent 0039c4d6a3
commit d92078471b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 385 additions and 350 deletions

View File

@ -46,6 +46,7 @@
database.][10206]
- [Implemented fallback to Windows-1252 encoding for `Encoding.Default`.][10190]
- [Added Table.duplicates component][10323]
- [Renamed `Table.order_by` to `Table.sort`][10372]
[debug-shortcuts]:
@ -55,6 +56,7 @@
[10206]: https://github.com/enso-org/enso/pull/10206
[10190]: https://github.com/enso-org/enso/pull/10190
[10323]: https://github.com/enso-org/enso/pull/10323
[10372]: https://github.com/enso-org/enso/pull/10372
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)

View File

@ -42,7 +42,7 @@ Vector.running self statistic:Statistic=..Count =
- statistics: Set of statistics to calculate.
@statistics Statistic.bulk_widget
Vector.running_bulk : Vector Statistic -> Vector Any
Vector.running_bulk self statistics:Statistic=[..Count, ..Sum] =
Vector.running_bulk self (statistics:(Vector Statistic)=[..Count, ..Sum]) =
Statistic.running_bulk self statistics
## GROUP Statistics

View File

@ -11,9 +11,9 @@ polyglot java import java.time.temporal.TemporalAdjuster
polyglot java import java.time.temporal.TemporalAdjusters
polyglot java import java.time.temporal.TemporalUnit
polyglot java import org.enso.base.time.CustomTemporalUnits
polyglot java import org.enso.base.time.Date_Utils
polyglot java import org.enso.base.time.Date_Period_Utils
polyglot java import org.enso.base.time.Date_Time_Utils
polyglot java import org.enso.base.time.Date_Utils
polyglot java import org.enso.base.time.Time_Of_Day_Utils
polyglot java import org.enso.base.Time_Utils

View File

@ -33,9 +33,9 @@ polyglot java import org.enso.base.XML_Utils
polyglot java import org.w3c.dom.Attr
polyglot java import org.w3c.dom.Document
polyglot java import org.w3c.dom.Element
polyglot java import org.w3c.dom.NamedNodeMap
polyglot java import org.w3c.dom.Node
polyglot java import org.w3c.dom.NodeList
polyglot java import org.w3c.dom.NamedNodeMap
polyglot java import org.w3c.dom.Text as Java_Text
polyglot java import org.xml.sax.SAXException
polyglot java import org.xml.sax.SAXParseException
@ -99,9 +99,9 @@ type XML_Document
Wrap Java's Document to XML_Document
new doc:Document = XML_Document.Value doc
## PRIVATE
private Value (java_document:Document)
## GROUP Metadata
ICON metadata
Get the root element of the document.

View File

@ -24,10 +24,10 @@ from project.Metadata import make_single_choice
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
polyglot java import org.enso.base.enso_cloud.HideableValue
polyglot java import org.enso.base.enso_cloud.HideableValue.Base64EncodeValue
polyglot java import org.enso.base.enso_cloud.HideableValue.ConcatValues
polyglot java import org.enso.base.enso_cloud.HideableValue.PlainValue
polyglot java import org.enso.base.enso_cloud.HideableValue.SecretValue
polyglot java import org.enso.base.enso_cloud.HideableValue.ConcatValues
polyglot java import org.enso.base.enso_cloud.HideableValue.Base64EncodeValue
## A reference to a secret stored in the Enso Cloud.
type Enso_Secret

View File

@ -30,9 +30,9 @@ from project.Data.Json.Extensions import all
polyglot java import java.lang.Exception as JException
polyglot java import java.net.http.HttpClient
polyglot java import java.net.http.HttpClient.Builder as ClientBuilder
polyglot java import java.net.http.HttpClient.Redirect
polyglot java import java.net.http.HttpClient.Version
polyglot java import java.net.http.HttpClient.Builder as ClientBuilder
polyglot java import java.net.http.HttpRequest
polyglot java import java.net.http.HttpRequest.BodyPublisher
polyglot java import java.net.http.HttpRequest.BodyPublishers
@ -40,8 +40,8 @@ polyglot java import java.net.http.HttpRequest.Builder
polyglot java import java.net.InetSocketAddress
polyglot java import java.net.ProxySelector
polyglot java import javax.net.ssl.SSLContext
polyglot java import org.enso.base.file_system.File_Utils
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
polyglot java import org.enso.base.file_system.File_Utils
polyglot java import org.enso.base.net.http.MultipartBodyBuilder
polyglot java import org.enso.base.net.http.UrlencodedBodyBuilder

View File

@ -26,8 +26,8 @@ from project.Metadata import Display, Widget
from project.Network.HTTP.Response_Body import decode_format_selector
polyglot java import java.net.http.HttpHeaders
polyglot java import org.enso.base.enso_cloud.EnsoHttpResponse
polyglot java import java.util.Optional
polyglot java import org.enso.base.enso_cloud.EnsoHttpResponse
type Response
## PRIVATE

View File

@ -47,8 +47,8 @@ polyglot java import java.nio.file.StandardCopyOption
polyglot java import java.nio.file.StandardOpenOption
polyglot java import java.time.ZonedDateTime
polyglot java import org.enso.base.DryRunFileManager
polyglot java import org.enso.base.file_system.FileSystemSPI
polyglot java import org.enso.base.file_system.File_Utils
polyglot java import org.enso.base.file_system.FileSystemSPI
## PRIVATE
file_types : Vector

View File

@ -12,8 +12,8 @@ import project.System.Input_Stream.Input_Stream
from project.Data.Boolean import Boolean, False, True
from project.Runtime import assert
polyglot java import org.enso.base.encoding.DecodingProblemAggregator
polyglot java import org.enso.base.encoding.DecodingProblem
polyglot java import org.enso.base.encoding.DecodingProblemAggregator
polyglot java import org.enso.base.encoding.Encoding_Utils
polyglot java import org.enso.base.encoding.ReportingStreamDecoder

View File

@ -15,10 +15,9 @@ from project.System.Input_Stream import close_stream
polyglot java import java.io.ByteArrayOutputStream
polyglot java import java.io.OutputStream as Java_Output_Stream
polyglot java import org.enso.base.encoding.Encoding_Utils
polyglot java import org.enso.base.encoding.ReportingStreamEncoder
polyglot java import org.enso.base.Stream_Utils
polyglot java import org.enso.base.Stream_Utils.OutputStreamLike
polyglot java import org.enso.base.encoding.ReportingStreamEncoder
## PRIVATE
An output stream, allowing for interactive writing of contents.

View File

@ -146,3 +146,18 @@ make_data_cleanse_vector_selector display:Display=Display.Always =
patterns = ['Leading_Whitespace', 'Trailing_Whitespace', 'Duplicate_Whitespace', 'All_Whitespace', 'Leading_Numbers', 'Trailing_Numbers', 'Non_ASCII', 'Tabs', 'Letters', 'Numbers', 'Punctuation', 'Symbols']
options = patterns.map f-> Option f (".." + f)
Multiple_Choice values=options display=display
## PRIVATE
Make a single value selector
make_any_selector : Display -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Widget
make_any_selector display:Display=..Always add_text:Boolean=False add_regex:Boolean=False add_number:Boolean=False add_boolean:Boolean=False add_named_pattern:Boolean=False add_nothing:Boolean=False =
text = if add_text then [Option "<Text Value>" "''"] else []
regex = if add_regex then [Option "<Regular Expression>" "(regex '')"] else []
number = if add_number then [Option "<Number Value>" "0"] else []
boolean = if add_boolean then [Option "<True/False>" "True"] else []
named_pattern = if add_named_pattern.not then [] else
patterns = ["Leading_Whitespace", "Trailing_Whitespace", "All_Whitespace", "Leading_Numbers", "Trailing_Numbers", "Non_ASCII", "Tabs", "Letters", "Numbers", "Punctuation", "Symbols"]
## Can't use auto-scoping as Named_Patterns are materialised into Regex.
patterns.map p-> Option "<"+p+">" "Named_Pattern."+p
nothing = if add_nothing then [Option "<Nothing>" "Nothing"] else []
make_single_choice (text + regex + number + boolean + named_pattern + nothing) display=display

View File

@ -1196,9 +1196,9 @@ type DB_Column
column.sort Sort_Direction.Descending
sort : Sort_Direction -> DB_Column
sort self order=Sort_Direction.Ascending =
self.to_table.order_by [Sort_Column.Index 0 order] . at 0
self.to_table.sort [..Index 0 order] . at 0
## ALIAS first, head, last, limit, sample, slice, tail, top, keep
## ALIAS first, head, keep, last, limit, sample, slice, tail, top
GROUP Standard.Base.Selections
ICON parse3
Creates a new Column with the specified range of rows from the input
@ -1210,7 +1210,7 @@ type DB_Column
take : (Index_Sub_Range | Range | Integer) -> DB_Column
take self range=(First 1) = self.to_table.take range . at 0
## ALIAS skip, remove
## ALIAS remove, skip
GROUP Standard.Base.Selections
ICON parse3
Creates a new column from the input with the specified range of rows
@ -1805,9 +1805,9 @@ type DB_Column
check_cast_compatibility self.value_type value_type <|
self.internal_do_cast value_type on_problems
## GROUP Standard.Base.Conversions
## ALIAS auto_value_type
GROUP Standard.Base.Conversions
ICON convert
ALIAS auto_value_type
Change the value type of the column to a more specific one, based on its
contents.

View File

@ -15,7 +15,7 @@ import Standard.Base.Errors.Unimplemented.Unimplemented
import Standard.Base.System.File.Generic.Writable_File.Writable_File
from Standard.Base.Metadata import Display, make_single_choice, Widget
from Standard.Base.Runtime import assert
from Standard.Base.Widget_Helpers import make_data_cleanse_vector_selector, make_delimiter_selector, make_format_chooser
from Standard.Base.Widget_Helpers import make_any_selector, make_data_cleanse_vector_selector, make_delimiter_selector, make_format_chooser
import Standard.Table.Column_Operation.Column_Operation
import Standard.Table.Columns_To_Add.Columns_To_Add
@ -167,6 +167,7 @@ type DB_Table
- if_missing: The value to use if the selector isn't present.
@selector Widget_Helpers.make_column_name_selector
@index (t-> Widget.Numeric_Input minimum=0 maximum=t.row_count-1)
@if_missing (make_any_selector add_text=True add_regex=True add_number=True add_boolean=True add_named_pattern=True add_nothing=True)
get_value : Text | Integer -> Integer -> Any -> Any
get_value self selector:(Text | Integer)=0 index:Integer=0 ~if_missing=Nothing =
col = self.get selector if_missing=Nothing
@ -735,7 +736,7 @@ type DB_Table
result = self.filter column Filter_Condition.Is_True
Warning.attach (Deprecated.Warning "Standard.Database.DB_Table.DB_Table" "filter_by_expression" "Deprecated: use `filter` with an `Expression` instead.") result
## ALIAS first, head, last, limit, sample, slice, tail, top, keep
## ALIAS first, head, keep, last, limit, sample, slice, tail, top
GROUP Standard.Base.Selections
ICON select_row
Creates a new Table with the specified range of rows from the input
@ -767,7 +768,7 @@ type DB_Table
take self range:(Index_Sub_Range | Range | Integer)=(..First 1) =
Take_Drop_Helpers.take_drop_helper Take_Drop.Take self range
## ALIAS skip, remove
## ALIAS remove, skip
GROUP Standard.Base.Selections
ICON select_row
Creates a new Table from the input with the specified range of rows
@ -877,7 +878,7 @@ type DB_Table
updated_table.as_subquery
## UNSTABLE
## ALIAS order_by
GROUP Standard.Base.Selections
ICON select_row
@ -906,8 +907,9 @@ type DB_Table
In the call below, assuming that the table of `t1` contains rows for
numbers 1, 2, ..., 10, will return rows starting from 6 and not an empty
result as one could expect if the limit was applied before the filters.
t1 = table.order_by [Sort_Column.Name "A"] . limit 5
t2 = t1.filter 'A' (Greater than=5)
t1 = table.sort [..Name "A"] . limit 5
t2 = t1.filter 'A' (..Greater than=5)
t2.read
limit : Integer -> DB_Table
limit self max_rows:Integer=1000 =
@ -1218,40 +1220,40 @@ type DB_Table
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`.
table.order_by ['Quantity']
table.sort ['Quantity']
> Example
Sorting `table` in descending order by the value in column `'Quantity'`.
table.order_by [Sort_Column.Name 'Quantity' Sort_Direction.Descending]
table.sort [..Name 'Quantity' ..Descending]
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`,
using the value in column `'Rating'` for breaking ties.
table.order_by ['Quantity', 'Rating']
table.sort ['Quantity', 'Rating']
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`,
using the value in column `'Rating'` in descending order for breaking
ties.
table.order_by [Sort_Column.Name 'Quantity', Sort_Column.Name 'Rating' Sort_Direction.Descending]
table.sort [..Name 'Quantity', ..Name 'Rating' ..Descending]
> Example
Order the table by the second column in ascending order. In case of any
ties, break them based on the 7th column from the end of the table in
descending order.
table.order_by [1, Sort_Column.Index -7 Sort_Direction.Descending]
table.sort [1, ..Index -7 ..Descending]
> Example
Sort the table by columns whose names start with letter `a`.
table.order_by [(Sort_Column.Select_By_Name "a.*".to_regex case_sensitivity=Case_Sensitivity.Insensitive)]
table.sort [(..Select_By_Name "a.*".to_regex case_sensitivity=..Insensitive)]
@columns Widget_Helpers.make_order_by_selector
order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> DB_Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
sort : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> DB_Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
sort self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder
problem_builder.attach_problems_before on_problems <|
@ -1263,6 +1265,16 @@ type DB_Table
new_ctx = self.context.add_orders new_order_descriptors
self.updated_context new_ctx
## PRIVATE
GROUP Standard.Base.Selections
ICON order
Deprecated - use `Table.sort` instead.
@columns Widget_Helpers.make_order_by_selector
order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> DB_Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
result = self.sort columns text_ordering error_on_missing_columns on_problems
Warning.attach (Deprecated.Warning "Standard.Database.Table.Table" "order_by" "Deprecated: use `sort` instead.") result
## PRIVATE
Returns the default ordering used for operations like `add_row_number` or
`take`.
@ -1331,7 +1343,7 @@ type DB_Table
setting.
@columns Widget_Helpers.make_column_name_multi_selector
distinct : Vector (Integer | Text | Regex) | Text | Integer | Regex -> Case_Sensitivity -> Problem_Behavior -> DB_Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
distinct self columns=self.column_names case_sensitivity:Case_Sensitivity=..Default on_problems:Problem_Behavior=Report_Warning =
distinct self columns=self.column_names case_sensitivity:Case_Sensitivity=..Default on_problems:Problem_Behavior=..Report_Warning =
key_columns = self.columns_helper.select_columns columns Case_Sensitivity.Default reorder=True error_on_missing_columns=True on_problems=on_problems . catch No_Output_Columns _->
Error.throw No_Input_Columns_Selected
problem_builder = Problem_Builder.new
@ -1697,6 +1709,7 @@ type DB_Table
# 1 | 20 | b | f
# 2 | 30 | c | g
# 3 | 40 | d | h
@lookup_table Widget_Helpers.make_replace_selector
@columns (Widget_Helpers.make_column_name_multi_selector add_regex=True add_by_type=True)
@from_column Widget.Text_Input
@to_column Widget.Text_Input

View File

@ -259,5 +259,5 @@ default_fetch_primary_key connection table_name =
keys_table = result_set_to_table rs connection.dialect.get_type_mapping.make_column_fetcher
# The names of the columns are sometimes lowercase and sometimes uppercase, so we do a case insensitive select first.
selected = keys_table.select_columns ["COLUMN_NAME", "KEY_SEQ"] case_sensitivity=Case_Sensitivity.Insensitive reorder=True
key_column_names = selected.order_by 1 . at 0 . to_vector
key_column_names = selected.sort 1 . at 0 . to_vector
if key_column_names.is_empty then Nothing else key_column_names

View File

@ -247,7 +247,7 @@ type SQLite_Dialect
## The `pk` field is non-zero if the columns is part of the primary key.
The column value indicates the position in the key.
See: https://www.sqlite.org/pragma.html#pragma_table_info
v = info_table.filter "pk" (>0) . order_by "pk" . at "name" . to_vector
v = info_table.filter "pk" (>0) . sort "pk" . at "name" . to_vector
if v.is_empty then Nothing else v
## PRIVATE

View File

@ -52,7 +52,7 @@
example_sort =
table = Examples.inventory_table
table.order_by [Sort_Column.Name "total_stock", Sort_Column.Name "sold_stock" Sort_Direction.Descending]
table.sort [Sort_Column.Name "total_stock", Sort_Column.Name "sold_stock" Sort_Direction.Descending]
> Example
Compute the number of transactions that each item has participated in, as

View File

@ -31,7 +31,7 @@
example_sort =
table = Examples.inventory_table
table.order_by [Sort_Column.Name "price" Sort_Direction.Descending]
table.sort [Sort_Column.Name "price" Sort_Direction.Descending]
> Example
Add two columns to each other.

View File

@ -1961,9 +1961,9 @@ type Column
new_storage = self.java_column.getStorage.cast target_storage_type cast_problem_builder
Column.from_storage self.name new_storage
## GROUP Standard.Base.Conversions
## ALIAS auto_value_type
GROUP Standard.Base.Conversions
ICON convert
ALIAS auto_value_type
Change the value type of the column to a more specific one, based on its
contents.
@ -2383,7 +2383,7 @@ type Column
sorted = self.to_vector.sort order by=wrapped
Column.from_vector self.name sorted
## ALIAS first, head, last, limit, sample, slice, tail, top, keep
## ALIAS first, head, keep, last, limit, sample, slice, tail, top
GROUP Standard.Base.Selections
ICON parse3
Creates a new Column with the specified range of rows from the input
@ -2418,7 +2418,7 @@ type Column
take self range=(First 1) =
Index_Sub_Range_Module.take_helper self.length (self.at _) self.slice (slice_ranges self) range
## ALIAS skip, remove
## ALIAS remove, skip
GROUP Standard.Base.Selections
ICON parse3
Creates a new Column from the input with the specified range of rows

View File

@ -4,7 +4,7 @@ import Standard.Base.Metadata.Widget
from Standard.Base.Metadata.Choice import Option
from Standard.Base.Metadata.Widget import Multiple_Choice, Numeric_Input, Single_Choice, Text_Input, Vector_Editor
from Standard.Base.System.File_Format import format_types
from Standard.Base.Widget_Helpers import make_format_chooser
from Standard.Base.Widget_Helpers import make_any_selector, make_format_chooser
import project.Aggregate_Column.Aggregate_Column
import project.Internal.Parse_Values_Helper
@ -239,3 +239,14 @@ make_value_type_vector_selector =
options = meta.constructors.map c-> Option c.name meta.qualified_name+"."+c.name
item_editor = Single_Choice display=Display.Always values=options
Vector_Editor item_editor=item_editor item_default="Value_Type.Boolean" display=Display.Always
## PRIVATE
Make a replace builder.
make_replace_selector : Display -> Widget
make_replace_selector display=Display.Always =
key_selector = make_any_selector add_text=True add_regex=True add_number=True add_boolean=True add_named_pattern=True add_nothing=False
value_selector = make_any_selector add_text=True add_regex=True add_number=True add_boolean=True add_named_pattern=True add_nothing=True
fqn = Meta.get_qualified_type_name Pair
name = Option "Pair" fqn+".Value" [["first", key_selector], ["second", value_selector]]
item_editor = Single_Choice display=Display.Always values=[name]
Vector_Editor item_editor=item_editor item_default="(Pair.Value 'Current' 'New')" display=display

View File

@ -17,7 +17,7 @@ import Standard.Base.Errors.Unimplemented.Unimplemented
import Standard.Base.Runtime.Context
import Standard.Base.System.File.Generic.Writable_File.Writable_File
from Standard.Base.Metadata import Display, make_single_choice, Widget
from Standard.Base.Widget_Helpers import make_data_cleanse_vector_selector, make_delimiter_selector, make_format_chooser
from Standard.Base.Widget_Helpers import make_any_selector, make_data_cleanse_vector_selector, make_delimiter_selector, make_format_chooser
import project.Aggregate_Column.Aggregate_Column
import project.Blank_Selector.Blank_Selector
@ -299,6 +299,7 @@ type Table
example_at = Examples.inventory_table.get_value "item_name" 4
@selector Widget_Helpers.make_column_name_selector
@index (t-> Widget.Numeric_Input minimum=0 maximum=t.row_count-1)
@if_missing (make_any_selector add_text=True add_regex=True add_number=True add_boolean=True add_named_pattern=True add_nothing=True)
get_value : Text | Integer -> Integer -> Any -> Any
get_value self selector:(Text | Integer)=0 index:Integer=0 ~if_missing=Nothing =
col = self.get selector if_missing=Nothing
@ -400,7 +401,7 @@ type Table
table.select_columns [..By_Type ..Integer]
@columns (Widget_Helpers.make_column_name_multi_selector add_regex=True add_by_type=True)
select_columns : Vector (Integer | Text | Regex | By_Type) | Text | Integer | Regex | By_Type -> Boolean -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns
select_columns self (columns : (Vector | Text | Integer | Regex | By_Type) = [self.columns.first.name]) (reorder:Boolean=False) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) (error_on_missing_columns:Boolean=True) (on_problems:Problem_Behavior=..Report_Warning) =
select_columns self (columns : (Vector | Text | Integer | Regex | By_Type) = [self.columns.first.name]) (reorder:Boolean=False) (case_sensitivity:Case_Sensitivity=..Default) (error_on_missing_columns:Boolean=True) (on_problems:Problem_Behavior=..Report_Warning) =
new_columns = self.columns_helper.select_columns columns case_sensitivity reorder error_on_missing_columns on_problems
Table.new new_columns
@ -421,7 +422,7 @@ type Table
select_columns_by_type self types:Vector strict:Boolean=False =
new_columns = self.columns_helper.select_by_type types strict
result = Table.new new_columns
Warning.attach (Deprecated.Warning "Standard.Database.Table.Table" "select_columns_by_type" "Deprecated: use `select_columns` with a `By_Type` instead.") result
Warning.attach (Deprecated.Warning "Standard.Table.Table.Table" "select_columns_by_type" "Deprecated: use `select_columns` with a `By_Type` instead.") result
## ALIAS drop fields, drop_columns, remove fields, select columns, select fields
GROUP Standard.Base.Selections
@ -480,7 +481,7 @@ type Table
table.remove_columns [..By_Type ..Integer]
@columns (Widget_Helpers.make_column_name_multi_selector add_regex=True add_by_type=True)
remove_columns : Vector (Integer | Text | Regex | By_Type) | Text | Integer | Regex | By_Type -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns
remove_columns self (columns : (Vector | Text | Integer | Regex | By_Type) = [self.columns.first.name]) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) (error_on_missing_columns:Boolean=False) (on_problems:Problem_Behavior=..Report_Warning) =
remove_columns self (columns : (Vector | Text | Integer | Regex | By_Type) = [self.columns.first.name]) (case_sensitivity:Case_Sensitivity=..Default) (error_on_missing_columns:Boolean=False) (on_problems:Problem_Behavior=..Report_Warning) =
new_columns = self.columns_helper.remove_columns columns case_sensitivity error_on_missing_columns=error_on_missing_columns on_problems=on_problems
Table.new new_columns
@ -501,7 +502,7 @@ type Table
remove_columns_by_type self types:Vector strict:Boolean=False =
new_columns = self.columns_helper.remove_by_type types strict
result = Table.new new_columns
Warning.attach (Deprecated.Warning "Standard.Database.Table.Table" "remove_columns_by_type" "Deprecated: use `remove_columns` with a `By_Type` instead.") result
Warning.attach (Deprecated.Warning "Standard.Table.Table.Table" "remove_columns_by_type" "Deprecated: use `remove_columns` with a `By_Type` instead.") result
## ALIAS select_blank_fields, select_missing_columns, select_na
GROUP Standard.Base.Selections
@ -525,7 +526,7 @@ type Table
table.select_blank_columns
select_blank_columns : Blank_Selector -> Boolean -> Table ! No_Output_Columns
select_blank_columns self (when : Blank_Selector = Blank_Selector.All_Cells) (treat_nans_as_blank : Boolean = False) =
select_blank_columns self (when : Blank_Selector = ..All_Cells) (treat_nans_as_blank : Boolean = False) =
new_columns = self.columns_helper.select_blank_columns_helper when treat_nans_as_blank
Table.new new_columns
@ -551,7 +552,7 @@ type Table
table.remove_blank_columns
remove_blank_columns : Blank_Selector -> Boolean -> Table ! No_Output_Columns
remove_blank_columns self (when : Blank_Selector = Blank_Selector.All_Cells) (treat_nans_as_blank : Boolean = False) =
remove_blank_columns self (when : Blank_Selector = ..All_Cells) (treat_nans_as_blank : Boolean = False) =
new_columns = self.columns_helper.select_blank_columns_helper when treat_nans_as_blank invert_selection=True
Table.new new_columns
@ -635,7 +636,7 @@ type Table
table.reorder_columns Sort_Direction.Descending
sort_columns : Sort_Direction -> Text_Ordering -> Table
sort_columns self order:Sort_Direction=Sort_Direction.Ascending text_ordering:Text_Ordering=Text_Ordering.Default =
sort_columns self order:Sort_Direction=..Ascending text_ordering:Text_Ordering=..Default =
new_columns = Table_Helpers.sort_columns self.columns order text_ordering
Table.new new_columns
@ -707,7 +708,7 @@ type Table
table.rename_columns (Map.from_vector [["name=(.*)".to_regex, "key:$1"]])
@column_map Widget_Helpers.make_rename_name_vector_selector
rename_columns : Map (Text | Integer | Regex) Text | Vector Text | Vector Vector -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Ambiguous_Column_Rename | Too_Many_Column_Names_Provided | Invalid_Column_Names | Duplicate_Output_Column_Names
rename_columns self (column_map:(Table | Map | Vector)=["Column"]) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) (error_on_missing_columns:Boolean=True) (on_problems:Problem_Behavior=..Report_Warning) = case column_map of
rename_columns self (column_map:(Table | Map | Vector)=["Column"]) (case_sensitivity:Case_Sensitivity=..Default) (error_on_missing_columns:Boolean=True) (on_problems:Problem_Behavior=..Report_Warning) = case column_map of
_ : Table ->
resolved = Table_Helpers.read_name_map_from_table column_map
self.rename_columns resolved case_sensitivity error_on_missing_columns on_problems
@ -830,7 +831,7 @@ type Table
if validated.old_style.not then Table.Value java_table else
Warning.attach (Deprecated.Warning "Standard.Table.Aggregate_Column.Aggregate_Column" "Group_By" "Deprecated: `Group_By` constructor has been deprecated, use the `group_by` argument instead.") (Table.Value java_table)
## ALIAS sort
## ALIAS order_by
GROUP Standard.Base.Selections
ICON order
Sorts the rows of the table according to the specified columns and order.
@ -863,40 +864,40 @@ type Table
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`.
table.order_by ['Quantity']
table.sort ['Quantity']
> Example
Sorting `table` in descending order by the value in column `'Quantity'`.
table.order_by [Sort_Column.Name 'Quantity' Sort_Direction.Descending]
table.sort [Sort_Column.Name 'Quantity' Sort_Direction.Descending]
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`,
using the value in column `'Rating'` for breaking ties.
table.order_by ['Quantity', 'Rating']
table.sort ['Quantity', 'Rating']
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`,
using the value in column `'Rating'` in descending order for breaking
ties.
table.order_by [Sort_Column.Name 'Quantity', Sort_Column.Name 'Rating' Sort_Direction.Descending]
table.sort [..Name 'Quantity', ..Name 'Rating' ..Descending]
> Example
Order the table by the second column in ascending order. In case of any
ties, break them based on the 7th column from the end of the table in
descending order.
table.order_by [1, Sort_Column.Index -7 Sort_Direction.Descending]
table.sort [1, ..Index -7 ..Descending]
> Example
Sort the table by columns whose names start with letter `a`.
table.order_by [(Sort_Column.Select_By_Name "a.*".to_regex case_sensitivity=Case_Sensitivity.Insensitive)]
table.sort [(..Select_By_Name "a.*".to_regex case_sensitivity=..Insensitive)]
@columns Widget_Helpers.make_order_by_selector
order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
order_by self (columns = [self.columns.first.name]) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
sort : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
sort self (columns = [self.columns.first.name]) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder
problem_builder.attach_problems_before on_problems <|
@ -916,6 +917,16 @@ type Table
self.java_table.orderBy java_columns directions comparator
Table.Value java_table
## PRIVATE
GROUP Standard.Base.Selections
ICON order
Deprecated - use `Table.sort` instead.
@columns Widget_Helpers.make_order_by_selector
order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns
order_by self (columns = [self.columns.first.name]) text_ordering:Text_Ordering=..Default error_on_missing_columns:Boolean=True on_problems:Problem_Behavior=..Report_Warning =
result = self.sort columns text_ordering error_on_missing_columns on_problems
Warning.attach (Deprecated.Warning "Standard.Table.Table.Table" "order_by" "Deprecated: use `sort` instead.") result
## ALIAS deduplicate, unique
GROUP Standard.Base.Selections
ICON preparation
@ -954,7 +965,7 @@ type Table
setting.
@columns Widget_Helpers.make_column_name_multi_selector
distinct : Vector (Integer | Text | Regex) | Text | Integer | Regex -> Case_Sensitivity -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
distinct self (columns = self.column_names) case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default on_problems:Problem_Behavior=..Report_Warning =
distinct self (columns = self.column_names) case_sensitivity:Case_Sensitivity=..Default on_problems:Problem_Behavior=..Report_Warning =
key_columns = self.columns_helper.select_columns columns Case_Sensitivity.Default reorder=True error_on_missing_columns=True on_problems=on_problems . catch No_Output_Columns _->
Error.throw No_Input_Columns_Selected
java_columns = key_columns.map c->c.java_column
@ -1282,9 +1293,9 @@ type Table
new_column = column_to_cast.cast value_type on_problems
table.set new_column as=column_to_cast.name set_mode=Set_Mode.Update
## GROUP Standard.Base.Conversions
## ALIAS auto_value_types
GROUP Standard.Base.Conversions
ICON convert
ALIAS auto_value_types
Change the value type of table columns to a more specific one, based on
their contents.
@ -1440,7 +1451,7 @@ type Table
be reported according to the `on_problems` behavior.
@column Widget_Helpers.make_column_name_selector
tokenize_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Columns_To_Add -> Problem_Behavior -> Table
tokenize_to_columns self column pattern="." case_sensitivity:Case_Sensitivity=Case_Sensitivity.Sensitive (column_count : Columns_To_Add = ..All_Columns) on_problems:Problem_Behavior=..Report_Warning =
tokenize_to_columns self column pattern="." case_sensitivity:Case_Sensitivity=..Sensitive (column_count : Columns_To_Add = ..All_Columns) on_problems:Problem_Behavior=..Report_Warning =
Split_Tokenize.tokenize_to_columns self column pattern case_sensitivity column_count on_problems
## GROUP Standard.Base.Conversions
@ -1461,7 +1472,7 @@ type Table
Equivalent to converting a tokenization output of [] to [Nothing].
@column Widget_Helpers.make_column_name_selector
tokenize_to_rows : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Table
tokenize_to_rows self column pattern="." case_sensitivity:Case_Sensitivity=Case_Sensitivity.Sensitive at_least_one_row:Boolean=False =
tokenize_to_rows self column pattern="." case_sensitivity:Case_Sensitivity=..Sensitive at_least_one_row:Boolean=False =
Split_Tokenize.tokenize_to_rows self column pattern case_sensitivity at_least_one_row
## GROUP Standard.Base.Conversions
@ -1493,7 +1504,7 @@ type Table
@column Widget_Helpers.make_column_name_selector
@pattern Widget.Text_Input
parse_to_columns : Text | Integer -> Text | Regex -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table
parse_to_columns self column pattern="." case_sensitivity:Case_Sensitivity=Case_Sensitivity.Sensitive parse_values=True on_problems:Problem_Behavior=..Report_Error =
parse_to_columns self column pattern="." case_sensitivity:Case_Sensitivity=..Sensitive parse_values=True on_problems:Problem_Behavior=..Report_Error =
Split_Tokenize.parse_to_columns self column pattern case_sensitivity parse_values on_problems
## GROUP Standard.Base.Calculations
@ -1508,7 +1519,7 @@ type Table
@column Widget_Helpers.make_column_name_selector
@fields (Widget.Vector_Editor item_editor=Widget.Text_Input item_default='""')
expand_column : Text | Integer -> (Vector Text) | Nothing -> Prefix_Name -> Table ! Type_Error | No_Such_Column | Index_Out_Of_Bounds
expand_column self (column : Text | Integer) (fields : (Vector Text) | Nothing = Nothing) (prefix : Prefix_Name = Prefix_Name.Column_Name) =
expand_column self (column : Text | Integer) (fields : (Vector Text) | Nothing = Nothing) (prefix : Prefix_Name = ..Column_Name) =
Expand_Objects_Helpers.expand_column self column fields prefix
## GROUP Standard.Base.Calculations
@ -1651,12 +1662,12 @@ type Table
people.filter_by_expression "[age] % 10 == 0"
filter_by_expression : Text -> Problem_Behavior -> Table ! No_Such_Column | Invalid_Value_Type | Expression_Error
filter_by_expression self expression on_problems:Problem_Behavior=..Report_Warning =
filter_by_expression self expression:Text on_problems:Problem_Behavior=..Report_Warning =
column = self.evaluate_expression (Expression.Value expression) on_problems
result = self.filter column Filter_Condition.Is_True
Warning.attach (Deprecated.Warning "Standard.Table.Table.Table" "filter_by_expression" "Deprecated: use `filter` with an `Expression` instead.") result
## ALIAS first, head, last, limit, sample, slice, tail, top, keep
## ALIAS first, head, keep, last, limit, sample, slice, tail, top
GROUP Standard.Base.Selections
ICON select_row
Creates a new Table with the specified range of rows from the input
@ -1688,7 +1699,7 @@ type Table
take self range:(Index_Sub_Range | Range | Integer)=(..First 1) =
Index_Sub_Range_Module.take_helper self.row_count (self.rows.at _) self.slice (slice_ranges self) range
## ALIAS skip, remove
## ALIAS remove, skip
GROUP Standard.Base.Selections
ICON select_row
Creates a new Table from the input with the specified range of rows
@ -1889,7 +1900,7 @@ type Table
- map: The `Map` to create the table from.
- key_column_name: The name to use for the first column.
- value_column_name: The name to use for the second column.
make_table_from_map : Map Any Any -> Text -> Text -> Table
make_table_from_map : Map Any Any -> Text -> Text -> Table
make_table_from_map self map key_column_name value_column_name =
keys_and_values = map.to_vector
self.make_table_from_vectors [keys_and_values.map .first, keys_and_values.map .second] [key_column_name, value_column_name]
@ -2268,6 +2279,7 @@ type Table
# 1 | 20 | b | f
# 2 | 30 | c | g
# 3 | 40 | d | h
@lookup_table Widget_Helpers.make_replace_selector
@columns (Widget_Helpers.make_column_name_multi_selector add_regex=True add_by_type=True)
@from_column Widget.Text_Input
@to_column Widget.Text_Input

View File

@ -51,11 +51,11 @@ type Faker
string_value self template =
case template of
_ : Text ->
char_vector = template.char_vector.map c-> case c of
char_vector = template.characters.map c-> case c of
"A" -> Faker.upper_case_letters
"a" -> Faker.lower_case_letters
"0" -> Faker.numbers
_ -> c
_ -> [c]
self.string_value char_vector
_ ->
characters = template.map possible_chars->

View File

@ -7,17 +7,17 @@ goal_placeholder = "__$$GOAL$$__"
## PRIVATE
Table.build_ai_prompt self =
ops = ["aggregate","filter_by_expression","order_by","row_count","set","select_columns","transpose","join"]
ops = ["aggregate","filter_by_expression","sort","row_count","set","select_columns","transpose","join"]
aggs = ["Count","Average","Sum","Median","First","Last","Maximum","Minimum"]
joins = ["Inner","Left_Outer","Right_Outer","Full","Left_Exclusive","Right_Exclusive"]
examples = """
Table["id","category","Unit Price","Stock"];goal=get product count by category==>>`aggregate ["category"] [Aggregate_Column.Count]`
Table["ID","Unit Price","Stock"];goal=order by how many items are available==>>`order_by ["Stock"]`
Table["ID","Unit Price","Stock"];goal=order by how many items are available==>>`sort ["Stock"]`
Table["Name","Enrolled Year"];goal=select people who enrolled between 2015 and 2018==>>`filter_by_expression "[Enrolled Year] >= 2015 && [Enrolled Year] <= 2018`
Table["Number of items","client name","city","unit price"];goal=compute the total value of each order==>>`set "[Number of items] * [unit price]" "total value"`
Table["Number of items","client name","CITY","unit price","total value"];goal=compute the average order value by city==>>`aggregate ["CITY"] [Aggregate_Column.Average "total value"]`
Table["Area Code", "number"];goal=get full phone numbers==>>`set "'+1 (' + [Area Code] + ') ' + [number]" "full phone number"`
Table["Name","Grade","Subject"];goal=rank students by their average grade==>>`aggregate ["Name"] [Aggregate_Column.Average "Grade" "Average Grade"] . order_by [Sort_Column.Name "Average Grade" Sort_Direction.Descending]`
Table["Name","Grade","Subject"];goal=rank students by their average grade==>>`aggregate ["Name"] [Aggregate_Column.Average "Grade" "Average Grade"] . sort [Sort_Column.Name "Average Grade" Sort_Direction.Descending]`
Table["Country","Prime minister name","2018","2019","2020","2021"];goal=pivot yearly GDP values to rows==>>`transpose ["Country", "Prime minister name"] "Year" "GDP"`
Table["Size","Weight","Width","stuff","thing"];goal=only select size and thing of each record==>>`select_columns ["Size", "thing"]`
Table["ID","Name","Count"];goal=join it with var_17==>>`join var_17 Join_Kind.Inner`

View File

@ -46,7 +46,7 @@ collect_benches = Bench.build builder->
if extended_tests then
# Comparing `add_row_number` to similar table ops
group_builder.specify "Sort_Table" <|
data.table.order_by "X"
data.table.sort "X"
group_builder.specify "Group_And_Sort" <|
data.table.aggregate ["X"] [Aggregate_Column.Last "Y" order_by="Y"]

View File

@ -50,14 +50,14 @@ collect_benches = Bench.build builder->
data = Data.create
builder.group "Table_Sorting" table_sort_opts group_builder->
group_builder.specify "table_order_by_ints" <|
data.ints_table.order_by [Sort_Column.Index 0]
group_builder.specify "table_sort_ints" <|
data.ints_table.sort [..Index 0]
group_builder.specify "table_order_by_dates" <|
data.dates_table.order_by [Sort_Column.Index 0]
group_builder.specify "table_sort_dates" <|
data.dates_table.sort [..Index 0]
group_builder.specify "table_order_by_objects" <|
data.objects_table.order_by [Sort_Column.Index 0]
group_builder.specify "table_sort_objects" <|
data.objects_table.sort [..Index 0]
builder.group "Vector_Sorting" vec_sort_opts group_builder->
group_builder.specify "vector_sort_ints" <|

View File

@ -43,7 +43,7 @@ add_specs suite_builder setup =
group_builder.specify "should rename existing column upon a name clash" <|
t1 = table_builder [["X", ['a', 'b']], ["Y", ['c', 'd']], ["Z", [40, 20]]]
t2 = t1.add_row_number name="Y" order_by=["X"] |> materialize |> _.order_by "X"
t2 = t1.add_row_number name="Y" order_by=["X"] |> materialize |> _.sort "X"
t2.column_names . should_equal ["X", "Y 1", "Z", "Y"]
t2.at "X" . to_vector . should_equal ['a', 'b']
@ -57,7 +57,7 @@ add_specs suite_builder setup =
group_builder.specify "should allow to order the row numbers by some columns" <|
t2 = table_builder [["X", ["a", "b", "a", "a"]], ["Y", [1, 2, 3, 4]]]
t3 = t2.add_row_number order_by=["X", (Sort_Column.Name "Y" Sort_Direction.Descending)] |> materialize |> _.order_by "Y"
t3 = t2.add_row_number order_by=["X", (Sort_Column.Name "Y" Sort_Direction.Descending)] |> materialize |> _.sort "Y"
t3.at "Y" . to_vector . should_equal [1, 2, 3, 4]
t3.at "Row" . to_vector . should_equal [3, 4, 2, 1]
@ -67,7 +67,7 @@ add_specs suite_builder setup =
vr = [1, 2, 3, 4, 5, 6, 7, 8]
t = table_builder [["X", vx], ["Y", vy], ["row_id", vr]]
# The row id is added to enforce a clear ordering in Database
t1 = t.add_row_number group_by=["X"] order_by=["Y"] from=100 step=100 |> materialize |> _.order_by "row_id"
t1 = t.add_row_number group_by=["X"] order_by=["Y"] from=100 step=100 |> materialize |> _.sort "row_id"
t1.at "X" . to_vector . should_equal vx
t1.at "Y" . to_vector . should_equal vy
@ -75,20 +75,20 @@ add_specs suite_builder setup =
group_builder.specify "should report floating point equality warning when grouping on float columns" <|
t = table_builder [["X", [1.0, 1.5, 1.0, 2.5, 2.5]], ["row_id", [1, 2, 3, 4, 5]]]
t1 = t.add_row_number group_by=["X"] order_by=["row_id"] |> materialize |> _.order_by "row_id"
t1 = t.add_row_number group_by=["X"] order_by=["row_id"] |> materialize |> _.sort "row_id"
Problems.expect_warning Floating_Point_Equality t1
t1.at "Row" . to_vector . should_equal [1, 1, 2, 1, 2]
r2 = t.add_row_number group_by=["X"] order_by=["row_id"] on_problems=Problem_Behavior.Report_Error
r2.should_fail_with Floating_Point_Equality
t3 = t.add_row_number order_by=["X"] |> materialize |> _.order_by "row_id"
t3 = t.add_row_number order_by=["X"] |> materialize |> _.sort "row_id"
Problems.assume_no_problems t3
t3.at "Row" . to_vector . should_equal [1, 3, 2, 4, 5]
if setup.is_database.not then
t4 = table_builder [["X", [1, "A", 1, 24.0, 24.0, 24.0, 24]], ["row_id", [1, 2, 3, 4, 5, 6, 7]]]
t5 = t4.add_row_number group_by=["X"] order_by=["row_id"] |> materialize |> _.order_by "row_id"
t5 = t4.add_row_number group_by=["X"] order_by=["row_id"] |> materialize |> _.sort "row_id"
Problems.expect_warning Floating_Point_Equality t5
t5.at "Row" . to_vector . should_equal [1, 1, 2, 1, 2, 3, 4]
@ -107,7 +107,7 @@ add_specs suite_builder setup =
group_builder.specify "will respect the row order of order_by" <|
t = table_builder [["X", [1, 2, 3, 4]], ["Y", [40, 30, 20, 10]]]
t1 = t.order_by "Y"
t1 = t.sort "Y"
t2 = t1.add_row_number
@ -119,7 +119,7 @@ add_specs suite_builder setup =
t0 = table_builder [["X", ["a", "b", "a", "c"]], ["Y", [1, 2, 4, 8]]]
t1 = t0.aggregate ["X"] [Aggregate_Column.Sum "Y"]
t2 = t1.order_by "X" . add_row_number
t2 = t1.sort "X" . add_row_number
t2.at "X" . to_vector . should_equal ['a', 'b', 'c']
t2.at "Sum Y" . to_vector . should_equal [5.0, 2.0, 8.0]
t2.at "Row" . to_vector . should_equal [1, 2, 3]
@ -233,7 +233,7 @@ add_specs suite_builder setup =
src = table_builder [["X", [500, 400, 30, 1, 2]], ["Y", [10, 20, 30, 40, 50]]]
db_table = src.select_into_database_table data.connection (Name_Generator.random_name "add-row-number-test-1") temporary=True primary_key=["X"]
t2 = db_table.add_row_number |> materialize |> _.order_by ["Y"]
t2 = db_table.add_row_number |> materialize |> _.sort ["Y"]
t2.at "Y" . to_vector . should_equal [10, 20, 30, 40, 50]
t2.at "X" . to_vector . should_equal [500, 400, 30, 1, 2]
t2.at "Row" . to_vector . should_equal [5, 4, 3, 1, 2]

View File

@ -944,7 +944,7 @@ add_specs suite_builder setup =
table = table_builder [["A", ["foo", "bar", "foo", "foo"]], ["B", ["a", "b", "c", "d"]]]
result = table.aggregate ["A"] [Concatenate "B" prefix="[[" suffix="]]" separator="; "]
result.row_count . should_equal 2
materialized = materialize result . order_by ([Sort_Column.Name "A"])
materialized = materialize result . sort ([..Name "A"])
Problems.assume_no_problems materialized
materialized.column_count . should_equal 2
materialized.columns.at 0 . name . should_equal "A"
@ -1055,14 +1055,14 @@ add_specs suite_builder setup =
r1 = t5.aggregate ["G"] [Count_Distinct "A" (ignore_nothing=True)]
r1.row_count . should_equal 2
m1 = materialize r1 . order_by ([Sort_Column.Name "G"])
m1 = materialize r1 . sort ([..Name "G"])
m1.column_count . should_equal 2
m1.columns.first.to_vector . should_equal ["bar", "foo"]
m1.columns.second.to_vector . should_equal [0, 1]
r2 = t5.aggregate ["G"] [Count_Distinct "A" (ignore_nothing=False)]
r2.row_count . should_equal 2
m2 = materialize r2 . order_by ([Sort_Column.Name "G"])
m2 = materialize r2 . sort ([..Name "G"])
m2.column_count . should_equal 2
m2.columns.first.to_vector . should_equal ["bar", "foo"]
m2.columns.second.to_vector . should_equal [1, 2]
@ -1120,7 +1120,7 @@ add_specs suite_builder setup =
r2 = table.aggregate ["G"] [Average "X"]
r2.row_count.should_equal 2
m2 = materialize r2 . order_by ([Sort_Column.Name "G"])
m2 = materialize r2 . sort ([..Name "G"])
m2.column_count . should_equal 2
m2.columns.first.to_vector . should_equal ["a", "b"]
m2.columns.second.to_vector . should_equal [0.5, 1]
@ -1347,7 +1347,7 @@ add_specs suite_builder setup =
table = table_builder [["A", [1, 1, 2, 1]], ["B", [3, 2, 2, 3]], ["C", [11, 12, 13, 14]]]
grouped = table.aggregate ["B", "A"]
grouped.row_count . should_equal 3
materialized = materialize grouped . order_by ([Sort_Column.Name "A", Sort_Column.Name "B"])
materialized = materialize grouped . sort ([..Name "A", ..Name "B"])
Problems.assume_no_problems materialized
materialized.column_count . should_equal 2
materialized.columns.at 1 . name . should_equal "A"
@ -1360,7 +1360,7 @@ add_specs suite_builder setup =
table = table_builder [["A", ['s', 's\u0301', 'ś', 's\u0301']], ["B", [1, 2, 4, 8]]]
grouped = table.aggregate ["A"] [Sum "B"]
grouped.row_count . should_equal 2
materialized = materialize grouped . order_by ["A"]
materialized = materialize grouped . sort ["A"]
Problems.assume_no_problems materialized
materialized.column_count . should_equal 2
materialized.columns.at 0 . name . should_equal "A"
@ -1377,17 +1377,17 @@ add_specs suite_builder setup =
table = table_builder [dates, times, datetimes, ints]
g1 = table.aggregate ["Date"] [Sum "Int"]
m1 = materialize g1 . order_by (["Date"])
m1 = materialize g1 . sort (["Date"])
m1.at "Date" . to_vector . should_equal [Date.new 1997, Date.new 2000 2 2, Date.new 2022 12 31]
m1.at "Sum Int" . to_vector . should_equal [17, 10, 4]
g2 = table.aggregate ["Time"] [Sum "Int"]
m2 = materialize g2 . order_by (["Time"])
m2 = materialize g2 . sort (["Time"])
m2.at "Time" . to_vector . should_equal [Time_Of_Day.new, Time_Of_Day.new 0 0 0 500, Time_Of_Day.new 1 2 3, Time_Of_Day.new 11 25 40]
m2.at "Sum Int" . to_vector . should_equal [9, 2, 4, 16]
g3 = table.aggregate ["DateTime"] [Sum "Int"]
m3 = materialize g3 . order_by (["DateTime"])
m3 = materialize g3 . sort (["DateTime"])
## The DB may change the timezone of the values, so we need to convert them back to be able to check for equality.
All that we require is that the instant in time represented by the values is preserved.
at_system_tz dt =
@ -1431,7 +1431,7 @@ add_specs suite_builder setup =
table = table_builder [["Index", [1, 1, 2, 2]], ["Value", [1, 2, 3, 4]]]
t1 = table.aggregate ["Index"] [Sum "Value", Sum (expr "[Value]*[Value]")]
t1.column_count . should_equal 3
r1 = t1 |> materialize |> _.order_by "Index"
r1 = t1 |> materialize |> _.sort "Index"
r1.at "Index" . to_vector . should_equal [1, 2]
r1.at "Sum Value" . to_vector . should_equal [3, 7]
# Not using by name, as naming is not yet consistent between backends.

View File

@ -183,7 +183,7 @@ add_specs suite_builder setup =
t3 = t1.join t2 on='ś'
t3.column_names . should_equal ['ś', 'X', 'Right ś', 'Y']
m3 = materialize t3 . order_by 'ś'
m3 = materialize t3 . sort 'ś'
m3.at 'ś' . to_vector . should_equal [1, 2]
m3.at 'X' . to_vector . should_equal ['a', 'b']
m3.at 'Right ś' . to_vector . should_equal [1, 2]

View File

@ -36,7 +36,7 @@ add_specs suite_builder setup =
a = ["A", ["a", "b", "a", "b", "a", "b"]]
b = ["B", [2, 1, 2, 2, 2, 1]]
t = table_builder [a, b]
r = t.distinct on_problems=Report_Error |> materialize |> _.order_by ["A", "B"]
r = t.distinct on_problems=Report_Error |> materialize |> _.sort ["A", "B"]
r.at "A" . to_vector . should_equal ["a", "b", "b"]
r.at "B" . to_vector . should_equal [2, 1, 2]
@ -51,7 +51,7 @@ add_specs suite_builder setup =
r1.at "B" . to_vector . should_equal [1]
r1.at "C" . to_vector . should_equal [0.1]
r2 = t.distinct ["A", "B"] on_problems=Report_Error |> materialize |> _.order_by "B"
r2 = t.distinct ["A", "B"] on_problems=Report_Error |> materialize |> _.sort "B"
r2.at "A" . to_vector . should_equal ["a", "a"]
r2.at "B" . to_vector . should_equal [1, 2]
cv = r2.at "C" . to_vector
@ -63,9 +63,9 @@ add_specs suite_builder setup =
a = ["A", ["a", "a", "a", "a", "a", "a"]]
b = ["B", [1, 1, 2, 2, 1, 2]]
c = ["C", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]]
t = table_builder [a, b, c] . order_by ([(Sort_Column.Name "C" Sort_Direction.Descending)])
t = table_builder [a, b, c] . sort ([(..Name "C" ..Descending)])
r2 = t.distinct ["A", "B"] on_problems=Report_Error |> materialize |> _.order_by "B"
r2 = t.distinct ["A", "B"] on_problems=Report_Error |> materialize |> _.sort "B"
r2.at "A" . to_vector . should_equal ["a", "a"]
r2.at "B" . to_vector . should_equal [1, 2]
r2.at "C" . to_vector . should_equal [0.5, 0.6]
@ -73,10 +73,10 @@ add_specs suite_builder setup =
group_builder.specify "should allow to control case-sensitivity of keys" <|
x = ["X", ['A', 'a', 'enso', 'Enso', 'A']]
t1 = table_builder [x]
d1 = t1.distinct ["X"] on_problems=Report_Error |> materialize |> _.order_by ["X"]
d1 = t1.distinct ["X"] on_problems=Report_Error |> materialize |> _.sort ["X"]
d1.at "X" . to_vector . should_equal ['A', 'Enso', 'a', 'enso']
d2 = t1.distinct ["X"] case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error |> materialize |> _.order_by ["X"]
d2 = t1.distinct ["X"] case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error |> materialize |> _.sort ["X"]
v = d2.at "X" . to_vector
v.length . should_equal 2
v.filter (_.equals_ignore_case "enso") . length . should_equal 1
@ -96,7 +96,7 @@ add_specs suite_builder setup =
a = ["A", ["a", Nothing, "b", "a", "b", Nothing, "a", "b"]]
b = ["B", [1, 2, 3, 4, 5, 6, 7, 8]]
t = table_builder [a, b]
r = t.distinct ["A"] on_problems=Report_Error |> materialize |> _.order_by "A"
r = t.distinct ["A"] on_problems=Report_Error |> materialize |> _.sort "A"
va = r.at "A" . to_vector
vb = r.at "B" . to_vector
va . should_equal [Nothing, "a", "b"]
@ -142,7 +142,7 @@ add_specs suite_builder setup =
a = ["A", ["a", "a", "b", "b", "c"]]
b = ["B", [1, 1, 1, 2, 1]]
t = table_builder [a, b]
r = t.duplicates on_problems=Report_Error |> materialize |> _.order_by ["A", "B"]
r = t.duplicates on_problems=Report_Error |> materialize |> _.sort ["A", "B"]
r.at "A" . to_vector . should_equal ["a", "a"]
r.at "B" . to_vector . should_equal [1, 1]
@ -165,10 +165,10 @@ add_specs suite_builder setup =
group_builder.specify "should allow to control case-sensitivity of keys" <|
x = ["X", ['A', 'a', 'enso', 'Enso', 'A']]
t1 = table_builder [x]
d1 = t1.duplicates ["X"] on_problems=Report_Error |> materialize |> _.order_by ["X"]
d1 = t1.duplicates ["X"] on_problems=Report_Error |> materialize |> _.sort ["X"]
d1.at "X" . to_vector . should_equal ['A', 'A']
d2 = t1.duplicates ["X"] case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error |> materialize |> _.order_by ["X"]
d2 = t1.duplicates ["X"] case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error |> materialize |> _.sort ["X"]
d2.at "X" . to_vector . should_equal ['A', 'A', 'Enso', 'a', 'enso']
group_builder.specify "should report a warning if the key contains floating point values" <|
@ -185,7 +185,7 @@ add_specs suite_builder setup =
a = ["A", ["a", Nothing, "b", Nothing]]
b = ["B", [1, 2, 3, 4]]
t = table_builder [a, b]
r = t.duplicates ["A"] on_problems=Report_Error |> materialize |> _.order_by "B"
r = t.duplicates ["A"] on_problems=Report_Error |> materialize |> _.sort "B"
r.at "A" . to_vector . should_equal [Nothing, Nothing]
r.at "B" . to_vector . should_equal [2, 4]

View File

@ -54,7 +54,7 @@ add_specs suite_builder setup =
t2 = table_builder [["Letter", ["A", "B", "A", "A", "C", "A", "C", "D", "D", "B", "B"]]]
t3 = t2.aggregate ["Letter"] [Aggregate_Column.Count]
t4 = t3.join t1 on="Count" join_kind=Join_Kind.Left_Outer |> materialize |> _.order_by "Letter"
t4 = t3.join t1 on="Count" join_kind=Join_Kind.Left_Outer |> materialize |> _.sort "Letter"
t4.columns.map .name . should_equal ["Letter", "Count", "Right Count", "Class"]
rows = t4.rows . map .to_vector
rows.at 0 . should_equal ["A", 4, Nothing, Nothing]
@ -66,7 +66,7 @@ add_specs suite_builder setup =
t2 = table_builder [["Letter", ["A", "B", "A", "A", "C", "C"]], ["Points", [2, 5, 2, 1, 10, 3]]]
t3 = t2.aggregate ["Letter"] [Aggregate_Column.Sum "Points"]
t4 = t3.distinct "Sum Points" |> materialize |> _.order_by "Sum Points"
t4 = t3.distinct "Sum Points" |> materialize |> _.sort "Sum Points"
t4.columns.map .name . should_equal ["Letter", "Sum Points"]
t4.row_count . should_equal 2
@ -81,7 +81,7 @@ add_specs suite_builder setup =
t2 = table_builder [["Letter", ["A", "B", "A", "A", "C", "C", "B"]], ["Points", [2, 5, 2, 1, 10, 3, 0]]]
t3 = t2.aggregate ["Letter"] [Aggregate_Column.Sum "Points"]
t4 = t3.filter "Sum Points" (Filter_Condition.Equal 5) |> materialize |> _.order_by "Letter"
t4 = t3.filter "Sum Points" (Filter_Condition.Equal 5) |> materialize |> _.sort "Letter"
t4.columns.map .name . should_equal ["Letter", "Sum Points"]
rows = t4.rows . map .to_vector
rows.at 0 . should_equal ["A", 5]
@ -90,7 +90,7 @@ add_specs suite_builder setup =
group_builder.specify "aggregates and ordering" <|
t1 = table_builder [["Letter", ["C", "A", "B", "A", "A", "C", "C", "B"]], ["Points", [0, -100, 5, 2, 1, 10, 3, 0]]]
t2 = t1.aggregate ["Letter"] [Aggregate_Column.Sum "Points"]
t3 = t2.order_by "Sum Points" |> materialize
t3 = t2.sort "Sum Points" |> materialize
t3.columns.map .name . should_equal ["Letter", "Sum Points"]
t3.at "Letter" . to_vector . should_equal ["A", "B", "C"]
t3.at "Sum Points" . to_vector . should_equal [-97, 5, 13]
@ -99,11 +99,11 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [1, 2, 2, 1]], ["Y", ["a", "b", "b", "a"]], ["Z", [1, 2, 3, 4]]]
# These are 'adversarial' white-box examples constructed knowing that Postgres' DISTINCT ON does not play too well with ORDER BY and it needs to be handled carefully.
t2 = t1.order_by "X" . distinct "X" |> materialize
t2 = t1.sort "X" . distinct "X" |> materialize
t2.row_count . should_equal 2
t3 = t1.order_by "Y" . distinct "X" |> materialize
t3 = t1.sort "Y" . distinct "X" |> materialize
t3.row_count . should_equal 2
t4 = t1.order_by "Y" . distinct "X" . order_by "Y" |> materialize
t4 = t1.sort "Y" . distinct "X" . sort "Y" |> materialize
t4.row_count . should_equal 2
if setup.test_selection.distinct_returns_first_row_from_group_if_ordered then
@ -111,14 +111,14 @@ add_specs suite_builder setup =
a = ["A", ["a", "a", "a", "a", "a", "a"]]
b = ["B", [1, 1, 2, 2, 1, 2]]
c = ["C", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]]
t = (table_builder [a, b, c]) . order_by ([(Sort_Column.Name "C" Sort_Direction.Descending)])
t = (table_builder [a, b, c]) . sort ([(..Name "C" ..Descending)])
t2 = t.distinct ["A", "B"] on_problems=Report_Error
# Now, reverse the order!
## But the distinct was taken under descending order, so that
should be preserved - we will still have _last_ rows from
each group (first in reversed order).
t3 = t2.order_by "C"
t3 = t2.sort "C"
r = t3 |> materialize
r.at "A" . to_vector . should_equal ["a", "a"]
r.at "B" . to_vector . should_equal [1, 2]
@ -134,7 +134,7 @@ add_specs suite_builder setup =
a = ["A", ["a", "a", "b", "a", "b"]]
b = ["B", [1, 2, 5, 5, 2]]
c = ["C", [0.1, 0.2, 0.3, 0.4, 0.5]]
t = table_builder [a, b, c] . order_by "C"
t = table_builder [a, b, c] . sort "C"
t2 = t.distinct ["A"] on_problems=Report_Error
r2 = t2 |> materialize
@ -198,7 +198,7 @@ add_specs suite_builder setup =
Test.with_clue "t4[X].value_type="+vt2.to_display_text+": " <|
vt2.should_be_a (Value_Type.Char ...)
vt2.variable_length.should_be_true
t5 = t4 |> materialize |> _.order_by "Y"
t5 = t4 |> materialize |> _.sort "Y"
t5.at "Y" . to_vector . should_equal [0, 1, 2]
t5.at "Shortest X" . to_vector . should_equal ["b", "a", "c"]

View File

@ -150,8 +150,8 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [100, 2]], ["Y", [4, 5]]]
t2 = table_builder [["Z", ['a', 'b', 'c']], ["W", ['x', 'd', 'd']]]
t3 = t1.order_by "X"
t4 = t2.order_by ([Sort_Column.Name "Z" Sort_Direction.Descending])
t3 = t1.sort "X"
t4 = t2.sort ([..Name "Z" ..Descending])
t5 = t3.cross_join t4
expect_column_names ["X", "Y", "Z", "W"] t5

View File

@ -63,7 +63,7 @@ add_specs suite_builder setup =
group_builder.specify "should by default do a Left Outer join on equality of first column in the left table, correlated with column of the same name in the right one" <|
t3 = table_builder [["Z", [4, 5, 6, 7]], ["X", [2, 3, 2, 4]]]
t4 = data.t1.join t3 |> materialize |> _.order_by ["X", "Z"]
t4 = data.t1.join t3 |> materialize |> _.sort ["X", "Z"]
expect_column_names ["X", "Y", "Z", "Right X"] t4
t4.at "X" . to_vector . should_equal [1, 2, 2, 3]
t4.at "Y" . to_vector . should_equal [4, 5, 5, 6]
@ -73,7 +73,7 @@ add_specs suite_builder setup =
group_builder.specify "should allow Inner join" <|
t3 = data.t1.join data.t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals 0 0)
expect_column_names ["X", "Y", "Z", "W"] t3
t4 = t3 |> materialize |> _.order_by ["X", "W"]
t4 = t3 |> materialize |> _.sort ["X", "W"]
t4.at "X" . to_vector . should_equal [2, 2, 3]
t4.at "Z" . to_vector . should_equal [2, 2, 3]
t4.at "Y" . to_vector . should_equal [5, 5, 6]
@ -82,14 +82,14 @@ add_specs suite_builder setup =
group_builder.specify "should allow Inner join (autoscoped)" <|
t3 = data.t1.join data.t2 join_kind=..Inner on=(..Equals 0 0)
expect_column_names ["X", "Y", "Z", "W"] t3
t4 = t3 |> materialize |> _.order_by ["X", "W"]
t4 = t3 |> materialize |> _.sort ["X", "W"]
t4.at "X" . to_vector . should_equal [2, 2, 3]
t4.at "Z" . to_vector . should_equal [2, 2, 3]
t4.at "Y" . to_vector . should_equal [5, 5, 6]
t4.at "W" . to_vector . should_equal [4, 6, 5]
group_builder.specify "should allow Full join" <|
t3 = data.t1.join data.t2 join_kind=Join_Kind.Full on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X", "W"]
t3 = data.t1.join data.t2 join_kind=Join_Kind.Full on=(Join_Condition.Equals 0 0) |> materialize |> _.sort ["X", "W"]
expect_column_names ["X", "Y", "Z", "W"] t3
t3.at "X" . to_vector . should_equal [Nothing, 1, 2, 2, 3]
t3.at "Y" . to_vector . should_equal [Nothing, 4, 5, 5, 6]
@ -97,7 +97,7 @@ add_specs suite_builder setup =
t3.at "W" . to_vector . should_equal [7, Nothing, 4, 6, 5]
group_builder.specify "should allow Right Outer join" <|
t5 = data.t1.join data.t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X", "W"]
t5 = data.t1.join data.t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Equals 0 0) |> materialize |> _.sort ["X", "W"]
expect_column_names ["X", "Y", "Z", "W"] t5
t5.at "X" . to_vector . should_equal [Nothing, 2, 2, 3]
t5.at "Y" . to_vector . should_equal [Nothing, 5, 5, 6]
@ -105,12 +105,12 @@ add_specs suite_builder setup =
t5.at "W" . to_vector . should_equal [7, 4, 6, 5]
group_builder.specify "should allow to perform anti-joins" <|
t6 = data.t1.join data.t2 join_kind=Join_Kind.Left_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X"]
t6 = data.t1.join data.t2 join_kind=Join_Kind.Left_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.sort ["X"]
t6.columns.map .name . should_equal ["X", "Y"]
t6.at "X" . to_vector . should_equal [1]
t6.at "Y" . to_vector . should_equal [4]
t7 = data.t1.join data.t2 join_kind=Join_Kind.Right_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["Z"]
t7 = data.t1.join data.t2 join_kind=Join_Kind.Right_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.sort ["Z"]
t7.columns.map .name . should_equal ["Z", "W"]
t7.at "Z" . to_vector . should_equal [4]
t7.at "W" . to_vector . should_equal [7]
@ -124,7 +124,7 @@ add_specs suite_builder setup =
group_builder.specify "should allow to join on equality of multiple columns and drop redundant columns if Inner join" <|
conditions = [Join_Condition.Equals "Y" "Y", Join_Condition.Equals "X" "X"]
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=conditions |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=conditions |> materialize |> _.sort ["X", "Y", "Z", "Right Z"]
check_xy_joined r
[Join_Kind.Full, Join_Kind.Left_Outer, Join_Kind.Right_Outer].each kind->
@ -132,13 +132,13 @@ add_specs suite_builder setup =
expect_column_names ["X", "Y", "Z", "Right X", "Right Y", "Right Z"] r2
group_builder.specify "should support same-name column join shorthand" <|
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=["X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=["X", "Y"] |> materialize |> _.sort ["X", "Y", "Z", "Right Z"]
check_xy_joined r
group_builder.specify "should correctly handle duplicated rows in Equals" <|
t1 = table_builder [["X", [1, 2, 2, 3]]]
t2 = table_builder [["X", [1, 2, 2, 4]]]
r1 = t1.join t2 join_kind=Join_Kind.Full on="X" . order_by "X"
r1 = t1.join t2 join_kind=Join_Kind.Full on="X" . sort "X"
within_table r1 <|
# Both 2's from t1 match with _both_ ones from t2 _each_, so in total we get 4 `2` pairs:
r1.at "X" . to_vector . should_equal [Nothing, 1, 2, 2, 2, 2, 3]
@ -154,7 +154,7 @@ add_specs suite_builder setup =
r1 . at "Y" . to_vector . should_equal [1]
r1 . at "Z" . to_vector . should_equal [2]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Z"]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.sort ["Z"]
expect_column_names ["X", "Y", "Right X", "Z"] r2
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
r2 . at "Right X" . to_vector . should_equal ["A", "a", "b"]
@ -172,7 +172,7 @@ add_specs suite_builder setup =
r1 . at "Y" . to_vector . should_equal [1]
r1 . at "Z" . to_vector . should_equal [3]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Right X", "Z"] r2
r2 . at "X" . to_vector . should_equal ['s\u0301', 'S\u0301']
r2 . at "Right X" . to_vector . should_equal ['ś', 'ś']
@ -195,7 +195,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [My_Type.Value 1 2, My_Type.Value 2 3]], ["Y", [1, 2]]]
t2 = table_builder [["X", [My_Type.Value 5 0, My_Type.Value 2 1]], ["Z", [10, 20]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Z"] r1
r1 . at "X" . to_vector . should_equal [My_Type.Value 1 2, My_Type.Value 2 3]
## We don't keep the other column, because the values in both
@ -210,7 +210,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
t2 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
r1 = t1.join join_kind=Join_Kind.Inner t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
r1 = t1.join join_kind=Join_Kind.Inner t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.sort ["X", "Z"]
r1.column_names . should_equal ["X", "Y", "lower", "upper", "Z"]
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
@ -222,7 +222,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ["a", "b", "c"]], ["Y", [1, 2, 3]]]
t2 = table_builder [["lower", ["a", "b"]], ["upper", ["a", "ccc"]], ["Z", [10, 20]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.sort ["X", "Z"]
r1.column_names . should_equal ["X", "Y", "lower", "upper", "Z"]
r1 . at "X" . to_vector . should_equal ["a", "b", "c"]
r1 . at "Y" . to_vector . should_equal [1, 2, 3]
@ -238,7 +238,7 @@ add_specs suite_builder setup =
# 5. unmatched rows on both sides - Full join
t1 = table_builder [["X", [1, 10, 20, 1, 2, 1, 1]], ["id", [1, 2, 3, 4, 5, 7, 7]]]
t2 = table_builder [["lower", [0, 10, 10]], ["upper", [3, 10, 0]], ["Z", ['a', 'b', 'c']]]
r1 = t1.join t2 join_kind=Join_Kind.Full on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Z", "id"]
r1 = t1.join t2 join_kind=Join_Kind.Full on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.sort ["Z", "id"]
within_table r1 <|
r1.column_names . should_equal ["X", "id", "lower", "upper", "Z"]
rows = r1.rows.map .to_vector
@ -261,13 +261,13 @@ add_specs suite_builder setup =
t1 = table_builder [["X", pts.map .first], ["Y", pts.map .second]]
t2 = table_builder [["lx", [1]], ["ux", [3]], ["ly", [1]], ["uy", [2]]]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lx" "ux", Join_Condition.Between "Y" "ly" "uy"] |> materialize |> _.order_by ["X", "Y"]
r2 = t1.join t2 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lx" "ux", Join_Condition.Between "Y" "ly" "uy"] |> materialize |> _.sort ["X", "Y"]
within_table r2 <|
r2.at "X" . to_vector . should_equal [1, 1, 2, 3, 3]
r2.at "Y" . to_vector . should_equal [1, 2, 2, 1, 2]
t3 = table_builder [["lx", [1.9]], ["ux", [3]], ["ly", [1]], ["uy", [2]]]
r3 = t1.join t3 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lx" "ux", Join_Condition.Between "Y" "ly" "uy"] |> materialize |> _.order_by ["X", "Y"]
r3 = t1.join t3 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lx" "ux", Join_Condition.Between "Y" "ly" "uy"] |> materialize |> _.sort ["X", "Y"]
within_table r3 <|
r3.at "X" . to_vector . should_equal [2, 3, 3]
r3.at "Y" . to_vector . should_equal [2, 1, 2]
@ -293,7 +293,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ['s\u0301', 's']], ["Y", [1, 2]]]
t2 = table_builder [["lower", ['s', 'ś']], ["upper", ['sa', 'ś']], ["Z", [10, 20]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
r1 . at "X" . to_vector . should_equal ['s\u0301', 's']
r1 . at "Y" . to_vector . should_equal [1, 2]
@ -306,7 +306,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [My_Type.Value 20 30, My_Type.Value 1 2]], ["Y", [1, 2]]]
t2 = table_builder [["lower", [My_Type.Value 3 0, My_Type.Value 10 10]], ["upper", [My_Type.Value 2 1, My_Type.Value 100 0]], ["Z", [10, 20]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Z"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.sort ["Z"]
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
r1 . at "X" . to_vector . to_text . should_equal "[(My_Type.Value 1 2), (My_Type.Value 20 30)]"
r1 . at "Y" . to_vector . should_equal [2, 1]
@ -319,7 +319,7 @@ add_specs suite_builder setup =
t2 = table_builder [["X", [12, 12, 1]], ["l", [0, 100, 100]], ["u", [10, 100, 200]], ["Z", ["A", "A", "A"]], ["W'", [10, 20, 30]]]
conditions = [Join_Condition.Between "Y" "l" "u", Join_Condition.Equals_Ignore_Case "Z" "Z", Join_Condition.Equals "X" "X"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=conditions |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=conditions |> materialize |> _.sort ["Y"]
within_table r1 <|
r1.column_names.should_equal ["X", "Y", "Z", "W", "l", "u", "Right Z", "W'"]
r1.at "X" . to_vector . should_equal [12, 12]
@ -331,7 +331,7 @@ add_specs suite_builder setup =
r1.at "Right Z" . to_vector . should_equal ["A", "A"]
r1.at "W'" . to_vector . should_equal [10, 10]
r2 = t1.join t2 join_kind=Join_Kind.Left_Exclusive on=conditions |> materialize |> _.order_by ["Y"]
r2 = t1.join t2 join_kind=Join_Kind.Left_Exclusive on=conditions |> materialize |> _.sort ["Y"]
within_table r2 <|
r2.column_names.should_equal ["X", "Y", "Z", "W"]
r2.at "X" . to_vector . should_equal [1, 0]
@ -339,7 +339,7 @@ add_specs suite_builder setup =
r2.at "Z" . to_vector . should_equal ["a", "ą"]
r2.at "W" . to_vector . should_equal [1, 4]
r3 = t1.join t2 join_kind=Join_Kind.Right_Exclusive on=conditions |> materialize |> _.order_by ["W'"]
r3 = t1.join t2 join_kind=Join_Kind.Right_Exclusive on=conditions |> materialize |> _.sort ["W'"]
within_table r3 <|
r3.column_names.should_equal ["X", "l", "u", "Z", "W'"]
r3.at "X" . to_vector . should_equal [12, 1]
@ -349,13 +349,13 @@ add_specs suite_builder setup =
r3.at "W'" . to_vector . should_equal [20, 30]
group_builder.specify "should work fine if the same condition is specified multiple times" <|
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=["X", "X", "Y", "X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
r = data.t3.join data.t4 join_kind=Join_Kind.Inner on=["X", "X", "Y", "X", "Y"] |> materialize |> _.sort ["X", "Y", "Z", "Right Z"]
check_xy_joined r
t5 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
t6 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
r1 = t5.join t6 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper"] |> materialize |> _.order_by ["X", "Z"]
r1 = t5.join t6 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper"] |> materialize |> _.sort ["X", "Z"]
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
r1 . at "Z" . to_vector . should_equal [1, 2, 3, 2, 3]
@ -363,14 +363,14 @@ add_specs suite_builder setup =
t7 = table_builder [["X", ["a", "B"]], ["Y", [1, 2]]]
t8 = table_builder [["X", ["A", "a", "b"]], ["Z", [1, 2, 3]]]
r2 = t7.join t8 join_kind=Join_Kind.Inner on=[Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X" "X"] |> materialize |> _.order_by ["Z"]
r2 = t7.join t8 join_kind=Join_Kind.Inner on=[Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X" "X"] |> materialize |> _.sort ["Z"]
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
r2 . at "Right X" . to_vector . should_equal ["A", "a", "b"]
r2 . at "Z" . to_vector . should_equal [1, 2, 3]
group_builder.specify "should correctly handle joining a table with itself" <|
t1 = table_builder [["X", [0, 1, 2, 3, 2]], ["Y", [1, 2, 3, 4, 100]], ["A", ["B", "C", "D", "E", "X"]]]
t2 = t1.join t1 join_kind=Join_Kind.Inner on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y"]
t2 = t1.join t1 join_kind=Join_Kind.Inner on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.sort ["X", "Y"]
expect_column_names ["X", "Y", "A", "Right X", "Right Y", "Right A"] t2
t2.at "X" . to_vector . should_equal [1, 2, 2, 3]
@ -381,7 +381,7 @@ add_specs suite_builder setup =
t2.at "Right X" . to_vector . should_equal [0, 1, 1, 2]
t2.at "Right A" . to_vector . should_equal ["B", "C", "C", "D"]
t3 = t1.join t1 join_kind=Join_Kind.Full on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y", "Right X"]
t3 = t1.join t1 join_kind=Join_Kind.Full on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.sort ["X", "Y", "Right X"]
expect_column_names ["X", "Y", "A", "Right X", "Right Y", "Right A"] t3
t3.at "X" . to_vector . should_equal [Nothing, Nothing, 0, 1, 2, 2, 3]
t3.at "Right Y" . to_vector . should_equal [100, 4, Nothing, 1, 2, 2, 3]
@ -392,7 +392,7 @@ add_specs suite_builder setup =
t3.at "Right A" . to_vector . should_equal ["X", "E", Nothing, "B", "C", "C", "D"]
t4 = table_builder [["X", [Nothing, "a", "B", "c"]], ["Y", ["ą", "b", "C", Nothing]], ["Z", [1, 2, 3, 4]]]
t5 = t4.join t4 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case left="Y" right="X") |> materialize |> _.order_by ["Y"]
t5 = t4.join t4 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case left="Y" right="X") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Z", "Right X", "Right Y", "Right Z"] t5
within_table t5 <|
t5.at "X" . to_vector . should_equal ["B", "a"]
@ -459,7 +459,7 @@ add_specs suite_builder setup =
action1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Z") on_problems=_
tester1 table =
expect_column_names ["X", "Y", "Z", "W"] table
t1 = table.order_by ["Y", "W"]
t1 = table.sort ["Y", "W"]
t1.at "X" . to_vector . should_equal [1.5, 2.0, 2.0]
t1.at "Y" . to_vector . should_equal [10, 20, 20]
t1.at "Z" . to_vector . should_equal [1.5, 2.0, 2.0]
@ -470,7 +470,7 @@ add_specs suite_builder setup =
action2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "W") on_problems=_
tester2 table =
expect_column_names ["X", "Y", "Z", "W"] table
t1 = table.order_by ["Y", "W"]
t1 = table.sort ["Y", "W"]
t1.at "X" . to_vector . should_equal [2.0]
t1.at "Y" . to_vector . should_equal [20]
t1.at "Z" . to_vector . should_equal [1.5]
@ -487,7 +487,7 @@ add_specs suite_builder setup =
t2 = table_builder [["Z", [2.0, 1.5, 2.0]], ["W", [1, 2, 3]]]
r3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Z") on_problems=Problem_Behavior.Report_Warning
r3.column_names.should_equal ["X", "Y", "Z", "W"]
r4 = r3.order_by ["Y", "W"]
r4 = r3.sort ["Y", "W"]
r4.at "X" . to_vector . should_equal [2.0, 2.0, 2, 2]
r4.at "Y" . to_vector . should_equal [20, 20, 30, 30]
r4.at "Z" . to_vector . should_equal [2.0, 2.0, 2.0, 2.0]
@ -499,7 +499,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą", "b"]], ["Y", [0, 1, 2, 3, 4, 5]]]
t2 = table_builder [["X", ["a", Nothing, Nothing, "b"]], ["Z", [10, 20, 30, 50]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Z"] r1
r1.at "X" . to_vector . should_equal ["a", "b"]
r1.at "Y" . to_vector . should_equal [2, 5]
@ -509,7 +509,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą", "b"]], ["Y", [0, 1, 2, 3, 4, 5]]]
t2 = table_builder [["X", ["a", Nothing, Nothing, "b"]], ["Z", [10, 20, 30, 50]]]
r2 = t1.join t2 join_kind=Join_Kind.Left_Outer |> materialize |> _.order_by ["Y"]
r2 = t1.join t2 join_kind=Join_Kind.Left_Outer |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Right X", "Z"] r2
vs2 = r2 . rows . map .to_vector
within_table r2 <|
@ -520,7 +520,7 @@ add_specs suite_builder setup =
vs2.at 4 . to_vector . should_equal ["ą", 4, Nothing, Nothing]
vs2.at 5 . to_vector . should_equal ["b", 5, "b", 50]
r3 = t1.join t2 join_kind=Join_Kind.Right_Outer |> materialize |> _.order_by ["Z"]
r3 = t1.join t2 join_kind=Join_Kind.Right_Outer |> materialize |> _.sort ["Z"]
expect_column_names ["X", "Y", "Right X", "Z"] r3
vs3 = r3 . rows . map .to_vector
within_table r3 <|
@ -533,7 +533,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą", "b"]], ["Y", [0, 1, 2, 3, 4, 5]]]
t2 = table_builder [["X", ["a", Nothing, Nothing, "b"]], ["Z", [10, 20, 30, 50]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Right X", "Z"] r1
r1.at "X" . to_vector . should_equal ["A", "a", "b"]
r1.at "Y" . to_vector . should_equal [0, 2, 5]
@ -544,7 +544,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą", "b"]], ["Y", [0, 1, 2, 3, 4, 5]]]
t2 = table_builder [["X", ["a", Nothing, Nothing, "b"]], ["Z", [10, 20, 30, 50]]]
r2 = t1.join t2 join_kind=Join_Kind.Left_Outer on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
r2 = t1.join t2 join_kind=Join_Kind.Left_Outer on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "Right X", "Z"] r2
vs2 = r2 . rows . map .to_vector
within_table r2 <|
@ -555,7 +555,7 @@ add_specs suite_builder setup =
vs2.at 4 . to_vector . should_equal ["ą", 4, Nothing, Nothing]
vs2.at 5 . to_vector . should_equal ["b", 5, "b", 50]
r3 = t1.join t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Z", "Y"]
r3 = t1.join t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.sort ["Z", "Y"]
expect_column_names ["X", "Y", "Right X", "Z"] r3
vs3 = r3 . rows . map .to_vector
within_table r3 <|
@ -569,7 +569,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [1, Nothing, 2, Nothing, 20]], ["Y", [0, 1, 2, 3, 4]]]
t2 = table_builder [["l", [Nothing, 0, 1, 20]], ["u", [100, 10, Nothing, 100]], ["Z", [10, 20, 30, 40]]]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "l", "u", "Z"] r1
vs1 = r1 . rows . map .to_vector
within_table r1 <|
@ -581,7 +581,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [1, Nothing, 2, Nothing, 20]], ["Y", [0, 1, 2, 3, 4]]]
t2 = table_builder [["l", [Nothing, 0, 1, 20]], ["u", [100, 10, Nothing, 100]], ["Z", [10, 20, 30, 40]]]
r1 = t1.join t2 join_kind=Join_Kind.Left_Outer on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.order_by ["Y"]
r1 = t1.join t2 join_kind=Join_Kind.Left_Outer on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.sort ["Y"]
expect_column_names ["X", "Y", "l", "u", "Z"] r1
vs1 = r1 . rows . map .to_vector
within_table r1 <|
@ -591,7 +591,7 @@ add_specs suite_builder setup =
vs1.at 3 . should_equal [Nothing, 3, Nothing, Nothing, Nothing]
vs1.at 4 . should_equal [20, 4, 20, 100, 40]
r2 = t1.join t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.order_by ["Z", "Y"]
r2 = t1.join t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.sort ["Z", "Y"]
expect_column_names ["X", "Y", "l", "u", "Z"] r2
vs2 = r2 . rows . map .to_vector
within_table r2 <|
@ -605,7 +605,7 @@ add_specs suite_builder setup =
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]], ["Right Y", [5, 6]]]
t2 = table_builder [["X", [2, 1]], ["Y", [2, 2]]]
t3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Y") |> materialize |> _.order_by ["Right X"]
t3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Y") |> materialize |> _.sort ["Right X"]
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right Y"]]
t3.column_names.should_equal ["X", "Y", "Right Y", "Right X", "Right Y 1"]
t3.at "X" . to_vector . should_equal [2, 2]
@ -664,14 +664,14 @@ add_specs suite_builder setup =
t3 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Inner
expect_column_names ["A", "B", "C", "D"] t3
r3 = materialize t3 . order_by ["A", "B", "D"] . rows . map .to_vector
r3 = materialize t3 . sort ["A", "B", "D"] . rows . map .to_vector
within_table t3 <|
r3.length . should_equal 1
r3.at 0 . should_equal [2, 3, 2, 5]
t4 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Full
expect_column_names ["A", "B", "C", "D"] t4
r4 = materialize t4 . order_by ["A", "B", "D", "C"] . rows . map .to_vector
r4 = materialize t4 . sort ["A", "B", "D", "C"] . rows . map .to_vector
within_table t4 <|
r4.length . should_equal 7
r4.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
@ -684,7 +684,7 @@ add_specs suite_builder setup =
t4_2 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Left_Outer
expect_column_names ["A", "B", "C", "D"] t4_2
r4_2 = materialize t4_2 . order_by ["A", "B", "D", "C"] . rows . map .to_vector
r4_2 = materialize t4_2 . sort ["A", "B", "D", "C"] . rows . map .to_vector
within_table t4_2 <|
r4_2.length . should_equal 4
r4_2.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
@ -694,7 +694,7 @@ add_specs suite_builder setup =
t4_3 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Right_Outer
expect_column_names ["A", "B", "C", "D"] t4_3
r4_3 = materialize t4_3 . order_by ["A", "B", "C", "D"] . rows . map .to_vector
r4_3 = materialize t4_3 . sort ["A", "B", "C", "D"] . rows . map .to_vector
within_table r4_3 <|
r4_3.length . should_equal 4
r4_3.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
@ -704,7 +704,7 @@ add_specs suite_builder setup =
t5 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Left_Exclusive
expect_column_names ["A", "B"] t5
r5 = materialize t5 . order_by ["A", "B"] . rows . map .to_vector
r5 = materialize t5 . sort ["A", "B"] . rows . map .to_vector
within_table t5 <|
r5.length . should_equal 3
r5.at 0 . should_equal [Nothing, Nothing]
@ -713,7 +713,7 @@ add_specs suite_builder setup =
t6 = t1.join t2 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Right_Exclusive
expect_column_names ["C", "D"] t6
r6 = materialize t6 . order_by ["C", "D"] . rows . map .to_vector
r6 = materialize t6 . sort ["C", "D"] . rows . map .to_vector
within_table t6 <|
r6.length . should_equal 3
r6.at 0 . should_equal [Nothing, Nothing]
@ -724,13 +724,13 @@ add_specs suite_builder setup =
t8 = table_builder [["C", [2, 3]], ["D", [4, 5]]]
t9 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Inner
r9 = materialize t9 . order_by ["A", "B", "D"] . rows . map .to_vector
r9 = materialize t9 . sort ["A", "B", "D"] . rows . map .to_vector
within_table t9 <|
r9.length . should_equal 1
r9.at 0 . should_equal [2, 3, 2, 4]
t10 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Full
r10 = materialize t10 . order_by ["A", "C"] . rows . map .to_vector
r10 = materialize t10 . sort ["A", "C"] . rows . map .to_vector
within_table t10 <|
r10.length . should_equal 3
r10.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
@ -738,14 +738,14 @@ add_specs suite_builder setup =
r10.at 2 . should_equal [2, 3, 2, 4]
t10_2 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Left_Outer
r10_2 = materialize t10_2 . order_by ["A", "C"] . rows . map .to_vector
r10_2 = materialize t10_2 . sort ["A", "C"] . rows . map .to_vector
within_table t10_2 <|
r10_2.length . should_equal 2
r10_2.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
r10_2.at 1 . should_equal [2, 3, 2, 4]
t10_3 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Right_Outer
r10_3 = materialize t10_3 . order_by ["A", "C"] . rows . map .to_vector
r10_3 = materialize t10_3 . sort ["A", "C"] . rows . map .to_vector
within_table t10_3 <|
r10_3.length . should_equal 2
r10_3.at 0 . should_equal [Nothing, Nothing, 3, 5]
@ -770,7 +770,7 @@ add_specs suite_builder setup =
res = (tc.join ta on=(Join_Condition.Equals "id_a" "id")) . join tb on=(Join_Condition.Equals "id_b" "id") right_prefix="b_"
sel = res.select_columns ["name", "b_name"]
r = materialize sel . order_by "name" . rows . map .to_vector
r = materialize sel . sort "name" . rows . map .to_vector
r.length . should_equal 2
r.at 0 . should_equal ["Foo", "Y"]
r.at 1 . should_equal ["X", "Bar"]
@ -793,7 +793,7 @@ add_specs suite_builder setup =
t4_2 = t4.set (expr "2*[X]+1") as="C"
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Inner
expect_column_names ["X", "Y", "C", "Right X", "Z"] t6
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
r2 = materialize t6 . sort ["Y"] . rows . map .to_vector
r2.length . should_equal 2
r2.at 0 . should_equal [2, 20, 5, 5, 100]
r2.at 1 . should_equal [3, 30, 7, 7, 200]
@ -804,7 +804,7 @@ add_specs suite_builder setup =
t3 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") join_kind=Join_Kind.Full
expect_column_names ["X", "Y", "Right X", "Z"] t3
r = materialize t3 . order_by ["Y"] . rows . map .to_vector
r = materialize t3 . sort ["Y"] . rows . map .to_vector
r.length . should_equal 4
r.at 0 . should_equal [Nothing, Nothing, "Ć", 100]
r.at 1 . should_equal ["a", 10, "A", 200]
@ -817,7 +817,7 @@ add_specs suite_builder setup =
t4_2 = t4.set (expr "2*[X]+1") as="C"
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
expect_column_names ["X", "Y", "C", "Right X", "Z"] t6
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
r2 = materialize t6 . sort ["Y"] . rows . map .to_vector
r2.length . should_equal 4
r2.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
r2.at 1 . should_equal [1, 10, 3, Nothing, Nothing]
@ -829,7 +829,7 @@ add_specs suite_builder setup =
t7 = t4_4.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
within_table t7 <|
expect_column_names ["X", "Y", "C", "Right X", "Z"] t7
r3 = materialize t7 . order_by ["Y", "Right X"] . rows . map .to_vector
r3 = materialize t7 . sort ["Y", "Right X"] . rows . map .to_vector
r3.length . should_equal 5
r3.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
r3.at 1 . should_equal [Nothing, Nothing, Nothing, 5, 100]
@ -841,7 +841,7 @@ add_specs suite_builder setup =
t9 = t4_2.join t8 join_kind=Join_Kind.Full on=["X", "Y", "C"]
within_table t9 <|
t9.column_names . should_equal ["X", "Y", "C", "Right X", "Right Y", "Right C"]
r3 = materialize t9 . order_by ["X", "Right X"] . rows . map .to_vector
r3 = materialize t9 . sort ["X", "Right X"] . rows . map .to_vector
r3.length . should_equal 4
r3.at 0 . should_equal [Nothing, Nothing, Nothing, 99, 99, 99]
r3.at 1 . should_equal [1, 10, 3, Nothing, Nothing, Nothing]

View File

@ -42,7 +42,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns="X"
t2.column_names . should_equal ["X", "Y", "Z"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
m2.at "X" . to_vector . should_equal [1, 2, 3, 2]
m2.at "Y" . to_vector . should_equal ["A", "B", "A", "B"]
@ -53,7 +53,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns="code" add_new_columns=True
t2.column_names . should_equal ["id", "code", "hmm", "status"]
m2 = t2 |> materialize |> _.order_by "id"
m2 = t2 |> materialize |> _.sort "id"
m2.at "id" . to_vector . should_equal [1, 2, 3, 4]
m2.at "code" . to_vector . should_equal ["a", "c", "c", "b"]
m2.at "hmm" . to_vector . should_equal [10, 20, 30, 40]
@ -63,7 +63,7 @@ add_specs suite_builder setup =
my_table2 = table_builder [["A", [1, 2, 3, 4]], ["is_X", [True, True, False, True]]]
t3 = my_table2.merge lookup2 key_columns="is_X" add_new_columns=True
t3.column_names . should_equal ["A", "is_X", "X"]
m3 = t3 |> materialize |> _.order_by "A"
m3 = t3 |> materialize |> _.sort "A"
m3.at "A" . to_vector . should_equal [1, 2, 3, 4]
m3.at "is_X" . to_vector . should_equal [True, True, False, True]
m3.at "X" . to_vector . should_equal ["Yes", "Yes", "No", "Yes"]
@ -74,7 +74,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns="code"
t2.column_names . should_equal ["id", "code", "hmm"]
m2 = t2 |> materialize |> _.order_by "id"
m2 = t2 |> materialize |> _.sort "id"
m2.at "id" . to_vector . should_equal [1, 2, 3, 4]
m2.at "code" . to_vector . should_equal ["a", "c", "c", "b"]
m2.at "hmm" . to_vector . should_equal [10, 20, 30, 40]
@ -91,7 +91,7 @@ add_specs suite_builder setup =
lookup2 = table_builder [["code", ["a", "b", "c"]], ["status", ["new", "old", "changed"]], ["hmm", [111, 222, 333]]]
t3 = my_table.merge lookup2 key_columns=["code"] add_new_columns=False
t3.column_names . should_equal ["id", "code", "hmm"]
m3 = t3 |> materialize |> _.order_by "id"
m3 = t3 |> materialize |> _.sort "id"
m3.at "id" . to_vector . should_equal [1, 2, 3, 4]
m3.at "code" . to_vector . should_equal ["a", "c", "c", "b"]
m3.at "hmm" . to_vector . should_equal [111, 333, 333, 222]
@ -104,7 +104,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns=["X"]
t2.column_names . should_equal ["X", "Y", "Z"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
m2.at "X" . to_vector . should_equal [1, 2, 3, 2]
m2.at "Y" . to_vector . should_equal ["A", "B", "ZZZ", "B"]
@ -116,7 +116,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns=["X"] allow_unmatched_rows=True add_new_columns=True
t2.column_names . should_equal ["X", "Y", "Z", "W"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
m2.at "X" . to_vector . should_equal [1, 2, 3, 2]
m2.at "Y" . to_vector . should_equal ["A", "B", "ZZZ", "B"]
@ -135,7 +135,7 @@ add_specs suite_builder setup =
lookup2 = table_builder [["X", [1, 2, 3]], ["Y", ["A", "B", "C"]]]
my_table2 = table_builder [["X", [1, 2, 1, 1]], ["Y", ["Z", "ZZ", "ZZZ", "ZZZZ"]], ["Z", [10, 20, 30, 40]]]
t3 = my_table2.merge lookup2 key_columns=["X"] add_new_columns=True
m3 = t3 |> materialize |> _.order_by "Z"
m3 = t3 |> materialize |> _.sort "Z"
m3.at "X" . to_vector . should_equal [1, 2, 1, 1]
m3.at "Y" . to_vector . should_equal ["A", "B", "A", "A"]
m3.at "Z" . to_vector . should_equal [10, 20, 30, 40]
@ -160,7 +160,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns=["X", "Y"]
t2.column_names . should_equal ["X", "Y", "Z", "W"]
m2 = t2 |> materialize |> _.order_by "W"
m2 = t2 |> materialize |> _.sort "W"
m2.at "W" . to_vector . should_equal [1000, 2000, 3000, 4000]
m2.at "X" . to_vector . should_equal [1, 1, 1, 2]
m2.at "Y" . to_vector . should_equal ["A", "B", "A", "B"]
@ -173,7 +173,7 @@ add_specs suite_builder setup =
# If the duplicates do not show up in result - it is accepted.
t2 = my_table.merge lookup key_columns=["X"]
t2.column_names . should_equal ["X", "Y", "Z"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
m2.at "X" . to_vector . should_equal [4, 2, 3, 2]
m2.at "Y" . to_vector . should_equal ["Z", "B", "ZZZ", "B"]
@ -190,7 +190,7 @@ add_specs suite_builder setup =
r3 = my_table2.merge lookup2 key_columns=["X"]
r3.should_fail_with Non_Unique_Key
m3 = my_table2.merge lookup2 key_columns=["X", "Y"] |> materialize |> _.order_by "Z"
m3 = my_table2.merge lookup2 key_columns=["X", "Y"] |> materialize |> _.sort "Z"
m3.at "Z" . to_vector . should_equal [10, 20]
m3.at "X" . to_vector . should_equal [1, 2]
m3.at "Y" . to_vector . should_equal ["Z", "ZZ"]
@ -208,7 +208,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns=["X"] add_new_columns=True
t2.column_names . should_equal ["X", "Z", "Y"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "X" . to_vector . should_equal [1, 2, 2, 2, 1]
m2.at "Y" . to_vector . should_equal ["A", "B", "B", "B", "A"]
m2.at "Z" . to_vector . should_equal [10, 20, 20, 20, 50]
@ -278,7 +278,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns="X"
t2.column_names . should_equal ["X", "Y", "Z"]
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
m2.at "X" . to_vector . should_equal [2.0, 3.0, 2.0, 3.0]
m2.at "Y" . to_vector . should_equal ["B", "C", "B", "C"]
@ -304,7 +304,7 @@ add_specs suite_builder setup =
t2 = my_table.merge lookup key_columns="X" allow_unmatched_rows=False
t2.column_names . should_equal ["X", "Y", "Z"]
t2.at "Y" . value_type . is_integer . should_be_true
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "X" . to_vector . should_equal [2, 3, 2, 3]
m2.at "Y" . to_vector . should_equal [11, 111, 11, 111]
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
@ -319,7 +319,7 @@ add_specs suite_builder setup =
lookup2 = table_builder [["X", [1, 2]], ["Y", ["A", "B"]]]
my_table2 = table_builder [["X", [2, 3, Nothing, 3]], ["Z", [10, 20, 30, 40]]]
t2 = my_table2.merge lookup2 key_columns="X" allow_unmatched_rows=True add_new_columns=True
m2 = t2 |> materialize |> _.order_by "Z"
m2 = t2 |> materialize |> _.sort "Z"
m2.at "X" . to_vector . should_equal [2, 3, Nothing, 3]
m2.at "Y" . to_vector . should_equal ["B", Nothing, Nothing, Nothing]
m2.at "Z" . to_vector . should_equal [10, 20, 30, 40]
@ -358,7 +358,7 @@ add_specs suite_builder setup =
# Immediately, the query is all good.
Problems.assume_no_problems r1
m1 = r1 |> materialize |> _.order_by "Z"
m1 = r1 |> materialize |> _.sort "Z"
m1.at "X" . to_vector . should_equal [1, 2, 2]
m1.at "Y" . to_vector . should_equal ["A", "B", "B"]
m1.at "Z" . to_vector . should_equal [10, 20, 30]
@ -398,7 +398,7 @@ add_specs suite_builder setup =
# Immediately, the query is all good.
Problems.assume_no_problems r1
m1 = r1 |> materialize |> _.order_by "Z"
m1 = r1 |> materialize |> _.sort "Z"
m1.at "X" . to_vector . should_equal [1, 2, 2]
m1.at "Y" . to_vector . should_equal ["A", "B", "B"]
m1.at "Z" . to_vector . should_equal [10, 20, 30]
@ -420,7 +420,7 @@ add_specs suite_builder setup =
# Immediately, the query is all good.
Problems.assume_no_problems r1
m1 = r1 |> materialize |> _.order_by "Z"
m1 = r1 |> materialize |> _.sort "Z"
m1.at "X" . to_vector . should_equal [1, 2, 2]
m1.at "Y" . to_vector . should_equal ["A", "B", "B"]
m1.at "Z" . to_vector . should_equal [10, 20, 30]
@ -440,7 +440,7 @@ add_specs suite_builder setup =
t2 = table.merge table key_columns="X"
t2.column_names . should_equal ["X", "Y"]
m2 = t2 |> materialize |> _.order_by "X"
m2 = t2 |> materialize |> _.sort "X"
m2.at "X" . to_vector . should_equal [1, 2, 3]
m2.at "Y" . to_vector . should_equal ["A", "B", "C"]

View File

@ -44,42 +44,42 @@ add_specs suite_builder setup =
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder [['x', [2, 1, 4, 3]], ['z', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table 'x' . order_by ["x", "y"]
result = table.replace lookup_table 'x' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should be able to replace values via a lookup table, specifying from/to columns" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder [['d', [4, 5, 6, 7]], ['x', [2, 1, 4, 3]], ['d2', [5, 6, 7, 8]], ['z', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table 'x' 'x' 'z' . order_by ["x", "y"]
result = table.replace lookup_table 'x' 'x' 'z' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should be able to replace values via a lookup table provided as a Map" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = Map.from_vector [[2, 20], [1, 10], [4, 40], [3, 30]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table 'x' . order_by ["x", "y"]
result = table.replace lookup_table 'x' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should be able to replace multiple columns" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['x2', [2, 1, 2, 1, 4]], ['x3', [3, 4, 1, 3, 4]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder [['d', [4, 5, 6, 7]], ['x', [2, 1, 4, 3]], ['d2', [5, 6, 7, 8]], ['z', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['x2', [20, 10, 40, 20, 10]], ['x3', [30, 40, 40, 10, 30]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table ['x', 'x2', 'x3'] 'x' 'z' . order_by ["x", "y"]
result = table.replace lookup_table ['x', 'x2', 'x3'] 'x' 'z' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should be able to replace multiple columns selected by regex" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['x2', [2, 1, 2, 1, 4]], ['x3', [3, 4, 1, 3, 4]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder [['d', [4, 5, 6, 7]], ['x', [2, 1, 4, 3]], ['d2', [5, 6, 7, 8]], ['z', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['x2', [20, 10, 40, 20, 10]], ['x3', [30, 40, 40, 10, 30]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table [(regex 'x.*')] 'x' 'z' . order_by ["x", "y"]
result = table.replace lookup_table [(regex 'x.*')] 'x' 'z' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should be able to replace multiple columns selected by type" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['x2', [2, 1, 2, 1, 4]], ['x3', [3, 4, 1, 3, 4]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder [['d', [4, 5, 6, 7]], ['x', [2, 1, 4, 3]], ['d2', [5, 6, 7, 8]], ['z', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['x2', [20, 10, 40, 20, 10]], ['x3', [30, 40, 40, 10, 30]], ['y', ['a', 'b', 'e', 'c', 'd']]]
result = table.replace lookup_table [..By_Type ..Integer] 'x' 'z' . order_by ["x", "y"]
result = table.replace lookup_table [..By_Type ..Integer] 'x' 'z' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should fail with Missing_Input_Columns if the specified columns do not exist" <|
@ -93,7 +93,7 @@ add_specs suite_builder setup =
table = table_builder [['x', [1, 2, 3, 4]], ['y', ['a', 'b', 'c', 'd']]]
lookup_table = table_builder [['x', [4, 3, 1]], ['z', [40, 30, 10]]]
expected = table_builder [['x', [2, 10, 30, 40]], ['y', ['b', 'a', 'c', 'd']]]
result = table.replace lookup_table 'x' . order_by "x"
result = table.replace lookup_table 'x' . sort "x"
result . should_equal expected
group_builder.specify "fails on unmatched rows" <|
@ -116,14 +116,14 @@ add_specs suite_builder setup =
group_builder.specify "(edge-case) should allow lookup with itself" <|
table = table_builder [['x', [2, 1, 4, 3]], ['y', [20, 10, 40, 30]]]
expected = table_builder [['x', [10, 20, 30, 40]], ['y', [10, 20, 30, 40]]]
result = table.replace table 'x' . order_by "x"
result = table.replace table 'x' . sort "x"
result . should_equal expected
group_builder.specify "should not merge columns other than the one specified in the `column` param" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']], ['q', [4, 5, 6, 7, 8]]]
lookup_table = table_builder [['x', [2, 1, 4, 3]], ['z', [20, 10, 40, 30]], ['q', [40, 50, 60, 70]]]
expected = table_builder [['x', [10, 20, 20, 30, 40]], ['y', ['a', 'b', 'e', 'c', 'd']], ['q', [4, 5, 8, 6, 7]]]
result = table.replace lookup_table 'x' . order_by ["x", "y"]
result = table.replace lookup_table 'x' . sort ["x", "y"]
result . should_equal expected
group_builder.specify "should fail on null key values in lookup table" <|
@ -139,14 +139,14 @@ add_specs suite_builder setup =
group_builder.specify "should accept an empty (but well-formed) lookup table if allow_unmatched_rows=True, but expect a warning" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]]
lookup_table = table_builder_typed [['x', []], ['z', []]] Value_Type.Integer
t = table.replace lookup_table 'x' . order_by ['y']
t = table.replace lookup_table 'x' . sort ['y']
t . should_equal table
Problems.expect_warning (Empty_Error.Error "lookup_table") t
group_builder.specify "should throw an error on an empty (but well-formed) lookup table and non-empty base table if allow_unmatched_rows=False" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]] . order_by ['x']
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]] . sort ['x']
lookup_table = table_builder_typed [['x', []], ['z', []]] Value_Type.Integer
t = table.replace lookup_table 'x' allow_unmatched_rows=False . order_by ['y']
t = table.replace lookup_table 'x' allow_unmatched_rows=False . sort ['y']
t . should_fail_with Unmatched_Rows_In_Lookup
group_builder.specify "should accept an empty (but well-formed) lookup table if the base table is also empty, but expect a warning" <|
@ -163,7 +163,7 @@ add_specs suite_builder setup =
Problems.expect_warning (Empty_Error.Error "lookup_table") t
group_builder.specify "should throw an error on an empty lookup map and non-empty base table if allow_unmatched_rows=False" <|
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]] . order_by ['x']
table = table_builder [['x', [1, 2, 3, 4, 2]], ['y', ['a', 'b', 'c', 'd', 'e']]] . sort ['x']
t = table.replace Map.empty 'x' allow_unmatched_rows=False
t . should_fail_with Unmatched_Rows_In_Lookup
t.catch.example_key_values . should_equal [1]

View File

@ -52,12 +52,12 @@ add_specs suite_builder setup =
expected_rows = [r0, r1, r2]
r.should_equal expected_rows
group_builder.specify "should allow to zip two tables, preserving the order defined by `order_by`" <|
group_builder.specify "should allow to zip two tables, preserving the order defined by `sort`" <|
t1 = table_builder [["X", [100, 2]], ["Y", [4, 5]]]
t2 = table_builder [["Z", ['a', 'b']], ["W", ['x', 'd']]]
t3 = t1.order_by "X"
t4 = t2.order_by [Sort_Column.Name "Z" Sort_Direction.Descending]
t3 = t1.sort "X"
t4 = t2.sort [..Name "Z" ..Descending]
t5 = t3.zip t4
expect_column_names ["X", "Y", "Z", "W"] t5

View File

@ -68,7 +68,7 @@ add_specs suite_builder setup =
group_builder.specify "should be able to create a literal table from a map" <|
map = Map.from_vector [['x', 1], ['y', 2], ['z', 3]]
t = data.dummy_table.make_table_from_map map 'k' 'v' . order_by 'v'
t = data.dummy_table.make_table_from_map map 'k' 'v' . sort 'v'
t.at 'k' . to_vector . should_equal ['x', 'y', 'z']
t.at 'v' . to_vector . should_equal [1, 2, 3]

View File

@ -309,7 +309,7 @@ add_specs suite_builder setup =
v = t1.at "x" . to_vector
v . should_equal [Nothing]
suite_builder.group prefix+"order_by" group_builder->
suite_builder.group prefix+"sort" group_builder->
data = Data.setup create_connection_fn
group_builder.teardown <|
@ -330,10 +330,10 @@ add_specs suite_builder setup =
if is_comparable then
table = table_builder_typed [["x", [value, Nothing, other_value, other_value, Nothing, value, Nothing]]] value_type
group_builder.specify "Correctly handle Nothing in .order_by (asc) for "+value_type.to_text <|
t1 = table . order_by [Sort_Column.Name "x" Sort_Direction.Ascending]
group_builder.specify "Correctly handle Nothing in .sort (asc) for "+value_type.to_text <|
t1 = table . sort [..Name "x" ..Ascending]
t1.at "x" . to_vector . should_equal [Nothing, Nothing, Nothing, value, value, other_value, other_value]
group_builder.specify "Correctly handle Nothing in .order_by (desc) for "+value_type.to_text <|
t1 = table . order_by [Sort_Column.Name "x" Sort_Direction.Descending]
group_builder.specify "Correctly handle Nothing in .sort (desc) for "+value_type.to_text <|
t1 = table . sort [..Name "x" ..Descending]
t1.at "x" . to_vector . should_equal [other_value, other_value, value, value, Nothing, Nothing, Nothing]

View File

@ -46,11 +46,11 @@ add_specs suite_builder setup =
prefix = setup.prefix
create_connection_fn = setup.create_connection_func
test_selection = setup.test_selection
order_by_pending = if test_selection.order_by.not then
"ToDo: order_by is not yet supported by this backend."
sort_pending = if test_selection.order_by.not then
"ToDo: sort is not yet supported by this backend."
pending_collation = "Need more reliable testing for collation locale support"
suite_builder.group prefix+"Table.order_by" pending=order_by_pending group_builder->
suite_builder.group prefix+"Table.sort" pending=sort_pending group_builder->
data = Data.setup create_connection_fn setup.table_builder
group_builder.teardown <|
@ -60,203 +60,186 @@ add_specs suite_builder setup =
setup.table_builder cols connection=data.connection
group_builder.specify "should work as shown in the doc examples" <|
t1 = data.table.order_by ["alpha"]
t1 = data.table.sort ["alpha"]
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
## Assumes stable sorting on database engine.
t2 = data.table.order_by [1, Sort_Column.Index -8 Sort_Direction.Descending]
t2 = data.table.sort [1, ..Index -8 ..Descending]
t2.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t2.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
t2.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
t3 = data.table.order_by [Sort_Column.Select_By_Name "a.*".to_regex case_sensitivity=Case_Sensitivity.Insensitive]
t3 = data.table.sort [..Select_By_Name "a.*".to_regex case_sensitivity=..Insensitive]
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
group_builder.specify "should work with single column name" <|
t1 = data.table.order_by "alpha"
t1 = data.table.sort "alpha"
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
group_builder.specify "should work with single Sort_Column" <|
t1 = data.table.order_by [Sort_Column.Name "alpha"]
t1 = data.table.sort [..Name "alpha"]
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t2 = t1.order_by [Sort_Column.Name "alpha" Sort_Direction.Descending]
t2 = t1.sort [..Name "alpha" ..Descending]
t2.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
t2.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
t3 = data.table.order_by [Sort_Column.Index 0]
t3 = data.table.sort [..Index 0]
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t3.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t4 = t3.order_by [Sort_Column.Index 0 Sort_Direction.Descending]
t4.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
t4.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
group_builder.specify "should work with single Sort_Column (autoscoped)" <|
t1 = data.table.order_by [..Name "alpha"]
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t2 = t1.order_by [..Name "alpha" ..Descending]
t2.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
t2.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
t3 = data.table.order_by [..Index 0]
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t3.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t4 = t3.order_by [..Index 0 ..Descending]
t4 = t3.sort [..Index 0 ..Descending]
t4.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
t4.at "gamma" . to_vector . should_equal [1, 2, 3, 4]
group_builder.specify "should allow the selector to mix regex and case insensitive matching" <|
t4 = data.table.order_by [Sort_Column.Select_By_Name "A.*".to_regex case_sensitivity=Case_Sensitivity.Insensitive]
t4 = data.table.sort [..Select_By_Name "A.*".to_regex case_sensitivity=..Insensitive]
t4.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
group_builder.specify "should correctly handle regexes matching multiple names" <|
t1 = data.table.order_by [Sort_Column.Select_By_Name ".*ta".to_regex Sort_Direction.Descending]
t1 = data.table.sort [..Select_By_Name ".*ta".to_regex ..Descending]
t1.at "beta" . to_vector . should_equal ["b", "b", "a", "a"]
t1.at "delta" . to_vector . should_equal ["a1", "a03", "a2", "a10"]
t1.at "gamma" . to_vector . should_equal [2, 4, 3, 1]
group_builder.specify "should correctly handle problems: out of bounds indices" <|
selector = [0, 100, Sort_Column.Index -200, Sort_Column.Index 300]
selector = [0, 100, ..Index -200, ..Index 300]
expected_problem = Missing_Input_Columns.Error [100, -200, 300]
t1 = data.table.order_by selector
t1 = data.table.sort selector
t1.should_fail_with Missing_Input_Columns
t1.catch . should_equal expected_problem
action = data.table.order_by selector error_on_missing_columns=False on_problems=_
action = data.table.sort selector error_on_missing_columns=False on_problems=_
tester table =
table.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
Problems.test_problem_handling action [expected_problem] tester
group_builder.specify "should correctly handle edge-cases: duplicate selectors" <|
selector1 = ["alpha", Sort_Column.Name "alpha" Sort_Direction.Descending]
t1 = data.table.order_by selector1
selector1 = ["alpha", ..Name "alpha" ..Descending]
t1 = data.table.sort selector1
Problems.assume_no_problems t1
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t2 = data.table.order_by [Sort_Column.Index 0, Sort_Column.Index 0 Sort_Direction.Descending]
t2 = data.table.sort [..Index 0, ..Index 0 ..Descending]
Problems.assume_no_problems t2
t2.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t2.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t3 = data.table.order_by [Sort_Column.Index 0, Sort_Column.Name "alpha" Sort_Direction.Descending]
t3 = data.table.sort [..Index 0, ..Name "alpha" ..Descending]
Problems.assume_no_problems t3
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t3.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
group_builder.specify "should correctly handle edge-cases: duplicate matches due to case insensitivity" <|
selector = [Sort_Column.Select_By_Name "ALPHA" case_sensitivity=Case_Sensitivity.Insensitive, Sort_Column.Select_By_Name "alpha" Sort_Direction.Descending]
t1 = data.table.order_by selector
selector = [..Select_By_Name "ALPHA" case_sensitivity=..Insensitive, ..Select_By_Name "alpha" ..Descending]
t1 = data.table.sort selector
Problems.assume_no_problems t1
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
group_builder.specify "should correctly handle edge-cases: duplicate matches due to regexes" <|
selector = [Sort_Column.Select_By_Name "a.*".to_regex, Sort_Column.Select_By_Name "alpha" Sort_Direction.Descending]
t1 = data.table.order_by selector
selector = [..Select_By_Name "a.*".to_regex, ..Select_By_Name "alpha" ..Descending]
t1 = data.table.sort selector
Problems.assume_no_problems t1
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
group_builder.specify "should correctly handle edge-cases: mixed selector types" <|
t1 = data.table.order_by [Sort_Column.Name "alpha", Sort_Column.Index 1]
t1 = data.table.sort [..Name "alpha", ..Index 1]
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "beta" . to_vector . should_equal ["b", "a", "b", "a"]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t2 = data.table.order_by [Sort_Column.Select_By_Name "a.*a".to_regex, Sort_Column.Index 1]
t2 = data.table.sort [..Select_By_Name "a.*a".to_regex, ..Index 1]
t2.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t2.at "beta" . to_vector . should_equal ["b", "a", "b", "a"]
t2.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
group_builder.specify "should correctly handle problems: unmatched names" <|
weird_name = '.*?-!@#!"'
selector = [Sort_Column.Name "alpha", "hmm", Sort_Column.Name weird_name]
selector = [..Name "alpha", "hmm", ..Name weird_name]
expected_problem = Missing_Input_Columns.Error ["hmm", weird_name]
t1 = data.table.order_by selector
t1 = data.table.sort selector
t1.should_fail_with Missing_Input_Columns
t1.catch . should_equal expected_problem
action = data.table.order_by selector error_on_missing_columns=False on_problems=_
action = data.table.sort selector error_on_missing_columns=False on_problems=_
tester table =
table.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
Problems.test_problem_handling action [expected_problem] tester
group_builder.specify "should report a problem if no columns are selected for ordering" <|
t2 = data.table.order_by []
t2 = data.table.sort []
t2.should_fail_with No_Input_Columns_Selected
group_builder.specify "should stack consecutive ordering operations" <|
t1 = data.table.order_by [Sort_Column.Name "alpha"]
t1 = data.table.sort [..Name "alpha"]
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "beta" . to_vector . should_equal ["b", "a", "b", "a"]
# Now we reverse the order
t2 = t1.order_by [Sort_Column.Name "alpha" Sort_Direction.Descending]
t2 = t1.sort [..Name "alpha" ..Descending]
t2.at "alpha" . to_vector . should_equal [3, 2, 1, 0]
t2.at "beta" . to_vector . should_equal ["a", "b", "a", "b"]
# Now we add another primary ordering, but the order from t1/t2 is kept for tie breaking.
t3 = t1.order_by [Sort_Column.Name "beta"]
t3 = t1.sort [..Name "beta"]
t3.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t3.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
t4 = t2.order_by ["beta"]
t4 = t2.sort ["beta"]
t4.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t4.at "alpha" . to_vector . should_equal [3, 1, 2, 0]
group_builder.specify "should give priority to the first selected column and use the next ones for breaking ties" <|
t1 = data.table.order_by ["beta", Sort_Column.Name "alpha" Sort_Direction.Ascending]
t1 = data.table.sort ["beta", ..Name "alpha" ..Ascending]
t1.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t1.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
t1.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
t1a = data.table.order_by ["beta", Sort_Column.Name "alpha" Sort_Direction.Ascending]
t1a = data.table.sort ["beta", ..Name "alpha" ..Ascending]
t1a.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t1a.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
t1a.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
t2 = data.table.order_by [Sort_Column.Name "beta", Sort_Column.Name "alpha" Sort_Direction.Descending]
t2 = data.table.sort [..Name "beta", ..Name "alpha" ..Descending]
t2.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t2.at "alpha" . to_vector . should_equal [3, 1, 2, 0]
t2.at "gamma" . to_vector . should_equal [1, 3, 2, 4]
t3 = data.table.order_by [Sort_Column.Name "alpha", Sort_Column.Name "beta"]
t3 = data.table.sort [..Name "alpha", ..Name "beta"]
t3.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t3.at "beta" . to_vector . should_equal ["b", "a", "b", "a"]
t3.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
t4 = data.table.order_by [Sort_Column.Index 1, Sort_Column.Index 0 Sort_Direction.Ascending]
t4 = data.table.sort [..Index 1, ..Index 0 ..Ascending]
t4.at "beta" . to_vector . should_equal ["a", "a", "b", "b"]
t4.at "alpha" . to_vector . should_equal [1, 3, 0, 2]
t4.at "gamma" . to_vector . should_equal [3, 1, 4, 2]
group_builder.specify "should deal with real numbers, and not warn when ordering by floats" <|
t1 = data.table.order_by ["tau"]
t1 = data.table.sort ["tau"]
t1.at "tau" . to_vector . should_equal [-0.1, 0.5, 1.6, 32.0]
t1.at "alpha" . to_vector . should_equal [1, 2, 0, 3]
Problems.assume_no_problems t1
group_builder.specify "should deal with nulls" <|
t1 = data.table.order_by ["xi"]
t1 = data.table.sort ["xi"]
t1.at "xi" . to_vector . should_equal [Nothing, 0.5, 1.0, 1.5]
t1.at "alpha" . to_vector . should_equal [1, 0, 3, 2]
t2 = data.table.order_by [Sort_Column.Name "rho"]
t2 = data.table.sort [..Name "rho"]
t2.at "rho" . to_vector . should_equal [Nothing, Nothing, "B", "BB"]
t3 = data.table.order_by [Sort_Column.Name "rho" Sort_Direction.Descending]
t3 = data.table.sort [..Name "rho" ..Descending]
t3.at "rho" . to_vector . should_equal ["BB", "B", Nothing, Nothing]
group_builder.specify "should behave as expected with Unicode normalization, depending on the defaults settings" pending=pending_collation <|
t1 = data.table.order_by [Sort_Column.Name "phi"]
t1 = data.table.sort [..Name "phi"]
case test_selection.order_by_unicode_normalization_by_default of
True ->
t1.at "phi" . to_vector . should_equal [Nothing, "śa", 's\u0301b', "śc"]
@ -266,54 +249,54 @@ add_specs suite_builder setup =
t1.at "alpha" . to_vector . should_equal [2, 1, 0, 3]
group_builder.specify "should support natural ordering" pending=(if test_selection.natural_ordering.not then "Natural ordering is not supported.") <|
t1 = data.table.order_by [Sort_Column.Name "delta"] text_ordering=(Text_Ordering.Default sort_digits_as_numbers=True)
t1 = data.table.sort [..Name "delta"] text_ordering=(..Default sort_digits_as_numbers=True)
t1.at "delta" . to_vector . should_equal ["a1", "a2", "a03", "a10"]
t1.at "alpha" . to_vector . should_equal [2, 1, 0, 3]
t2 = data.table.order_by ["delta"] text_ordering=(Text_Ordering.Default sort_digits_as_numbers=False)
t2 = data.table.sort ["delta"] text_ordering=(..Default sort_digits_as_numbers=False)
t2.at "delta" . to_vector . should_equal ["a03", "a1", "a10", "a2"]
t2.at "alpha" . to_vector . should_equal [0, 2, 3, 1]
group_builder.specify "should support case insensitive ordering" pending=(if test_selection.case_insensitive_ordering.not then "Case insensitive ordering is not supported." else pending_collation) <|
t1 = data.table.order_by [Sort_Column.Name "eta"] text_ordering=(Text_Ordering.Case_Insensitive)
t1 = data.table.sort [..Name "eta"] text_ordering=(..Case_Insensitive)
expected = case test_selection.case_insensitive_ascii_only of
True -> ["Aleph", "alpha", "Beta", "bądź"]
False -> ["Aleph", "alpha", "bądź", "Beta"]
t1.at "eta" . to_vector . should_equal expected
t2 = data.table.order_by [Sort_Column.Name "eta"] text_ordering=(Text_Ordering.Case_Sensitive)
t2 = data.table.sort [..Name "eta"] text_ordering=(..Case_Sensitive)
t2.at "eta" . to_vector . should_equal ["Aleph", "Beta", "alpha", "bądź"]
t3 = data.table.order_by [Sort_Column.Name "psi"] text_ordering=(Text_Ordering.Case_Insensitive)
t3 = data.table.sort [..Name "psi"] text_ordering=(..Case_Insensitive)
t3.at "psi" . to_vector . should_equal [Nothing, "c01", "c10", "C2"]
t4 = data.table.order_by [Sort_Column.Name "psi" Sort_Direction.Descending] text_ordering=(Text_Ordering.Case_Sensitive)
t4 = data.table.sort [..Name "psi" ..Descending] text_ordering=(..Case_Sensitive)
t4.at "psi" . to_vector . should_equal ["c10", "c01", "C2", Nothing]
group_builder.specify "should support natural and case insensitive ordering at the same time" pending=(if (test_selection.natural_ordering.not || test_selection.case_insensitive_ordering.not) then "Natural ordering or case sensitive ordering is not supported.") <|
t1 = data.table.order_by [Sort_Column.Name "psi"] text_ordering=(Text_Ordering.Case_Insensitive sort_digits_as_numbers=True)
t1 = data.table.sort [..Name "psi"] text_ordering=(..Case_Insensitive sort_digits_as_numbers=True)
t1.at "psi" . to_vector . should_equal [Nothing, "c01", "C2", "c10"]
t2 = data.table.order_by [Sort_Column.Name "psi"] text_ordering=(Text_Ordering.Default sort_digits_as_numbers=True)
t2 = data.table.sort [..Name "psi"] text_ordering=(..Default sort_digits_as_numbers=True)
t2.at "psi" . to_vector . should_equal [Nothing, "C2", "c01", "c10"]
t3 = data.table.order_by [Sort_Column.Name "psi"] text_ordering=(Text_Ordering.Case_Insensitive)
t3 = data.table.sort [..Name "psi"] text_ordering=(..Case_Insensitive)
t3.at "psi" . to_vector . should_equal [Nothing, "c01", "c10", "C2"]
t4 = data.table.order_by [Sort_Column.Name "psi"]
t4 = data.table.sort [..Name "psi"]
t4.at "psi" . to_vector . should_equal [Nothing, "C2", "c01", "c10"]
group_builder.specify "text ordering settings should not affect numeric columns" <|
ordering = Text_Ordering.Case_Insensitive sort_digits_as_numbers=True
t1 = data.table.order_by [Sort_Column.Name "alpha"] text_ordering=ordering
ordering = ..Case_Insensitive sort_digits_as_numbers=True
t1 = data.table.sort [..Name "alpha"] text_ordering=ordering
t1.at "alpha" . to_vector . should_equal [0, 1, 2, 3]
t1.at "gamma" . to_vector . should_equal [4, 3, 2, 1]
if setup.is_database.not then
group_builder.specify "should allow ordering enso objects with a comparator" <|
t = table_builder [["X", [Day_Of_Week.Friday, Day_Of_Week.Monday, Nothing, Nothing, Day_Of_Week.Wednesday]]]
t.order_by "X" . at "X" . to_vector . should_equal [Nothing, Nothing, Day_Of_Week.Monday, Day_Of_Week.Wednesday, Day_Of_Week.Friday]
t.sort "X" . at "X" . to_vector . should_equal [Nothing, Nothing, Day_Of_Week.Monday, Day_Of_Week.Wednesday, Day_Of_Week.Friday]
group_builder.specify "should raise Incomparable_Values if ordering by incomparable values" <|
t = table_builder [["X", [My_Type.Foo 42, My_Type.Foo "a"]]]
t.order_by "X" . should_fail_with Incomparable_Values
t.sort "X" . should_fail_with Incomparable_Values

View File

@ -27,7 +27,7 @@ type Table_Take_Drop_Data
table =
col1 = ["alpha", [1,2,3,4,5,6,7,8]]
col2 = ["beta", ["A","B","C","D","E","F","G","H"]]
(table_builder [col1, col2] connection=connection) . order_by "alpha"
(table_builder [col1, col2] connection=connection) . sort "alpha"
empty = table.remove_all_rows
[connection, table, empty]
@ -50,7 +50,7 @@ type Column_Take_Drop_Data
table =
col1 = ["alpha", [1,2,3,4,5,6,7,8]]
col2 = ["beta", ["A","B","C","D","E","F","G","H"]]
(table_builder [col1, col2] connection=connection) . order_by "alpha"
(table_builder [col1, col2] connection=connection) . sort "alpha"
alpha = table.at "alpha"
beta = table.at "beta"
@ -113,12 +113,12 @@ add_specs suite_builder setup =
data.table.drop (Last 100) . should_equal data.empty
group_builder.specify "should handle consecutive take/drops" <|
data.table.take 5 . order_by "alpha" . take 3 . at "alpha" . to_vector . should_equal [1, 2, 3]
data.table.take 3 . order_by "alpha" . take 5 . at "alpha" . to_vector . should_equal [1, 2, 3]
data.table.take 5 . order_by "alpha" . drop 3 . at "alpha" . to_vector . should_equal [4, 5]
data.table.drop 3 . order_by "alpha" . drop 2 . at "alpha" . to_vector . should_equal [6, 7, 8]
data.table.drop 2 . order_by "alpha" . drop 3 . at "alpha" . to_vector . should_equal [6, 7, 8]
data.table.drop 3 . order_by "alpha" . take 2 . at "alpha" . to_vector . should_equal [4, 5]
data.table.take 5 . sort "alpha" . take 3 . at "alpha" . to_vector . should_equal [1, 2, 3]
data.table.take 3 . sort "alpha" . take 5 . at "alpha" . to_vector . should_equal [1, 2, 3]
data.table.take 5 . sort "alpha" . drop 3 . at "alpha" . to_vector . should_equal [4, 5]
data.table.drop 3 . sort "alpha" . drop 2 . at "alpha" . to_vector . should_equal [6, 7, 8]
data.table.drop 2 . sort "alpha" . drop 3 . at "alpha" . to_vector . should_equal [6, 7, 8]
data.table.drop 3 . sort "alpha" . take 2 . at "alpha" . to_vector . should_equal [4, 5]
group_builder.specify "should allow selecting rows by ranges or indices" <|
data.table.take (2.up_to 4) . at "beta" . to_vector . should_equal ["C", "D"]
@ -187,9 +187,9 @@ add_specs suite_builder setup =
if setup.is_database.not then
group_builder.specify "should allow sampling rows" <|
one = table_builder [["X", ["a"]]] . order_by "X"
two = table_builder [["X", ["a", "a"]]] . order_by "X"
three = table_builder [["X", ["a", "a", "a"]]] . order_by "X"
one = table_builder [["X", ["a"]]] . sort "X"
two = table_builder [["X", ["a", "a"]]] . sort "X"
three = table_builder [["X", ["a", "a", "a"]]] . sort "X"
empty = one.remove_all_rows
three.take (Sample 0) . should_equal empty
empty.take (Sample 0) . should_equal empty
@ -249,11 +249,11 @@ add_specs suite_builder setup =
t0 = table_builder [["X", ["a", "b", "a", "c"]], ["Y", [1, 2, 4, 8]]]
t1 = t0.aggregate ["X"] [Aggregate_Column.Sum "Y"]
t2 = t1.order_by "X" . take 2
t2 = t1.sort "X" . take 2
t2.at "X" . to_vector . should_equal ['a', 'b']
t2.at "Sum Y" . to_vector . should_equal [5.0, 2.0]
t3 = t1.order_by "X" . drop 1
t3 = t1.sort "X" . drop 1
t3.at "X" . to_vector . should_equal ['b', 'c']
t3.at "Sum Y" . to_vector . should_equal [2.0, 8.0]

View File

@ -32,7 +32,7 @@ type Dummy_Connection
- filter: An optional Text filter for filtering out test specs and groups. See the
docs of `Test.Suite.run_with_filter`.
run_default_backend add_specs filter=Nothing =
selection = Test_Selection.Config supports_case_sensitive_columns=True order_by=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True supports_unicode_normalization=True supports_time_duration=True supports_nanoseconds_in_time=True supports_mixed_columns=True fixed_length_text_columns=True supports_8bit_integer=True
selection = Test_Selection.Config supports_case_sensitive_columns=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True supports_unicode_normalization=True supports_time_duration=True supports_nanoseconds_in_time=True supports_mixed_columns=True fixed_length_text_columns=True supports_8bit_integer=True
aggregate_selection = Aggregate_Spec.Test_Selection.Config
table_fn _ = (enso_project.data / "data.csv") . read

View File

@ -132,22 +132,22 @@ add_specs suite_builder =
data.teardown
group_builder.specify "should allow sorting by a single column name" <|
r1 = data.t1.order_by ([Sort_Column.Name "A"]) . at "B"
r1 = data.t1.sort ([..Name "A"]) . at "B"
r1.to_sql.prepare . should_equal ['SELECT "T1"."B" AS "B" FROM "T1" AS "T1" ORDER BY "T1"."A" ASC', []]
r2 = data.t1.order_by ([Sort_Column.Name "B" Sort_Direction.Descending]) . at "A"
r2 = data.t1.sort ([..Name "B" ..Descending]) . at "A"
r2.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A" FROM "T1" AS "T1" ORDER BY "T1"."B" DESC', []]
group_builder.specify 'should allow sorting by multiple column names' <|
r1 = data.t1.order_by ([Sort_Column.Name 'A', Sort_Column.Name 'B'])
r1 = data.t1.sort ([..Name 'A', ..Name 'B'])
r1.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1" ORDER BY "T1"."A" ASC, "T1"."B" ASC', []]
group_builder.specify 'should allow sorting with specific by-column rules' <|
r1 = data.t1.order_by ([Sort_Column.Name "A", Sort_Column.Name "B" Sort_Direction.Descending])
r1 = data.t1.sort ([..Name "A", ..Name "B" ..Descending])
r1.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1" ORDER BY "T1"."A" ASC, "T1"."B" DESC', []]
group_builder.specify 'should return warnings and errors when passed a non-existent column' <|
t2 = data.t1.order_by ([Sort_Column.Name 'foobar'])
t2 = data.t1.sort ([..Name 'foobar'])
t2.should_fail_with Missing_Input_Columns
suite_builder.group "[Codegen] Aggregation" group_builder->

View File

@ -280,7 +280,7 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
(Table.new [["a", [1, 2, 3]], ["b", [4, 5, 6]]]).select_into_database_table data.connection name temporary=True
t1 = data.connection.query name
m1 = t1.read.order_by "a"
m1 = t1.read.sort "a"
Problems.assume_no_problems m1
m1.at "a" . to_vector . should_equal [1, 2, 3]
m1.at "b" . to_vector . should_equal [4, 5, 6]
@ -302,7 +302,7 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
(Table.new [["a", [1, 2, 3]], ["b", [4, 5, 6]]]).select_into_database_table data.connection name temporary=True
t1 = data.connection.query name
m1 = t1.read.order_by "a"
m1 = t1.read.sort "a"
Problems.assume_no_problems m1
m1.at "a" . to_vector . should_equal [1, 2, 3]
m1.at "b" . to_vector . should_equal [4, 5, 6]
@ -346,7 +346,7 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
data.teardown
group_builder.specify "fill_nothing should replace nulls" <|
t4_ordered = data.t4.order_by "rowid"
t4_ordered = data.t4.sort "rowid"
t4_ordered.at "a" . fill_nothing 10 . to_vector . should_equal [0, 1, 10, 42, 10]
t4_ordered.at "b" . fill_nothing False . to_vector . should_equal [True, False, True, False, False]
t4_ordered.at "c" . fill_nothing "NA" . to_vector . should_equal ["", "foo", "bar", "NA", "NA"]
@ -366,27 +366,27 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
data.teardown
group_builder.specify "should allow sorting by a single column name" <|
r_1 = data.df.order_by ([Sort_Column.Name 'quantity'])
r_1 = data.df.sort ([..Name 'quantity'])
r_1.at 'id' . to_vector . should_have_relative_ordering [[2,4],[1,3],[5,6]]
r_3 = data.df.order_by ([Sort_Column.Name 'rating' Sort_Direction.Descending])
r_3 = data.df.sort ([..Name 'rating' ..Descending])
r_3.at 'id' . to_vector . should_have_relative_ordering [[3],[1,4],[5],[2,6]]
group_builder.specify 'should allow sorting by multiple column names' <|
r_1 = data.df.order_by ([Sort_Column.Name 'quantity', Sort_Column.Name 'rating'])
r_1 = data.df.sort ([..Name 'quantity', ..Name 'rating'])
r_1.at 'id' . to_vector . should_equal [2,4,1,3,6,5]
r_2 = data.df.order_by ([Sort_Column.Name 'rating' Sort_Direction.Descending, Sort_Column.Name 'quantity' Sort_Direction.Descending])
r_2 = data.df.sort ([..Name 'rating' ..Descending, ..Name 'quantity' ..Descending])
r_2.at 'id' . to_vector . should_equal [3,1,4,5,6,2]
group_builder.specify 'should allow sorting with specific by-column rules' <|
r_1 = data.df.order_by ([Sort_Column.Name "quantity", Sort_Column.Name "price" Sort_Direction.Descending])
r_1 = data.df.sort ([..Name "quantity", ..Name "price" ..Descending])
r_1.at 'id' . to_vector . should_equal [4,2,3,1,6,5]
group_builder.specify 'should correctly reorder all kinds of columns and leave the original columns untouched' <|
initial = data.t8.order_by 'ints'
r = initial.order_by ([Sort_Column.Name 'ord'])
initial = data.t8.sort 'ints'
r = initial.sort ([Sort_Column.Name 'ord'])
r.at 'ints' . to_vector . should_equal [1, 5, 3, 2, 4]
initial.at 'ints' . to_vector . should_equal data.ints
@ -420,7 +420,7 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
(InMemory) table are ordered according to a specified column or list
of columns.
determinize_by order_column table =
table.order_by ([Sort_Column.Name order_column])
table.sort ([..Name order_column])
group_builder.specify "should allow counting group sizes and elements" <|
## Names set to lower case to avoid issue with Redshift where columns are

View File

@ -70,15 +70,15 @@ add_specs (suite_builder : Suite_Builder) (prefix : Text) (create_connection_fn
data.db_table_with_key.join data.db_table_with_key . default_ordering . should_equal Nothing
data.db_table_with_key.aggregate ["X"] . default_ordering . should_equal Nothing
group_builder.specify "will return the ordering determined by order_by" <|
v1 = data.db_table_with_key.order_by ["Y", Sort_Column.Name "X" Sort_Direction.Descending] . default_ordering
group_builder.specify "will return the ordering determined by sort" <|
v1 = data.db_table_with_key.sort ["Y", ..Name "X" ..Descending] . default_ordering
v1.length . should_equal 2
v1.first.expression.name . should_equal "Y"
v1.first.direction . should_equal Sort_Direction.Ascending
v1.second.expression.name . should_equal "X"
v1.second.direction . should_equal Sort_Direction.Descending
v2 = data.db_table_without_key.order_by ["Y"] . default_ordering
v2 = data.db_table_without_key.sort ["Y"] . default_ordering
v2.length . should_equal 1
v2.first.expression.name . should_equal "Y"
v2.first.direction . should_equal Sort_Direction.Ascending

View File

@ -416,7 +416,7 @@ add_specs suite_builder prefix create_connection_func =
w.original_names . should_equal ["RIGHT_" + name_a, "RIGHT_" + name_b]
t2.row_count . should_equal 3
m2 = t2.read . order_by name_a
m2 = t2.read . sort name_a
m2.column_names . should_equal [name_a, name_b]+w.truncated_names
m2.at name_a . to_vector . should_equal [1, 2, 3]
m2.at name_b . to_vector . should_equal [4, 5, 6]
@ -429,7 +429,7 @@ add_specs suite_builder prefix create_connection_func =
w.original_names . should_equal ["RIGHT_" + name_a, "RIGHT_" + name_b]
t2.row_count . should_equal 9
m2 = t2.read . order_by [name_a, name_b]
m2 = t2.read . sort [name_a, name_b]
m2.column_names . should_equal [name_a, name_b]+w.truncated_names
m2.at name_a . to_vector . should_contain_the_same_elements_as [1, 2, 3]
m2.at name_b . to_vector . should_contain_the_same_elements_as [4, 5, 6]

View File

@ -325,7 +325,7 @@ sqlite_spec suite_builder prefix create_connection_func =
Common_Spec.add_specs suite_builder prefix create_connection_func
common_selection = Common_Table_Operations.Main.Test_Selection.Config supports_case_sensitive_columns=False order_by=True natural_ordering=False case_insensitive_ordering=True case_insensitive_ascii_only=True is_nan_and_nothing_distinct=False date_time=False supported_replace_params=supported_replace_params different_size_integer_types=False length_restricted_text_columns=False
common_selection = Common_Table_Operations.Main.Test_Selection.Config supports_case_sensitive_columns=False natural_ordering=False case_insensitive_ordering=True case_insensitive_ascii_only=True is_nan_and_nothing_distinct=False date_time=False supported_replace_params=supported_replace_params different_size_integer_types=False length_restricted_text_columns=False
## For now `advanced_stats`, `first_last`, `text_shortest_longest` and
`multi_distinct` remain disabled, because SQLite does not provide the

View File

@ -994,7 +994,7 @@ test_table_append group_builder (data : Data) source_table_builder target_table_
r2 = t1.update_rows s1 update_action=Update_Action.Insert key_columns=[]
Problems.assume_no_problems r2
m2 = r2.read . order_by "Y"
m2 = r2.read . sort "Y"
m2.at "Y" . to_vector . should_equal ["a", "b", "c", "x", "y"]
m2.at "X" . to_vector . should_equal [0, 10, 100, 10, Nothing]
@ -1332,7 +1332,7 @@ test_table_delete group_builder (data : Data) source_table_builder target_table_
t1 = target_table_builder [["X", ["a", "b", Nothing, "c"]], ["Y", [1, 2, 3, Nothing]]] connection=data.connection
s1 = source_table_builder [["X", ["b", "c"]]] connection=data.connection
t1.delete_rows s1 key_columns=["X"] . should_equal 2
m1 = t1.read . order_by "X"
m1 = t1.read . sort "X"
m1.at "X" . to_vector . should_equal [Nothing, "a"]
m1.at "Y" . to_vector . should_equal [3, 1]

View File

@ -10,7 +10,7 @@ type Dummy_Connection
close = Nothing
add_specs suite_builder =
selection = Common_Table_Operations.Main.Test_Selection.Config supports_case_sensitive_columns=True order_by=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True supports_unicode_normalization=True supports_time_duration=True supports_nanoseconds_in_time=True supports_mixed_columns=True fixed_length_text_columns=True supports_8bit_integer=True
selection = Common_Table_Operations.Main.Test_Selection.Config supports_case_sensitive_columns=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True supports_unicode_normalization=True supports_time_duration=True supports_nanoseconds_in_time=True supports_mixed_columns=True fixed_length_text_columns=True supports_8bit_integer=True
aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config
agg_table_fn = _ ->

View File

@ -357,7 +357,7 @@ add_specs suite_builder =
c_1 = ['id', [1, 2, 3, 4, 5, 6]]
c_2 = ['val', [My.Data 1 2, My.Data 3 4, My.Data 2 1, My.Data 5 2, My.Data 7 0, My.Data 4 -1]]
df = Table.new [c_1, c_2]
r = df.order_by (['val'])
r = df.sort (['val'])
r.at 'id' . to_vector . should_equal [1,3,6,2,4,5]
group_builder.specify 'should correctly reorder all kinds of columns and leave the original columns untouched' <|
@ -373,7 +373,7 @@ add_specs suite_builder =
mixed_dates = [Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 2000]
df = Table.new [['ord', ord], ['ints', ints], ['reals', reals], ['bools', bools], ['texts', texts], ['objs', objs], ['dates', dates], ['times', times], ['datetimes', datetimes], ['mixed_dates', mixed_dates]]
r = df.order_by (['ord'])
r = df.sort (['ord'])
r.at 'ints' . to_vector . should_equal [1, 5, 3, 2, 4]
df.at 'ints' . to_vector . should_equal ints
@ -400,23 +400,23 @@ add_specs suite_builder =
df.at 'datetimes' . to_vector . should_equal datetimes
# TODO move this test to Common_Table_Operations once we support dates there
r2 = df.order_by (['dates'])
r2 = df.sort (['dates'])
r2.at 'dates' . to_vector . should_equal [Date.new 1999, Date.new 1999 12 31, Date.new 2000 2 7, Date.new 2000 10 3, Date.new 2020]
r2.at 'ints' . to_vector . should_equal [2, 4, 5, 3, 1]
r3 = df.order_by (['times'])
r3 = df.sort (['times'])
r3.at 'times' . to_vector . should_equal [Time_Of_Day.new 1 30 40, Time_Of_Day.new 10 20 30, Time_Of_Day.new 12, Time_Of_Day.new 12 30 0, Time_Of_Day.new 23 59 59]
r3.at 'ints' . to_vector . should_equal [2, 5, 1, 4, 3]
r4 = df.order_by (['datetimes'])
r4 = df.sort (['datetimes'])
r4.at 'datetimes' . to_vector . should_equal [Date_Time.new 1999 1 1 1 30 40, Date_Time.new 1999 12 31 12 30 0, Date_Time.new 2000 10 3 10 20 30, Date_Time.new 2000 10 3 23 59 59, Date_Time.new 2020 1 1 12]
r4.at 'ints' . to_vector . should_equal [2, 4, 5, 3, 1]
r5 = df.order_by (['objs'])
r5 = df.sort (['objs'])
r5.at 'objs' . to_vector . should_equal [My.Data 2 3, My.Data 6 7, My.Data 8 9, My.Data 10 30, My.Data 100 2]
r5.at 'ints' . to_vector . should_equal [2, 3, 4, 5, 1]
r6 = df.order_by (['mixed_dates'])
r6 = df.sort (['mixed_dates'])
r6 . should_fail_with Incomparable_Values
suite_builder.group "Sorting Columns" group_builder->
@ -712,7 +712,7 @@ add_specs suite_builder =
texts = ["texts", ['ściana', 'ściana', 'łąka', 's\u0301ciana', 'ła\u0328ka', 'sciana']]
ints = ["ints", [1, 2, 4, 8, 16, 32]]
table = Table.new [texts, ints]
r1 = table.aggregate ["texts"] [Aggregate_Column.Sum "ints"] . order_by ([Sort_Column.Name "texts"])
r1 = table.aggregate ["texts"] [Aggregate_Column.Sum "ints"] . sort ([..Name "texts"])
r1.at "texts" . to_vector . should_equal ['sciana', 'ściana', 'łąka']
r1.at "Sum ints" . to_vector . should_equal [32, 11, 20]
@ -722,10 +722,10 @@ add_specs suite_builder =
group_builder.specify "should be able to aggregate over enso Types" <|
weekday_table = Table.new [["days", [Day_Of_Week.Monday, Day_Of_Week.Monday, Day_Of_Week.Monday, Day_Of_Week.Tuesday, Day_Of_Week.Sunday]], ["group", [1,1,2,1,2]]]
r1 = weekday_table.aggregate ["days"] . order_by "days"
r1 = weekday_table.aggregate ["days"] . sort "days"
r1.at "days" . to_vector . should_equal [Day_Of_Week.Sunday, Day_Of_Week.Monday, Day_Of_Week.Tuesday]
r2 = weekday_table.aggregate ["group"] [Aggregate_Column.Minimum "days" "min", Aggregate_Column.Maximum "days" "max"] . order_by "group"
r2 = weekday_table.aggregate ["group"] [Aggregate_Column.Minimum "days" "min", Aggregate_Column.Maximum "days" "max"] . sort "group"
r2.at "group" . to_vector . should_equal [1, 2]
r2.at "min" . to_vector . should_equal [Day_Of_Week.Monday, Day_Of_Week.Sunday]
r2.at "max" . to_vector . should_equal [Day_Of_Week.Tuesday, Day_Of_Week.Monday]