Skip to content

Commit

Permalink
Tweaks from client Demo (#10685)
Browse files Browse the repository at this point in the history
- Adjusted Filter_Condition removing keep/drop from basic filters.
- Fix Is_In to have selector.
- Fix for Date simple expressions.
- Add get_row to Table and DB_Table.
  • Loading branch information
jdunkerley authored Jul 26, 2024
1 parent 20a04db commit 74acc1d
Show file tree
Hide file tree
Showing 18 changed files with 163 additions and 165 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ polyglot java import org.enso.base.Regex_Utils

type Filter_Condition
## Is less than a value (or another column, in case of Table operations)?
Less than=(Missing_Argument.throw "than") action:Filter_Action=Filter_Action.Keep
Less than=(Missing_Argument.throw "than")

## Is less than or equal to a value (or another column, in case of Table operations)?
Equal_Or_Less than=(Missing_Argument.throw "than") action:Filter_Action=Filter_Action.Keep
Equal_Or_Less than=(Missing_Argument.throw "than")

## Is equal to a value (or another column, in case of Table operations)?
Equal to=(Missing_Argument.throw "to") action:Filter_Action=Filter_Action.Keep
Equal to=(Missing_Argument.throw "to")

## Is greater than or equal to a value (or another column, in case of Table operations)?
Equal_Or_Greater than=(Missing_Argument.throw "than") action:Filter_Action=Filter_Action.Keep
Equal_Or_Greater than=(Missing_Argument.throw "than")

## Is greater than a value (or another column, in case of Table operations)?
Greater than=(Missing_Argument.throw "than") action:Filter_Action=Filter_Action.Keep
Greater than=(Missing_Argument.throw "than")

## Is not equal to a value (or another column, in case of Table operations)?
Not_Equal to=(Missing_Argument.throw "to") action:Filter_Action=Filter_Action.Keep
Not_Equal to=(Missing_Argument.throw "to")

## Is between (inclusive) two values (or columns, in case of Table operations)?
Between lower=(Missing_Argument.throw "lower") upper=(Missing_Argument.throw "upper") action:Filter_Action=Filter_Action.Keep
Between lower=(Missing_Argument.throw "lower") upper=(Missing_Argument.throw "upper") keep_or_remove:Filter_Action=..Keep

## Is equal to another value, ignoring case (Text only)?

Expand All @@ -58,60 +58,62 @@ type Filter_Condition
This ensures that different ways of expressing the same character in
the underlying binary representation are considered equal.
@locale Locale.default_widget
Equal_Ignore_Case (to = (Missing_Argument.throw "to")) (locale:Locale=Locale.default) action:Filter_Action=Filter_Action.Keep
Equal_Ignore_Case (to = (Missing_Argument.throw "to")) (locale:Locale=Locale.default) keep_or_remove:Filter_Action=..Keep

## Does the value start with a prefix (Text only)?

? Table Operations
It accepts a Text value to check if the value contains it. In case of
Table operations, it can accept another column - then the corresponding
values from the source column and the provided column are checked.
Starts_With (prefix = (Missing_Argument.throw "prefix")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) action:Filter_Action=Filter_Action.Keep
Starts_With (prefix = (Missing_Argument.throw "prefix")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) keep_or_remove:Filter_Action=..Keep

## Does the value end with a suffix (Text only)?

? Table Operations
It accepts a Text value to check if the value contains it. In case of
Table operations, it can accept another column - then the corresponding
values from the source column and the provided column are checked.
Ends_With (suffix = (Missing_Argument.throw "suffix")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) action:Filter_Action=Filter_Action.Keep
Ends_With (suffix = (Missing_Argument.throw "suffix")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) keep_or_remove:Filter_Action=..Keep

## Does the value contain the substring (Text only)?

? Table Operations
It accepts a Text value to check if the value contains it. In case of
Table operations, it can accept another column - then the corresponding
values from the source column and the provided column are checked.
Contains (substring = (Missing_Argument.throw "substring")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) action:Filter_Action=Filter_Action.Keep
Contains (substring = (Missing_Argument.throw "substring")) (case_sensitivity:Case_Sensitivity=Case_Sensitivity.Default) keep_or_remove:Filter_Action=..Keep

## Is equal to Nothing?
Is_Nothing action:Filter_Action=Filter_Action.Keep
Is_Nothing

## Is not equal to Nothing?
Not_Nothing action:Filter_Action=Filter_Action.Keep
Not_Nothing

## Is the value a NaN (Number only)?
Is_Nan action:Filter_Action=Filter_Action.Keep
Is_Nan

## Is the value not a NaN (Number only)?
Not_Nan

## Is the value infinite (Number only)?
Is_Infinite action:Filter_Action=Filter_Action.Keep
Is_Infinite

## Is the value finite (Number only)?

Finite numbers are ones that are not infinite nor NaN.
Is_Finite action:Filter_Action=Filter_Action.Keep
Is_Finite

## Is the value equal to True (Boolean only)?
Is_True action:Filter_Action=Filter_Action.Keep
Is_True

## Is the value equal to False (Boolean only)?
Is_False action:Filter_Action=Filter_Action.Keep
Is_False

## Is equal to "" or Nothing (Text only)?
Is_Empty action:Filter_Action=Filter_Action.Keep
Is_Empty

## Is not equal to "" and Nothing (Text only)?
Not_Empty action:Filter_Action=Filter_Action.Keep
Not_Empty

## Does the value match the SQL pattern (Text only)?

Expand All @@ -130,7 +132,7 @@ type Filter_Condition
Due to this limitation, Unicode normalization has been disabled for
this function, so beware that some equivalent graphemes like 'ś' and
's\u0301' will not be matched.
Like (pattern = (Missing_Argument.throw "pattern")) action:Filter_Action=Filter_Action.Keep
Like (pattern = (Missing_Argument.throw "pattern")) keep_or_remove:Filter_Action=..Keep

## Is the value contained in `values`?

Expand All @@ -144,7 +146,20 @@ type Filter_Condition
Using Columns can be particularly useful for Database operations, as
uploading a temporary table and using its column for an `Is_In` check
will likely be faster than using the vector directly.
Is_In values=[] action:Filter_Action=Filter_Action.Keep
Is_In values=[] keep_or_remove:Filter_Action=..Keep

## PRIVATE
The action to perform on the matched items.
action : Filter_Action
action self = case self of
Filter_Condition.Between _ _ action -> action
Filter_Condition.Equal_Ignore_Case _ _ action -> action
Filter_Condition.Starts_With _ _ action -> action
Filter_Condition.Ends_With _ _ action -> action
Filter_Condition.Contains _ _ action -> action
Filter_Condition.Like _ action -> action
Filter_Condition.Is_In _ action -> action
_ -> Filter_Action.Keep

## PRIVATE
Resolves a possibly auto-scoped value to a concrete value.
Expand All @@ -167,12 +182,12 @@ type Filter_Condition
to_predicate self =
base = case self of
# == does not need special handling for Nothing
Equal value _ -> ==value
Not_Equal value _ -> !=value
Less value _ -> handle_nothing (<value)
Equal_Or_Less value _ -> handle_nothing (<=value)
Equal_Or_Greater value _ -> handle_nothing (>=value)
Greater value _ -> handle_nothing (>value)
Equal value -> ==value
Not_Equal value -> !=value
Less value -> handle_nothing (<value)
Equal_Or_Less value -> handle_nothing (<=value)
Equal_Or_Greater value -> handle_nothing (>=value)
Greater value -> handle_nothing (>value)
Between lower upper _ -> handle_nothing <| elem->
(lower <= elem) && (elem <= upper)
Equal_Ignore_Case value locale _ ->
Expand All @@ -183,19 +198,20 @@ type Filter_Condition
handle_nothing <| txt-> (txt : Text).ends_with suffix case_sensitivity
Contains substring case_sensitivity _ ->
handle_nothing <| txt-> (txt : Text).contains substring case_sensitivity
Is_Nothing _ -> elem -> case elem of
Is_Nothing -> elem -> case elem of
Nothing -> True
_ -> False
Not_Nothing _ -> elem -> case elem of
Not_Nothing -> elem -> case elem of
Nothing -> False
_ -> True
Is_Nan _ -> handle_nothing x-> (x:Number).is_nan
Is_Infinite _ -> handle_nothing x-> (x:Number).is_infinite
Is_Finite _ -> handle_nothing x-> (x:Number).is_finite
Is_True _ -> handle_nothing b-> (b:Boolean)==True
Is_False _ -> handle_nothing b-> (b:Boolean)==False
Is_Empty _ -> elem-> elem.is_nothing || (elem : Text)==""
Not_Empty _ -> handle_nothing elem-> (elem : Text)!=""
Is_Nan -> handle_nothing x-> (x:Number).is_nan
Not_Nan -> handle_nothing x-> (x:Number).is_nan.not
Is_Infinite -> handle_nothing x-> (x:Number).is_infinite
Is_Finite -> handle_nothing x-> (x:Number).is_finite
Is_True -> handle_nothing b-> (b:Boolean)==True
Is_False -> handle_nothing b-> (b:Boolean)==False
Is_Empty -> elem-> elem.is_nothing || (elem : Text)==""
Not_Empty -> handle_nothing elem-> (elem : Text)!=""
Like sql_pattern _ ->
regex = sql_like_to_regex sql_pattern
handle_nothing <| regex.matches
Expand All @@ -210,28 +226,29 @@ type Filter_Condition
if case_sensitivity == Case_Sensitivity.Default then "" else " Case " + case_sensitivity.to_display_text

condition = case self of
Less value _ -> "<" + value.to_display_text
Equal_Or_Less value _ -> "<=" + value.to_display_text
Equal value _ -> "==" + value.to_display_text
Equal_Or_Greater value _ -> ">=" + value.to_display_text
Greater value _ -> ">" + value.to_display_text
Not_Equal value _ -> "!=" + value.to_display_text
Less value -> "<" + value.to_display_text
Equal_Or_Less value -> "<=" + value.to_display_text
Equal value -> "==" + value.to_display_text
Equal_Or_Greater value -> ">=" + value.to_display_text
Greater value -> ">" + value.to_display_text
Not_Equal value -> "!=" + value.to_display_text
Between lower upper _ -> "Between " + lower.to_display_text + " And " + upper.to_display_text
Equal_Ignore_Case value locale _ ->
suffix = if locale == Locale.default then "" else " (within locale " + locale.to_display_text + ")"
"Equal Ignore Case " + value.to_display_text + suffix
Starts_With prefix case_sensitivity _ -> "Starts With " + prefix.to_display_text + (render_case case_sensitivity)
Ends_With suffix case_sensitivity _ -> "Ends With " + suffix.to_display_text + (render_case case_sensitivity)
Contains substring case_sensitivity _ -> "Contains " + substring.to_display_text + (render_case case_sensitivity)
Is_Nothing _ -> "is Nothing"
Not_Nothing _ -> "is not Nothing"
Is_Nan _ -> "is NaN"
Is_Infinite _ -> "is Infinite"
Is_Finite _ -> "is Finite"
Is_True _ -> "is True"
Is_False _ -> "is False"
Is_Empty _ -> "is Empty"
Not_Empty _ -> "is not Empty"
Is_Nothing -> "is Nothing"
Not_Nothing -> "is not Nothing"
Is_Nan -> "is NaN"
Not_Nan -> "is not NaN"
Is_Infinite -> "is Infinite"
Is_Finite -> "is Finite"
Is_True -> "is True"
Is_False -> "is False"
Is_Empty -> "is Empty"
Not_Empty -> "is not Empty"
Like sql_pattern _ -> "Like " + sql_pattern.to_display_text
Is_In values _ -> "is in " + values.to_display_text
"Filter Condition: " + condition + (if self.action == Filter_Action.Keep then "" else " (Remove)")
Expand All @@ -257,6 +274,7 @@ type Filter_Condition
builder.append (Option "Is Finite" "..Is_Finite")
builder.append (Option "Is Infinite" "..Is_Infinite")
builder.append (Option "Is NaN" "..Is_Nan")
builder.append (Option "Is Not NaN" "..Not_Nan")

if include_boolean then
builder.append (Option "Is True" "..Is_True")
Expand All @@ -275,7 +293,7 @@ type Filter_Condition
builder.append (Option "Is Not Empty" "..Not_Empty")
builder.append (Option "Like" "..Like" [["pattern", Widget.Text_Input]])

value_editor = Widget.Vector_Editor item_editor=equatable_types display=Display.Always item_default=''
value_editor = Widget.Vector_Editor item_editor=equatable_types display=Display.Always item_default='""'
builder.append (Option "Is In" "..Is_In" [["values", value_editor]])

make_single_choice options
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import project.Any.Any
import project.Data.Filter_Condition.Filter_Action
import project.Data.Filter_Condition.Filter_Condition
import project.Data.Text.Case.Case
import project.Data.Text.Text
Expand Down Expand Up @@ -469,7 +468,7 @@ type Locale
predefined_locale_fields =
locale_meta = Meta.meta Locale
remove_us = locale_meta.methods + ["Value", "new", "default", "from_language_tag", "from_java", "predefined_locale_fields", "default_widget", "widget_options"]
Meta.Type.Value (Meta.type_of locale_meta.value) . methods . filter (Filter_Condition.Is_In remove_us Filter_Action.Remove) . sort
Meta.Type.Value (Meta.type_of locale_meta.value) . methods . filter (Filter_Condition.Is_In remove_us ..Remove) . sort

## PRIVATE
widget_options : Vector Option
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ type Connection
True -> result
False ->
hidden_tables = self.hidden_table_registry.list_hidden_tables
result.filter "Name" (Filter_Condition.Is_In hidden_tables Filter_Action.Remove)
result.filter "Name" (Filter_Condition.Is_In hidden_tables ..Remove)

## PRIVATE
Checks if the table with the given name exists in the database.
Expand Down
20 changes: 18 additions & 2 deletions distribution/lib/Standard/Database/0.0.0-dev/src/DB_Table.enso
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,29 @@ type DB_Table
- index: The index of the value to get within the column.
- 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_date=True add_time=True add_date_time=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
if Nothing == col then if_missing else col.get index if_missing

## ALIAS row
GROUP Standard.Base.Selections
ICON select_row
Gets a row from the table.
This is a live read from the database, so the results may change on
re-evaluation.

Arguments:
- index: The index of the row to get within the table.
- if_missing: The value to use if the selector isn't present.
get_row : Integer -> Any -> Any
get_row self index:Integer=0 ~if_missing=Nothing =
if index == -1 then self.last_row else
real_row = (if index < 0 then index + self.row_count else index)
if real_row < 0 then if_missing else
self.rows real_row+1 . get real_row if_missing

## ALIAS first cell
GROUP Standard.Base.Selections
ICON local_scope4
Expand Down Expand Up @@ -1981,7 +1997,7 @@ type DB_Table
aggregate : Vector (Integer | Text | Regex | Aggregate_Column) | Text | Integer | Regex -> Vector Aggregate_Column -> Boolean -> Problem_Behavior -> DB_Table ! No_Output_Columns | Invalid_Aggregate_Column | Invalid_Column_Names | Duplicate_Output_Column_Names | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings
aggregate self group_by=[] columns=[] (error_on_missing_columns:Boolean=False) (on_problems:Problem_Behavior=..Report_Warning) =
normalized_group_by = Vector.unify_vector_or_element group_by
if normalized_group_by.is_empty && columns.is_empty then Error.throw (No_Output_Columns.Error "At least one column must be specified.") else
if normalized_group_by.is_empty && columns.is_empty then Error.throw (No_Output_Columns.Error "No columns specified in aggregate.") else
## This is a workaround for #10321 - if the source query contains an ORDER BY,
we need to push it into a subquery to not interfere with aggregations.
base_table = if self.context.orders.not_empty then self.as_subquery else self
Expand Down
7 changes: 4 additions & 3 deletions distribution/lib/Standard/Table/0.0.0-dev/src/Errors.enso
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,10 @@ type No_Output_Columns

Pretty prints the no output columns error.
to_display_text : Text
to_display_text self =
if self.cause.is_nothing then "The result would contain no columns." else
"No columns in the result, because of another problem: "+self.cause.to_display_text
to_display_text self = case self.cause of
Nothing -> "The result would contain no columns."
_ : Text -> self.cause
_ -> "No columns in the result, because of another problem: "+self.cause.to_display_text

## Indicates that one column has been matched by multiple selectors, resulting
in ambiguous new names.
Expand Down
Loading

0 comments on commit 74acc1d

Please sign in to comment.