From 63f0a3b53bd78acecc0dc2aa1df3c208cf07ccf6 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:17 +0200 Subject: [PATCH 01/17] 40 red --- .../src/Internal/Base_Generator.enso | 7 ++--- .../src/Internal/SQLServer_Dialect.enso | 26 +++++++------------ test/Microsoft_Tests/src/SQLServer_Spec.enso | 4 +-- .../Aggregate_Spec.enso | 2 +- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Base_Generator.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Base_Generator.enso index 8a4b233782d6..ecdc797ebc85 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Base_Generator.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Base_Generator.enso @@ -179,6 +179,7 @@ type SQL_Generator generate_select_query_sql : Dialect -> Vector (Pair Text SQL_Expression) -> Context -> SQL_Builder generate_select_query_sql self dialect columns ctx = gen_exprs exprs = exprs.map (expr-> dialect.generate_expression self expr for_select=False) + gen_group_exprs exprs = exprs.map (expr-> dialect.generate_expression self expr for_select=True) gen_column pair = (dialect.generate_expression self expr=pair.second for_select=True) ++ alias dialect pair.first generated_columns = case columns of @@ -187,7 +188,7 @@ type SQL_Generator from_part = self.generate_from_part dialect ctx.from_spec where_part = (SQL_Builder.join " AND " (gen_exprs ctx.where_filters)) . prefix_if_present " WHERE " - group_part = (SQL_Builder.join ", " (gen_exprs ctx.groups)) . prefix_if_present " GROUP BY " + group_part = (SQL_Builder.join ", " (gen_group_exprs ctx.groups)) . prefix_if_present " GROUP BY " orders = ctx.orders.map (self.generate_order dialect) order_part = (SQL_Builder.join ", " orders) . prefix_if_present " ORDER BY " @@ -663,14 +664,14 @@ preprocess_query (query : Query) -> Query = column expression; it should be provided only if `has_quote` is `True` and must not be empty then. If the quote character occurs in the expression, it is escaped by doubling each occurrence. -make_concat make_raw_concat_expr make_contains_expr has_quote args = +make_concat make_raw_concat_expr make_contains_expr has_quote args append_char="||" = expected_args = if has_quote then 5 else 4 if args.length != expected_args then Error.throw (Illegal_State.Error "Unexpected number of arguments for the concat operation.") else expr = args.at 0 separator = args.at 1 prefix = args.at 2 suffix = args.at 3 - append = " || " + append = " " + append_char + " " possibly_quoted = case has_quote of True -> quote = args.at 4 diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index a681cc9fdeb1..615178e1a602 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -243,6 +243,7 @@ type SQLServer_Dialect Feature.Filter -> True Feature.Join -> True Feature.Union -> True + Feature.Aggregate -> True _ -> False ## PRIVATE @@ -401,6 +402,7 @@ private _generate_expression dialect base_gen expr expression_kind:Expression_Ki pair final_expr null_checks_result query : Query -> pair (base_gen.generate_sub_query dialect query) [] + descriptor : Order_Descriptor -> pair (base_gen.generate_order dialect descriptor) [] ## PRIVATE type Expression_Kind @@ -437,7 +439,7 @@ private _op_return_kind op -> Expression_Kind = if return_bool_ops.contains op then Expression_Kind.Boolean_Condition else Expression_Kind.Value private _op_needs_to_materialize_null_checks op -> Boolean = - ["FILL_NULL", "COALESCE"].contains op + ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL"].contains op ## PRIVATE make_dialect_operations = @@ -520,17 +522,17 @@ make_first_aggregator reverse ignore_null args = ## PRIVATE agg_shortest = Base_Generator.lift_unary_op "SHORTEST" arg-> - SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LENGTH(" ++ arg ++ "))" + SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LEN(" ++ arg ++ "))" ## PRIVATE agg_longest = Base_Generator.lift_unary_op "LONGEST" arg-> - SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LENGTH(" ++ arg ++ ") DESC)" + SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LEN(" ++ arg ++ ") DESC)" ## PRIVATE concat_ops = make_raw_concat_expr expr separator = SQL_Builder.code "string_agg(" ++ expr ++ ", " ++ separator ++ ")" - concat = Base_Generator.make_concat make_raw_concat_expr make_contains_expr + concat = Base_Generator.make_concat make_raw_concat_expr make_contains_expr append_char="+" [["CONCAT", concat (has_quote=False)], ["CONCAT_QUOTE_IF_NEEDED", concat (has_quote=True)]] ## PRIVATE @@ -554,14 +556,7 @@ agg_count_distinct args = if args.is_empty then (Error.throw (Illegal_Argument.E True -> ## A single null value will be skipped. SQL_Builder.code "COUNT(DISTINCT " ++ args.first ++ ")" - False -> - ## A tuple of nulls is not a null, so it will not be skipped - but - we want to ignore all-null columns. So we manually filter them - out. - count = SQL_Builder.code "COUNT(DISTINCT (" ++ SQL_Builder.join ", " args ++ "))" - are_nulls = args.map arg-> arg.paren ++ " IS NULL" - all_nulls_filter = SQL_Builder.code " FILTER (WHERE NOT (" ++ SQL_Builder.join " AND " are_nulls ++ "))" - (count ++ all_nulls_filter).paren + False -> Error.throw (Illegal_Argument.Error "COUNT_DISTINCT supports only single arguments in SQLServer.") ## PRIVATE agg_count_distinct_include_null args = case args.length == 1 of @@ -595,12 +590,11 @@ ends_with = Base_Generator.lift_binary_op "ENDS_WITH" str-> sub-> res.paren ## PRIVATE -contains = Base_Generator.lift_binary_op "CONTAINS" str-> sub-> - res = SQL_Builder.code "CHARINDEX(" ++ sub ++ ", " ++ str ++ ") > 0" - res.paren +make_contains_expr expr substring = + SQL_Builder.code "CHARINDEX(" ++ substring ++ ", " ++ expr ++ ") > 0" ## PRIVATE -make_contains_expr expr substring = contains [expr, substring] +contains = Base_Generator.lift_binary_op "CONTAINS" make_contains_expr ## PRIVATE make_case_sensitive = Base_Generator.lift_unary_op "MAKE_CASE_SENSITIVE" arg-> diff --git a/test/Microsoft_Tests/src/SQLServer_Spec.enso b/test/Microsoft_Tests/src/SQLServer_Spec.enso index c0c37beb98c8..eee5417ccb61 100644 --- a/test/Microsoft_Tests/src/SQLServer_Spec.enso +++ b/test/Microsoft_Tests/src/SQLServer_Spec.enso @@ -200,8 +200,8 @@ add_sqlserver_specs suite_builder create_connection_fn = materialize = .read common_selection = Common_Table_Operations.Main.Test_Selection.Config supported_replace_params=supported_replace_params run_advanced_edge_case_tests_by_default=True - aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config first_last_row_order=False aggregation_problems=False - agg_in_memory_table = (enso_project.data / "data.csv") . read + aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False aggregation_problems=False multi_distinct=False + agg_in_memory_table = ((Project_Description.new enso_dev.Table_Tests).data / "data.csv") . read agg_table_fn = _-> agg_in_memory_table.select_into_database_table default_connection.get (Name_Generator.random_name "Agg1") primary_key=Nothing temporary=True diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 9dca091a8e6e..303890f49a29 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -124,7 +124,7 @@ add_aggregate_specs suite_builder setup = materialized.columns.at 0 . name . should_equal "Count Distinct Index Flag" materialized.columns.at 0 . at 0 . should_equal 20 - group_builder.specify "should be able to compute sum and average of values" <| + group_builder.specify "should be able to compute sum and average of valuesx" <| grouped = data.table.aggregate columns=[Sum "Value", Sum "ValueWithNothing", Average "Value", Average "ValueWithNothing"] materialized = materialize grouped Problems.assume_no_problems materialized From 3e269325bbc0f427ac5793e5bc7d7bf0c3d47ac6 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:18 +0200 Subject: [PATCH 02/17] 18 Red --- .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 615178e1a602..c5cb0326e8da 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -471,15 +471,15 @@ private _make_iif arguments:Vector -> SQL_Builder = ## PRIVATE agg_count_is_null = Base_Generator.lift_unary_op "COUNT_IS_NULL" arg-> - SQL_Builder.code "SUM(CASE WHEN " ++ arg.paren ++ " IS NULL THEN 1 ELSE 0 END)" + SQL_Builder.code "COALESCE(SUM(CASE WHEN " ++ arg.paren ++ " IS NULL THEN 1 ELSE 0 END), 0)" ## PRIVATE agg_count_empty = Base_Generator.lift_unary_op "COUNT_EMPTY" arg-> - SQL_Builder.code "SUM(CASE WHEN (" ++ arg.paren ++ " IS NULL) OR (" ++ arg.paren ++ " = '') THEN 1 ELSE 0 END)" + SQL_Builder.code "COALESCE(SUM(CASE WHEN (" ++ arg.paren ++ " IS NULL) OR (" ++ arg.paren ++ " = '') THEN 1 ELSE 0 END), 0)" ## PRIVATE agg_count_not_empty = Base_Generator.lift_unary_op "COUNT_NOT_EMPTY" arg-> - SQL_Builder.code "SUM(CASE WHEN (" ++ arg.paren ++ " IS NOT NULL) AND (" ++ arg.paren ++ " != '') THEN 1 ELSE 0 END)" + SQL_Builder.code "COALESCE(SUM(CASE WHEN (" ++ arg.paren ++ " IS NOT NULL) AND (" ++ arg.paren ++ " != '') THEN 1 ELSE 0 END), 0)" ## PRIVATE From 822fd562ea3c3013cf834f6545f5c884bfcdc59c Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:18 +0200 Subject: [PATCH 03/17] 31 Red --- .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index c5cb0326e8da..b214c9d7768d 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -439,7 +439,7 @@ private _op_return_kind op -> Expression_Kind = if return_bool_ops.contains op then Expression_Kind.Boolean_Condition else Expression_Kind.Value private _op_needs_to_materialize_null_checks op -> Boolean = - ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL"].contains op + ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL", "STDDEV_POP", "STDDEV_SAMP"].contains op ## PRIVATE make_dialect_operations = @@ -449,8 +449,8 @@ make_dialect_operations = arith_extensions = [floating_point_div, mod_op, decimal_div, decimal_mod, ["ROW_MIN", Base_Generator.make_function "LEAST"], ["ROW_MAX", Base_Generator.make_function "GREATEST"]] bool = [bool_or] - stddev_pop = ["STDDEV_POP", Base_Generator.make_function "stddev_pop"] - stddev_samp = ["STDDEV_SAMP", Base_Generator.make_function "stddev_samp"] + stddev_pop = ["STDDEV_POP", Base_Generator.make_function "STDEVP"] + stddev_samp = ["STDDEV_SAMP", Base_Generator.make_function "STDEV"] stats = [agg_median, agg_mode, agg_percentile, stddev_pop, stddev_samp] date_ops = [["year", Base_Generator.make_function "year"], make_datepart "quarter", ["month", Base_Generator.make_function "month"], make_datepart "week" "iso_week", ["day", Base_Generator.make_function "day"], make_datepart "hour", make_datepart "minute", make_datepart "day_of_year" "dayofyear", make_day_of_week, make_datepart "second", make_datepart "millisecond", make_extract_microsecond, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]] special_overrides = [is_empty, ["IIF", _make_iif]] From 1f3342d9489bab77afd61c98c0d5a875a1416b36 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:18 +0200 Subject: [PATCH 04/17] 20 red --- .../src/Internal/Aggregate_Helper.enso | 2 +- .../src/Internal/SQLServer_Dialect.enso | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso index b13515f13277..e8c9939934df 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso @@ -35,7 +35,7 @@ from project.Errors import Aggregagtion_Requires_Order make_aggregate_column : DB_Table -> Aggregate_Column -> Text -> Dialect -> (Text -> Vector -> SQL_Expression -> SQL_Type_Reference) -> Problem_Builder -> Internal_Column make_aggregate_column table aggregate as dialect infer_return_type problem_builder -> Internal_Column = simple_aggregate op_kind columns = - expression = dialect.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) + expression = SQL_Expression.Operation op_kind (columns.map c->(dialect.cast_op_type op_kind columns c.expression)) sql_type_ref = infer_return_type op_kind columns expression Internal_Column.Value as sql_type_ref expression diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index b214c9d7768d..4e0b4e54fc9b 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -212,8 +212,22 @@ type SQLServer_Dialect is used only to override the type in cases where the default one that the database uses is not what we want. cast_op_type self (op_kind:Text) (args:(Vector Internal_Column)) (expression:SQL_Expression) = - _ = [op_kind, args] - expression + is_int8 ic = ic.sql_type_reference.get.typeid == Java_Types.BIGINT + is_int ic = + typeid = ic.sql_type_reference.get.typeid + typeid == Java_Types.SMALLINT || typeid == Java_Types.INTEGER || typeid == Java_Types.BIGINT + + cast_to = case op_kind of + "AVG" -> + if is_int (args.at 0) then "FLOAT" else Nothing + "STDDEV_POP" -> + if is_int (args.at 0) then "FLOAT" else Nothing + "STDDEV_SAMP" -> + if is_int (args.at 0) then "FLOAT" else Nothing + _ -> Nothing + + if cast_to.is_nothing then expression else + SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement @@ -439,7 +453,7 @@ private _op_return_kind op -> Expression_Kind = if return_bool_ops.contains op then Expression_Kind.Boolean_Condition else Expression_Kind.Value private _op_needs_to_materialize_null_checks op -> Boolean = - ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL", "STDDEV_POP", "STDDEV_SAMP"].contains op + ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL", "STDDEV_POP", "STDDEV_SAMP", "CONCAT", "CONCAT_QUOTE_IF_NEEDED"].contains op ## PRIVATE make_dialect_operations = From fab04a69d475c87a5149abbb904de4a0aae29b25 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:18 +0200 Subject: [PATCH 05/17] 18 Red --- .../Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 303890f49a29..07a1b552ce50 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -1262,7 +1262,7 @@ add_aggregate_specs suite_builder setup = loc = Meta.get_source_location 2 Test.fail "Expected a Nothing or NaN but got: "+value.to_text+" (at "+loc+")." - suite_builder.group prefix+"Table.aggregate should correctly handle infinities" group_builder-> + if setup.flagged ..Supports_Infinity then suite_builder.group prefix+"Table.aggregate should correctly handle infinities" group_builder-> pos_inf = 1/0 neg_inf = -1/0 From a00c4ff81de968f8aedde58cbd50d98c72239381 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:19 +0200 Subject: [PATCH 06/17] 15 red --- .../src/Internal/SQLServer_Dialect.enso | 25 +------------------ test/Microsoft_Tests/src/SQLServer_Spec.enso | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 4e0b4e54fc9b..371ab9e3a214 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -212,7 +212,6 @@ type SQLServer_Dialect is used only to override the type in cases where the default one that the database uses is not what we want. cast_op_type self (op_kind:Text) (args:(Vector Internal_Column)) (expression:SQL_Expression) = - is_int8 ic = ic.sql_type_reference.get.typeid == Java_Types.BIGINT is_int ic = typeid = ic.sql_type_reference.get.typeid typeid == Java_Types.SMALLINT || typeid == Java_Types.INTEGER || typeid == Java_Types.BIGINT @@ -469,7 +468,7 @@ make_dialect_operations = date_ops = [["year", Base_Generator.make_function "year"], make_datepart "quarter", ["month", Base_Generator.make_function "month"], make_datepart "week" "iso_week", ["day", Base_Generator.make_function "day"], make_datepart "hour", make_datepart "minute", make_datepart "day_of_year" "dayofyear", make_day_of_week, make_datepart "second", make_datepart "millisecond", make_extract_microsecond, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]] special_overrides = [is_empty, ["IIF", _make_iif]] other = [["RUNTIME_ERROR", make_runtime_error_op]] - my_mappings = text + counts + stats + first_last_aggregators + arith_extensions + bool + date_ops + special_overrides + other + my_mappings = text + counts + stats + arith_extensions + bool + date_ops + special_overrides + other base = Base_Generator.base_dialect_operations . extend_with my_mappings Base_Generator.Dialect_Operations.Value (base.operations_dict.remove "IS_IN") @@ -512,28 +511,6 @@ agg_percentile = Base_Generator.lift_binary_op "PERCENTILE" p-> expr-> has_nan = SQL_Builder.code "BOOLOR_AGG(" ++ expr ++ " = 'NaN'::Double)" SQL_Builder.code "CASE WHEN " ++ has_nan ++ " THEN 'NaN' ELSE " ++ percentile ++ " END" -## PRIVATE - These are written in a not most-efficient way, but a way that makes them - compatible with other group-by aggregations out-of-the-box. In the future, we - may want to consider some alternative solutions. -first_last_aggregators = - first = make_first_aggregator reverse=False ignore_null=False - first_not_null = make_first_aggregator reverse=False ignore_null=True - last = make_first_aggregator reverse=True ignore_null=False - last_not_null = make_first_aggregator reverse=True ignore_null=True - [["FIRST", first], ["FIRST_NOT_NULL", first_not_null], ["LAST", last], ["LAST_NOT_NULL", last_not_null]] - -## PRIVATE -make_first_aggregator reverse ignore_null args = - if args.length < 2 then Error.throw (Illegal_State.Error "Insufficient number of arguments for the operation.") else - result_expr = args.first - order_bys = args.drop 1 - - method_name = if reverse then "LAST_VALUE" else "FIRST_VALUE" - filter_clause = if ignore_null then ") IGNORE NULLS OVER" else ") OVER" - order_clause = SQL_Builder.code " ORDER BY " ++ SQL_Builder.join "," order_bys - SQL_Builder.code (method_name + "(") ++ result_expr ++ filter_clause ++ order_clause - ## PRIVATE agg_shortest = Base_Generator.lift_unary_op "SHORTEST" arg-> SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LEN(" ++ arg ++ "))" diff --git a/test/Microsoft_Tests/src/SQLServer_Spec.enso b/test/Microsoft_Tests/src/SQLServer_Spec.enso index eee5417ccb61..92978696c8d2 100644 --- a/test/Microsoft_Tests/src/SQLServer_Spec.enso +++ b/test/Microsoft_Tests/src/SQLServer_Spec.enso @@ -200,7 +200,7 @@ add_sqlserver_specs suite_builder create_connection_fn = materialize = .read common_selection = Common_Table_Operations.Main.Test_Selection.Config supported_replace_params=supported_replace_params run_advanced_edge_case_tests_by_default=True - aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False aggregation_problems=False multi_distinct=False + aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False aggregation_problems=False multi_distinct=False first_last_multi_order=False first_last_ignore_nothing=False agg_in_memory_table = ((Project_Description.new enso_dev.Table_Tests).data / "data.csv") . read agg_table_fn = _-> From 35c86108fb5bd2e98e9eccc0d9ee7617a1482dbf Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:19 +0200 Subject: [PATCH 07/17] 9 Red --- .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 371ab9e3a214..2d00007d96bd 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -452,7 +452,7 @@ private _op_return_kind op -> Expression_Kind = if return_bool_ops.contains op then Expression_Kind.Boolean_Condition else Expression_Kind.Value private _op_needs_to_materialize_null_checks op -> Boolean = - ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL", "STDDEV_POP", "STDDEV_SAMP", "CONCAT", "CONCAT_QUOTE_IF_NEEDED"].contains op + ["FILL_NULL", "COALESCE", "COUNT_IS_NULL", "COUNT_EMPTY", "COUNT_NOT_EMPTY", "COUNT", "SUM", "AVG", "LONGEST", "SHORTEST", "COUNT_DISTINCT", "COUNT_DISTINCT_INCLUDE_NULL", "STDDEV_POP", "STDDEV_SAMP", "CONCAT", "CONCAT_QUOTE_IF_NEEDED", "MIN", "MAX"].contains op ## PRIVATE make_dialect_operations = From 474548ee8cea37f1609bb700ea6924989410982d Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:19 +0200 Subject: [PATCH 08/17] 7 --- .../Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 07a1b552ce50..797111b738ce 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -1341,7 +1341,7 @@ add_aggregate_specs suite_builder setup = expect_null_or_nan <| m1.columns.first.at 0 expect_null_or_nan <| m1.columns.second.at 0 - suite_builder.group prefix+"Table.aggregate should correctly handle NaN" pending=(resolve_pending test_selection.nan) group_builder-> + if setup.flagged ..Supports_Separate_NaN then suite_builder.group prefix+"Table.aggregate should correctly handle NaN" pending=(resolve_pending test_selection.nan) group_builder-> nan = 0.log 0 group_builder.specify "on Average" <| t1 = table_builder [["X", [Nothing, nan, 0, 1, 2]]] From f60dc68b34875fcf465bd5ef9d29f92409bf7bd3 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:19 +0200 Subject: [PATCH 09/17] Comment out broken test for now --- .../src/Common_Table_Operations/Aggregate_Spec.enso | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 797111b738ce..71f8e1384a27 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -1771,7 +1771,7 @@ add_aggregate_specs suite_builder setup = problems.at 0 . location . should_equal "Float" if is_database then - suite_builder.group prefix+"Table.aggregate should report unsupported operations but not block other aggregations in warning mode" group_builder-> + suite_builder.group prefix+"Table.aggregate should report unsupported operations but not block other aggregations in warning mode" pending="TODO" group_builder-> expect_sum_and_unsupported_errors error_count result = within_table result <| result.column_count . should_equal 1 result.row_count . should_equal 1 @@ -1790,7 +1790,7 @@ add_aggregate_specs suite_builder setup = table = table_builder [["A", [3,2,1]], ["X", [1,2,3]]] order = [Sort_Column.Name "A"] expect_sum_and_unsupported_errors 2 <| - table.aggregate columns=[Sum "X", First ignore_nothing=False "X" (order_by=order), Last ignore_nothing=False "X" (order_by=order)] + table.aggregate columns=[Sum "X", First "X" ignore_nothing=False order_by=order, Last "X" ignore_nothing=False order_by=order] on_problems=..Report_Warning if test_selection.first_last_ignore_nothing.not then group_builder.specify "with First and Last with ignore_nothing=True" <| From 3435557be64429531fb3eb2fa42bcd4a3115aa9e Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:20 +0200 Subject: [PATCH 10/17] Green --- .../src/Internal/SQLServer_Dialect.enso | 29 +++++++++++++++++-- test/Microsoft_Tests/src/SQLServer_Spec.enso | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 2d00007d96bd..00908b1d8ff5 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -239,8 +239,31 @@ type SQLServer_Dialect ## PRIVATE check_aggregate_support : Aggregate_Column -> Boolean ! Unsupported_Database_Operation check_aggregate_support self aggregate = - _ = aggregate - True + unsupported name = + Error.throw (Unsupported_Database_Operation.Error name) + case aggregate of + Group_By _ _ -> True + Count _ -> True + Count_Distinct columns _ _ -> + if columns.length == 1 then True else + unsupported "Count_Distinct on multiple columns" + Count_Not_Nothing _ _ -> True + Count_Nothing _ _ -> True + Count_Not_Empty _ _ -> True + Count_Empty _ _ -> True + Percentile _ _ _ -> unsupported "Percentile" + Mode _ _ -> unsupported "Mode" + First _ _ _ _ -> unsupported "First" + Last _ _ _ _ -> unsupported "Last" + Maximum _ _ -> True + Minimum _ _ -> True + Shortest _ _ -> unsupported "Shortest" + Longest _ _ -> unsupported "Longest" + Standard_Deviation _ _ _ -> True + Concatenate _ _ _ _ _ _ -> True + Sum _ _ -> True + Average _ _ -> True + Median _ _ -> unsupported "Median" ## PRIVATE Checks if an operation is supported by the dialect. @@ -468,7 +491,7 @@ make_dialect_operations = date_ops = [["year", Base_Generator.make_function "year"], make_datepart "quarter", ["month", Base_Generator.make_function "month"], make_datepart "week" "iso_week", ["day", Base_Generator.make_function "day"], make_datepart "hour", make_datepart "minute", make_datepart "day_of_year" "dayofyear", make_day_of_week, make_datepart "second", make_datepart "millisecond", make_extract_microsecond, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]] special_overrides = [is_empty, ["IIF", _make_iif]] other = [["RUNTIME_ERROR", make_runtime_error_op]] - my_mappings = text + counts + stats + arith_extensions + bool + date_ops + special_overrides + other + my_mappings = text + counts + arith_extensions + bool + stats + date_ops + special_overrides + other base = Base_Generator.base_dialect_operations . extend_with my_mappings Base_Generator.Dialect_Operations.Value (base.operations_dict.remove "IS_IN") diff --git a/test/Microsoft_Tests/src/SQLServer_Spec.enso b/test/Microsoft_Tests/src/SQLServer_Spec.enso index 92978696c8d2..d0f38ac6e069 100644 --- a/test/Microsoft_Tests/src/SQLServer_Spec.enso +++ b/test/Microsoft_Tests/src/SQLServer_Spec.enso @@ -200,7 +200,7 @@ add_sqlserver_specs suite_builder create_connection_fn = materialize = .read common_selection = Common_Table_Operations.Main.Test_Selection.Config supported_replace_params=supported_replace_params run_advanced_edge_case_tests_by_default=True - aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False aggregation_problems=False multi_distinct=False first_last_multi_order=False first_last_ignore_nothing=False + aggregate_selection = Common_Table_Operations.Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False aggregation_problems=False multi_distinct=False first_last_multi_order=False first_last_ignore_nothing=False text_concat=False agg_in_memory_table = ((Project_Description.new enso_dev.Table_Tests).data / "data.csv") . read agg_table_fn = _-> From 8b5ce80166c04d1e7700d7104fbb2cbafb9f7726 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:20 +0200 Subject: [PATCH 11/17] Cleanup --- .../src/Internal/SQLServer_Dialect.enso | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 00908b1d8ff5..a99d4e15ba7b 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -487,7 +487,7 @@ make_dialect_operations = stddev_pop = ["STDDEV_POP", Base_Generator.make_function "STDEVP"] stddev_samp = ["STDDEV_SAMP", Base_Generator.make_function "STDEV"] - stats = [agg_median, agg_mode, agg_percentile, stddev_pop, stddev_samp] + stats = [stddev_pop, stddev_samp] date_ops = [["year", Base_Generator.make_function "year"], make_datepart "quarter", ["month", Base_Generator.make_function "month"], make_datepart "week" "iso_week", ["day", Base_Generator.make_function "day"], make_datepart "hour", make_datepart "minute", make_datepart "day_of_year" "dayofyear", make_day_of_week, make_datepart "second", make_datepart "millisecond", make_extract_microsecond, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]] special_overrides = [is_empty, ["IIF", _make_iif]] other = [["RUNTIME_ERROR", make_runtime_error_op]] @@ -517,23 +517,6 @@ agg_count_empty = Base_Generator.lift_unary_op "COUNT_EMPTY" arg-> agg_count_not_empty = Base_Generator.lift_unary_op "COUNT_NOT_EMPTY" arg-> SQL_Builder.code "COALESCE(SUM(CASE WHEN (" ++ arg.paren ++ " IS NOT NULL) AND (" ++ arg.paren ++ " != '') THEN 1 ELSE 0 END), 0)" - -## PRIVATE -agg_median = Base_Generator.lift_unary_op "MEDIAN" arg-> - median = SQL_Builder.code "MEDIAN(" ++ arg ++ ")" - has_nan = SQL_Builder.code "BOOLOR_AGG(" ++ arg ++ " = 'NaN'::Double)" - SQL_Builder.code "CASE WHEN " ++ has_nan ++ " THEN 'NaN'::Double ELSE " ++ median ++ " END" - -## PRIVATE -agg_mode = Base_Generator.lift_unary_op "MODE" arg-> - SQL_Builder.code "MODE(" ++ arg ++ ")" - -## PRIVATE -agg_percentile = Base_Generator.lift_binary_op "PERCENTILE" p-> expr-> - percentile = SQL_Builder.code "percentile_cont(" ++ p ++ ") WITHIN GROUP (ORDER BY " ++ expr ++ ")" - has_nan = SQL_Builder.code "BOOLOR_AGG(" ++ expr ++ " = 'NaN'::Double)" - SQL_Builder.code "CASE WHEN " ++ has_nan ++ " THEN 'NaN' ELSE " ++ percentile ++ " END" - ## PRIVATE agg_shortest = Base_Generator.lift_unary_op "SHORTEST" arg-> SQL_Builder.code "FIRST_VALUE(" ++ arg ++ ") IGNORE NULLS OVER (ORDER BY LEN(" ++ arg ++ "))" From c2a04681e86e91c6580757d59d5c2d9a247ab9b9 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:20 +0200 Subject: [PATCH 12/17] Changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d4db090dd76..6793a5646ca0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ - [Enhance Managed_Resource to allow implementation of in-memory caches][11577] - [Added `add_group_number` to the in-memory database.[11818] - [The reload button clears the HTTP cache.][11673] +- [SQL Server Support for Aggregate][11811] [11235]: https://github.com/enso-org/enso/pull/11235 [11255]: https://github.com/enso-org/enso/pull/11255 @@ -144,6 +145,7 @@ [11577]: https://github.com/enso-org/enso/pull/11577 [11818]: https://github.com/enso-org/enso/pull/11818 [11673]: https://github.com/enso-org/enso/pull/11673 +[11811]: https://github.com/enso-org/enso/pull/11811 #### Enso Language & Runtime From b4ae2857874b34c6dc692fdbf79103f4f100531c Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:20 +0200 Subject: [PATCH 13/17] Update check_aggregate_support --- .../0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index a99d4e15ba7b..df7e7fe458a4 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -237,8 +237,7 @@ type SQLServer_Dialect generate_collate self collation_name:Text -> Text = Base_Generator.default_generate_collate collation_name quote_char="" ## PRIVATE - check_aggregate_support : Aggregate_Column -> Boolean ! Unsupported_Database_Operation - check_aggregate_support self aggregate = + check_aggregate_support self aggregate:Aggregate_Column -> Boolean ! Unsupported_Database_Operation = unsupported name = Error.throw (Unsupported_Database_Operation.Error name) case aggregate of @@ -257,8 +256,8 @@ type SQLServer_Dialect Last _ _ _ _ -> unsupported "Last" Maximum _ _ -> True Minimum _ _ -> True - Shortest _ _ -> unsupported "Shortest" - Longest _ _ -> unsupported "Longest" + Shortest _ _ -> True + Longest _ _ -> True Standard_Deviation _ _ _ -> True Concatenate _ _ _ _ _ _ -> True Sum _ _ -> True From 1ad28a4f912fa1af54a698488b44b85be6b4d89e Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:21 +0200 Subject: [PATCH 14/17] Cleanup --- .../Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 71f8e1384a27..f9380ae3afda 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -124,7 +124,7 @@ add_aggregate_specs suite_builder setup = materialized.columns.at 0 . name . should_equal "Count Distinct Index Flag" materialized.columns.at 0 . at 0 . should_equal 20 - group_builder.specify "should be able to compute sum and average of valuesx" <| + group_builder.specify "should be able to compute sum and average of values" <| grouped = data.table.aggregate columns=[Sum "Value", Sum "ValueWithNothing", Average "Value", Average "ValueWithNothing"] materialized = materialize grouped Problems.assume_no_problems materialized From eac8dac90b54ded88de73d5e9bd3fc96b9ee3c64 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:21 +0200 Subject: [PATCH 15/17] Reenable test --- .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 4 ++-- .../src/Common_Table_Operations/Aggregate_Spec.enso | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index df7e7fe458a4..cb71c7d57af1 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -256,8 +256,8 @@ type SQLServer_Dialect Last _ _ _ _ -> unsupported "Last" Maximum _ _ -> True Minimum _ _ -> True - Shortest _ _ -> True - Longest _ _ -> True + Shortest _ _ -> unsupported "Shortest" + Longest _ _ -> unsupported "Longest" Standard_Deviation _ _ _ -> True Concatenate _ _ _ _ _ _ -> True Sum _ _ -> True diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index f9380ae3afda..6bdd30f483a6 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -1771,7 +1771,7 @@ add_aggregate_specs suite_builder setup = problems.at 0 . location . should_equal "Float" if is_database then - suite_builder.group prefix+"Table.aggregate should report unsupported operations but not block other aggregations in warning mode" pending="TODO" group_builder-> + suite_builder.group prefix+"Table.aggregate should report unsupported operations but not block other aggregations in warning mode" group_builder-> expect_sum_and_unsupported_errors error_count result = within_table result <| result.column_count . should_equal 1 result.row_count . should_equal 1 @@ -1817,7 +1817,7 @@ add_aggregate_specs suite_builder setup = expect_sum_and_unsupported_errors 2 <| table.aggregate columns=[Sum "X", Shortest "Y", Longest "Y"] - if test_selection.text_concat.not && (setup.prefix.contains "Snowflake" . not) then + if test_selection.text_concat.not && (setup.prefix.contains "Snowflake" . not && setup.prefix.contains "SQLServer" . not) then group_builder.specify "with Concatenate" <| table = table_builder [["X", [1,2,3]], ["Y", ["a", "bb", "ccc"]]] expect_sum_and_unsupported_errors 1 <| From 5aff3afc90caeea425a63e703949aaa18270d99b Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:22 +0200 Subject: [PATCH 16/17] Fix tests --- .../src/Database/Redshift/Internal/Redshift_Dialect.enso | 3 +++ .../Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso | 2 +- .../0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso | 3 +++ .../Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso | 3 +++ .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 3 +++ .../Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso | 3 +++ 6 files changed, 16 insertions(+), 1 deletion(-) diff --git a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso index 4d7c649c1f9e..8a2a5c625009 100644 --- a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso +++ b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso @@ -157,6 +157,9 @@ type Redshift_Dialect _ = [op_kind, args] expression + cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = + self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) + ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement prepare_fetch_types_query self expression context = diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso index e8c9939934df..812ed2422802 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Aggregate_Helper.enso @@ -35,7 +35,7 @@ from project.Errors import Aggregagtion_Requires_Order make_aggregate_column : DB_Table -> Aggregate_Column -> Text -> Dialect -> (Text -> Vector -> SQL_Expression -> SQL_Type_Reference) -> Problem_Builder -> Internal_Column make_aggregate_column table aggregate as dialect infer_return_type problem_builder -> Internal_Column = simple_aggregate op_kind columns = - expression = SQL_Expression.Operation op_kind (columns.map c->(dialect.cast_op_type op_kind columns c.expression)) + expression = dialect.cast_aggregate_columns op_kind columns sql_type_ref = infer_return_type op_kind columns expression Internal_Column.Value as sql_type_ref expression diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso index 533712091822..484cbbdd3920 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso @@ -231,6 +231,9 @@ type Postgres_Dialect if cast_to.is_nothing then expression else SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] + cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = + self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) + ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement prepare_fetch_types_query self expression context = diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso index efbc22421dc4..854187e89447 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso @@ -215,6 +215,9 @@ type SQLite_Dialect _ = [op_kind, args] expression + cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = + self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) + ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement prepare_fetch_types_query self expression context = diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index cb71c7d57af1..fa831eafd534 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -228,6 +228,9 @@ type SQLServer_Dialect if cast_to.is_nothing then expression else SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] + cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = + SQL_Expression.Operation op_kind (columns.map c->(self.cast_op_type op_kind columns (Internals_Access.column_expression c))) + ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement prepare_fetch_types_query self expression context = diff --git a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso index 778a3609dcac..e6de1bc885cc 100644 --- a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso +++ b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso @@ -219,6 +219,9 @@ type Snowflake_Dialect _ = [op_kind, args] expression + cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = + self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) + ## PRIVATE prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement prepare_fetch_types_query self expression context = From d92ce0627aa77728ff8dbcdc3a722e75dc625297 Mon Sep 17 00:00:00 2001 From: Adam Riley Date: Fri, 20 Dec 2024 17:57:23 +0200 Subject: [PATCH 17/17] Doc comment --- .../src/Database/Redshift/Internal/Redshift_Dialect.enso | 3 +++ .../0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso | 3 +++ .../Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso | 3 +++ .../Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso | 3 +++ .../Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso | 3 +++ 5 files changed, 15 insertions(+) diff --git a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso index 8a2a5c625009..36752731167d 100644 --- a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso +++ b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Internal/Redshift_Dialect.enso @@ -157,6 +157,9 @@ type Redshift_Dialect _ = [op_kind, args] expression + ## PRIVATE + Add an extra cast to adjust the output type of aggregate operations. + Some DBs do CAST(SUM(x) AS FLOAT) others do SUM(CAST(x AS FLOAT)). cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso index 484cbbdd3920..b99fa8bc3c49 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso @@ -231,6 +231,9 @@ type Postgres_Dialect if cast_to.is_nothing then expression else SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] + ## PRIVATE + Add an extra cast to adjust the output type of aggregate operations. + Some DBs do CAST(SUM(x) AS FLOAT) others do SUM(CAST(x AS FLOAT)). cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso index 854187e89447..69e4d50e201d 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso @@ -215,6 +215,9 @@ type SQLite_Dialect _ = [op_kind, args] expression + ## PRIVATE + Add an extra cast to adjust the output type of aggregate operations. + Some DBs do CAST(SUM(x) AS FLOAT) others do SUM(CAST(x AS FLOAT)). cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index fa831eafd534..59585a7649b5 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -228,6 +228,9 @@ type SQLServer_Dialect if cast_to.is_nothing then expression else SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] + ## PRIVATE + Add an extra cast to adjust the output type of aggregate operations. + Some DBs do CAST(SUM(x) AS FLOAT) others do SUM(CAST(x AS FLOAT)). cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = SQL_Expression.Operation op_kind (columns.map c->(self.cast_op_type op_kind columns (Internals_Access.column_expression c))) diff --git a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso index e6de1bc885cc..e5eaf0f7b3dc 100644 --- a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso +++ b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso @@ -219,6 +219,9 @@ type Snowflake_Dialect _ = [op_kind, args] expression + ## PRIVATE + Add an extra cast to adjust the output type of aggregate operations. + Some DBs do CAST(SUM(x) AS FLOAT) others do SUM(CAST(x AS FLOAT)). cast_aggregate_columns self op_kind:Text columns:(Vector Internal_Column) = self.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression))