From ce940442f1ca5e7fe9c23832c7c38343d4ebb8b3 Mon Sep 17 00:00:00 2001
From: EmirVildanov <reddog201030@gmail.com>
Date: Mon, 28 Oct 2024 21:36:14 +0300
Subject: [PATCH] feat: add tests for distinct asterisk, fix unit tests

---
 .../test/integration/groupby_test.lua         | 45 +++++++++++++++++++
 sbroad-core/src/executor/tests/exec_plan.rs   | 25 +++++------
 sbroad-core/src/frontend/sql/ir/tests.rs      | 37 ++++++++++++---
 3 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/sbroad-cartridge/test_app/test/integration/groupby_test.lua b/sbroad-cartridge/test_app/test/integration/groupby_test.lua
index 4d670ad6f7..bce587ed75 100644
--- a/sbroad-cartridge/test_app/test/integration/groupby_test.lua
+++ b/sbroad-cartridge/test_app/test/integration/groupby_test.lua
@@ -1742,6 +1742,51 @@ groupby_queries.test_total = function()
     })
 end
 
+groupby_queries.test_distinct_asterisk_single_column = function()
+    local api = cluster:server("api-1").net_box
+
+    local r, err = api:call("sbroad.execute", {
+        [[
+        WITH first  AS (SELECT "id" FROM "arithmetic_space" WHERE "id" = 1),
+             second AS (SELECT "id" FROM "arithmetic_space2" WHERE "id" = 2)
+        SELECT DISTINCT * FROM first JOIN second ON TRUE
+        ]], {}
+    })
+    t.assert_equals(err, nil)
+    t.assert_equals(r.metadata, {
+        { name = "id", type = "integer" },
+        { name = "id", type = "integer" },
+    })
+    t.assert_items_equals(r.rows, {
+        {1, 2},
+    })
+end
+
+groupby_queries.test_distinct_asterisk_several_columns = function()
+    local api = cluster:server("api-1").net_box
+
+    local r, err = api:call("sbroad.execute", {
+        [[
+        WITH first  AS (SELECT "id", "a" FROM "arithmetic_space"),
+             second AS (SELECT "id", "a" FROM "arithmetic_space2")
+        SELECT DISTINCT * FROM first JOIN second ON first."id" = second."id"
+        ]], {}
+    })
+    t.assert_equals(err, nil)
+    t.assert_equals(r.metadata, {
+        { name = "id", type = "integer" },
+        { name = "a", type = "integer" },
+        { name = "id", type = "integer" },
+        { name = "a", type = "integer" },
+    })
+    t.assert_items_equals(r.rows, {
+        {1, 1, 1, 2},
+        {2, 1, 2, 2},
+        {3, 2, 3, 1},
+        {4, 2, 4, 1},
+    })
+end
+
 groupby_queries.test_total_no_rows = function()
     local api = cluster:server("api-1").net_box
 
diff --git a/sbroad-core/src/executor/tests/exec_plan.rs b/sbroad-core/src/executor/tests/exec_plan.rs
index b393de31d9..5c8451a372 100644
--- a/sbroad-core/src/executor/tests/exec_plan.rs
+++ b/sbroad-core/src/executor/tests/exec_plan.rs
@@ -234,16 +234,13 @@ fn exec_plan_subtree_aggregates() {
     assert_eq!(
         sql,
         PatternWithParams::new(
-            format!(
-                "{} {} {} {} {} {} {}",
-                r#"SELECT "T1"."sys_op" as "column_596", ("T1"."id") * ("T1"."sys_op") as "column_1632","#,
-                r#""T1"."id" as "column_2096", group_concat ("T1"."FIRST_NAME", ?) as "group_concat_2496","#,
-                r#"count ("T1"."sysFrom") as "count_1596", total ("T1"."id") as "total_2896","#,
-                r#"min ("T1"."id") as "min_3096", count ("T1"."id") as "count_2696","#,
-                r#"max ("T1"."id") as "max_3296", sum ("T1"."id") as "sum_1796""#,
-                r#"FROM "test_space" as "T1""#,
-                r#"GROUP BY "T1"."sys_op", ("T1"."id") * ("T1"."sys_op"), "T1"."id""#,
-            ),
+            f_sql(r#"SELECT "T1"."sys_op" as "column_596",
+("T1"."id") * ("T1"."sys_op") as "column_1632", "T1"."id" as "column_2096",
+count ("T1"."id") as "count_2696", sum ("T1"."id") as "sum_1796",
+count ("T1"."sysFrom") as "count_1596", group_concat ("T1"."FIRST_NAME", ?) as "group_concat_2496",
+total ("T1"."id") as "total_2896", min ("T1"."id") as "min_3096", max ("T1"."id") as "max_3296"
+FROM "test_space" as "T1"
+GROUP BY "T1"."sys_op", ("T1"."id") * ("T1"."sys_op"), "T1"."id""#),
             vec![Value::from("o")]
         )
     );
@@ -256,11 +253,11 @@ fn exec_plan_subtree_aggregates() {
             format!(
                 "{} {} {} {} {} {} {} {}",
                 r#"SELECT ("COL_1") || ("COL_1") as "col_1","#,
-                r#"("COL_1") * (?) + (sum ("COL_5")) as "col_2", sum ("COL_10") as "col_3","#,
+                r#"("COL_1") * (?) + (sum ("COL_6")) as "col_2", sum ("COL_5") as "col_3","#,
                 r#"(sum (DISTINCT "COL_2")) / (count (DISTINCT "COL_3")) as "col_4","#,
-                r#"group_concat ("COL_4", ?) as "col_5","#,
-                r#"sum (CAST ("COL_10" as double)) / sum (CAST ("COL_8" as double)) as "col_6","#,
-                r#"total ("COL_6") as "col_7", min ("COL_7") as "col_8", max ("COL_9") as "col_9""#,
+                r#"group_concat ("COL_7", ?) as "col_5","#,
+                r#"sum (CAST ("COL_5" as double)) / sum (CAST ("COL_4" as double)) as "col_6","#,
+                r#"total ("COL_8") as "col_7", min ("COL_9") as "col_8", max ("COL_10") as "col_9""#,
                 r#"FROM (SELECT "COL_1","COL_2","COL_3","COL_4","COL_5","COL_6","COL_7","COL_8","COL_9","COL_10" FROM "TMP_test_0136")"#,
                 r#"GROUP BY "COL_1""#
             ),
diff --git a/sbroad-core/src/frontend/sql/ir/tests.rs b/sbroad-core/src/frontend/sql/ir/tests.rs
index d85da8c067..07a392a415 100644
--- a/sbroad-core/src/frontend/sql/ir/tests.rs
+++ b/sbroad-core/src/frontend/sql/ir/tests.rs
@@ -1704,9 +1704,9 @@ fn front_sql_aggregates() {
 
     let expected_explain = String::from(
         r#"projection ("column_596"::unsigned -> "b", ROW(sum(("count_1496"::integer))::decimal) + ROW(sum(("count_1596"::integer))::decimal) -> "col_1")
-    group by ("column_596"::unsigned) output: ("column_596"::unsigned -> "column_596", "count_1596"::integer -> "count_1596", "count_1496"::integer -> "count_1496")
+    group by ("column_596"::unsigned) output: ("column_596"::unsigned -> "column_596", "count_1496"::integer -> "count_1496", "count_1596"::integer -> "count_1596")
         motion [policy: segment([ref("column_596")])]
-            projection ("t"."b"::unsigned -> "column_596", count(("t"."b"::unsigned))::integer -> "count_1596", count(("t"."a"::unsigned))::integer -> "count_1496")
+            projection ("t"."b"::unsigned -> "column_596", count(("t"."a"::unsigned))::integer -> "count_1496", count(("t"."b"::unsigned))::integer -> "count_1596")
                 group by ("t"."b"::unsigned) output: ("t"."a"::unsigned -> "a", "t"."b"::unsigned -> "b", "t"."c"::unsigned -> "c", "t"."d"::unsigned -> "d", "t"."bucket_id"::unsigned -> "bucket_id")
                     scan "t"
 execution options:
@@ -1718,6 +1718,31 @@ execution options:
     assert_eq!(expected_explain, plan.as_explain().unwrap());
 }
 
+#[test]
+fn front_sql_distinct_asterisk() {
+    check_output(
+        r#"select distinct * from (select "id" from "test_space_hist")
+                 join (select "id" from "test_space") on true"#,
+    vec![],
+        r#"projection ("column_1996"::unsigned -> "id", "column_2096"::unsigned -> "id")
+    group by ("column_1996"::unsigned, "column_2096"::unsigned) output: ("column_1996"::unsigned -> "column_1996", "column_2096"::unsigned -> "column_2096")
+        motion [policy: segment([ref("column_1996"), ref("column_2096")])]
+            projection ("id"::unsigned -> "column_1996", "id"::unsigned -> "column_2096")
+                group by ("id"::unsigned, "id"::unsigned) output: ("id"::unsigned -> "id", "id"::unsigned -> "id")
+                    join on true::boolean
+                        scan
+                            projection ("test_space_hist"."id"::unsigned -> "id")
+                                scan "test_space_hist"
+                        motion [policy: full]
+                            scan
+                                projection ("test_space"."id"::unsigned -> "id")
+                                    scan "test_space"
+execution options:
+    vdbe_max_steps = 45000
+    vtable_max_rows = 5000
+"#)
+}
+
 #[test]
 fn front_sql_avg_aggregate() {
     let input = r#"SELECT avg("b"), avg(distinct "b"), avg("b") * avg("b") FROM "t""#;
@@ -1727,7 +1752,7 @@ fn front_sql_avg_aggregate() {
     let expected_explain = String::from(
         r#"projection (sum(("sum_696"::decimal::double))::decimal / sum(("count_696"::decimal::double))::decimal -> "col_1", avg(distinct ("column_796"::decimal::double))::decimal -> "col_2", ROW(sum(("sum_696"::decimal::double))::decimal / sum(("count_696"::decimal::double))::decimal) * ROW(sum(("sum_696"::decimal::double))::decimal / sum(("count_696"::decimal::double))::decimal) -> "col_3")
     motion [policy: full]
-        projection ("t"."b"::unsigned -> "column_796", count(("t"."b"::unsigned))::integer -> "count_696", sum(("t"."b"::unsigned))::decimal -> "sum_696")
+        projection ("t"."b"::unsigned -> "column_796", sum(("t"."b"::unsigned))::decimal -> "sum_696", count(("t"."b"::unsigned))::integer -> "count_696")
             group by ("t"."b"::unsigned) output: ("t"."a"::unsigned -> "a", "t"."b"::unsigned -> "b", "t"."c"::unsigned -> "c", "t"."d"::unsigned -> "d", "t"."bucket_id"::unsigned -> "bucket_id")
                 scan "t"
 execution options:
@@ -2529,9 +2554,9 @@ fn front_sql_groupby_expression3() {
     let plan = sql_to_optimized_ir(input, vec![]);
     let expected_explain = String::from(
         r#"projection ("column_532"::unsigned -> "col_1", "column_832"::unsigned * ROW(sum(("sum_2496"::decimal))::decimal) / ROW(sum(("count_2596"::integer))::decimal) -> "col_2")
-    group by ("column_532"::unsigned, "column_832"::unsigned) output: ("column_532"::unsigned -> "column_532", "column_832"::unsigned -> "column_832", "count_2596"::integer -> "count_2596", "sum_2496"::decimal -> "sum_2496")
+    group by ("column_532"::unsigned, "column_832"::unsigned) output: ("column_532"::unsigned -> "column_532", "column_832"::unsigned -> "column_832", "sum_2496"::decimal -> "sum_2496", "count_2596"::integer -> "count_2596")
         motion [policy: segment([ref("column_532"), ref("column_832")])]
-            projection (ROW("t"."a"::unsigned) + ROW("t"."b"::unsigned) -> "column_532", (ROW("t"."c"::unsigned) * ROW("t"."d"::unsigned)) -> "column_832", count((ROW("t"."a"::unsigned) * ROW("t"."b"::unsigned)))::integer -> "count_2596", sum((ROW("t"."c"::unsigned) * ROW("t"."d"::unsigned)))::decimal -> "sum_2496")
+            projection (ROW("t"."a"::unsigned) + ROW("t"."b"::unsigned) -> "column_532", (ROW("t"."c"::unsigned) * ROW("t"."d"::unsigned)) -> "column_832", sum((ROW("t"."c"::unsigned) * ROW("t"."d"::unsigned)))::decimal -> "sum_2496", count((ROW("t"."a"::unsigned) * ROW("t"."b"::unsigned)))::integer -> "count_2596")
                 group by (ROW("t"."a"::unsigned) + ROW("t"."b"::unsigned), (ROW("t"."c"::unsigned) * ROW("t"."d"::unsigned))) output: ("t"."a"::unsigned -> "a", "t"."b"::unsigned -> "b", "t"."c"::unsigned -> "c", "t"."d"::unsigned -> "d", "t"."bucket_id"::unsigned -> "bucket_id")
                     scan "t"
 execution options:
@@ -2978,7 +3003,7 @@ fn front_sql_unique_local_aggregates() {
     let expected_explain = String::from(
         r#"projection (sum(("sum_696"::decimal))::decimal -> "col_1", sum(("count_896"::integer))::decimal -> "col_2", ROW(sum(("sum_696"::decimal))::decimal) + ROW(sum(("count_896"::integer))::decimal) -> "col_3")
     motion [policy: full]
-        projection (sum(("t"."a"::unsigned))::decimal -> "sum_696", count(("t"."a"::unsigned))::integer -> "count_896")
+        projection (count(("t"."a"::unsigned))::integer -> "count_896", sum(("t"."a"::unsigned))::decimal -> "sum_696")
             scan "t"
 execution options:
     vdbe_max_steps = 45000
-- 
GitLab