Changeset: c52e948fd166 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c52e948fd166
Modified Files:
        sql/server/rel_select.c
        sql/test/analytics/Tests/analytics10.sql
        sql/test/analytics/Tests/analytics10.stable.out
Branch: grouping-analytics
Log Message:

Combining rollup and cube


diffs (truncated from 466 to 300 lines):

diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -4483,15 +4483,15 @@ static list*
 list_power_set(sql_allocator *sa, list* input) /* cube */
 {
        list *res = sa_list(sa);
-       // N stores total number of subsets
+       /* N stores total number of subsets */
        int N = (int) pow(2, input->cnt);
 
-       // generate each subset one by one
+       /* generate each subset one by one */
        for (int i = 0; i < N; i++) {
                list *ll = sa_list(sa);
-               int j = 0; // check every bit of i
+               int j = 0; /* check every bit of i */
                for (node *n = input->h ; n ; n = n->next) {
-                       // if j'th bit of i is set, then append
+                       /* if j'th bit of i is set, then append */
                        if (i & (1 << j))
                                list_append(ll, n->data);
                        j++;
@@ -4505,56 +4505,33 @@ static list*
 list_rollup(sql_allocator *sa, list* input)
 {
        list *res = sa_list(sa);
-       int counter, j;
-
-       for (counter = input->cnt; counter >= 0; counter--) {
+
+       for (int counter = input->cnt; counter > 0; counter--) {
                list *ll = sa_list(sa);
-               j = 0;
+               int j = 0;
                for (node *n = input->h; n && j < counter; j++, n = n->next)
                        list_append(ll, n->data);
                list_append(res, ll);
        }
+       list_append(res, sa_list(sa)); /* global aggregate case */
        return res;
 }
 
-static int
-list_equal(list* list1, list* list2)
-{
-       for (node *n = list1->h; n ; n = n->next) {
-               sql_exp *e = (sql_exp*) n->data;
-               if (!exps_find_exp(list2, e))
-                       return 1;
-       }
-       for (node *n = list2->h; n ; n = n->next) {
-               sql_exp *e = (sql_exp*) n->data;
-               if (!exps_find_exp(list1, e))
-                       return 1;
-       }
-       return 0;
-}
-
-/*
-(a, b),
-(a),
-()
-
-(c)
-*/
-
 static list*
 lists_cartesian_product_and_distinct(sql_allocator *sa, list *l1, list *l2)
 {
        list *res = sa_list(sa);
 
+       /* for each list of l2, merge into each list of l1 while removing 
duplicates */
        for (node *n = l1->h ; n ; n = n->next) {
                list *sub_list = (list*) n->data;
 
                for (node *m = l2->h ; m ; m = m->next) {
                        list *other = (list*) m->data;
-                       list_append(res, list_merge(list_dup(sub_list, (fdup) 
NULL), other, (fdup) NULL));
-               }
-       }
-       return list_distinct(res, (fcmp)list_equal, (fdup)NULL);
+                       list_append(res, 
list_distinct(list_merge(list_dup(sub_list, (fdup) NULL), other, (fdup) NULL), 
(fcmp) exp_equal, (fdup) NULL));
+               }
+       }
+       return res;
 }
 
 static list*
@@ -4576,6 +4553,8 @@ rel_groupings(sql_query *query, sql_rel 
                symbol *grouping = o->data.sym;
                dlist *dl = grouping->data.lval;
                if (dl) { /* GROUP BY a, b, ... case */
+                       list *gexps = new_exp_list(sql->sa);
+                       
                        for (dnode *oo = dl->h; oo; oo = oo->next) {
                                symbol *grp = oo->data.sym;
                                sql_exp *e = rel_group_column(query, rel, grp, 
selection, f);
@@ -4590,36 +4569,37 @@ rel_groupings(sql_query *query, sql_rel 
                                        if (!stack_push_groupby_expression(sql, 
grp, e))
                                                return NULL;
                                }
-                               list_append(exps, e);
+                               list_append(gexps, e);
                        }
                        if (grouping->token == SQL_ROLLUP) {
                                assert(combined_totals);
                                if (!*sets) {
-                                       *sets = list_rollup(sql->sa, exps);
+                                       *sets = list_rollup(sql->sa, gexps);
                                } else {
-                                       list *new_set = list_rollup(sql->sa, 
exps);
+                                       list *new_set = list_rollup(sql->sa, 
gexps);
                                        *sets = 
lists_cartesian_product_and_distinct(sql->sa, *sets, new_set);
                                }
                        } else if (grouping->token == SQL_CUBE) {
                                assert(combined_totals);
                                if (!*sets) {
-                                       *sets = list_power_set(sql->sa, exps);
+                                       *sets = list_power_set(sql->sa, gexps);
                                } else {
-                                       list *new_set = list_power_set(sql->sa, 
exps);
+                                       list *new_set = list_power_set(sql->sa, 
gexps);
                                        *sets = 
lists_cartesian_product_and_distinct(sql->sa, *sets, new_set);
                                }
                        } else if (combined_totals && grouping->token == 
SQL_GROUPBY) {
                                if (!*sets) {
-                                       list *single_l = list_dup(exps, 
(fdup)NULL);
+                                       list *single_l = list_dup(gexps, 
(fdup)NULL);
                                        *sets = sa_list(sql->sa);
                                        list_append(*sets, single_l);
                                } else {
-                                       list *single_l = list_dup(exps, 
(fdup)NULL);
+                                       list *single_l = list_dup(gexps, 
(fdup)NULL);
                                        list *new_set = sa_list(sql->sa);
                                        list_append(new_set, single_l);
                                        *sets = 
lists_cartesian_product_and_distinct(sql->sa, *sets, new_set);
                                }
                        }
+                       exps = list_merge(exps, gexps, (fdup) NULL);
                } /* The GROUP BY () case is the global aggregate which is 
always added by ROLLUP and CUBE */
        }
        return exps;
diff --git a/sql/test/analytics/Tests/analytics10.sql 
b/sql/test/analytics/Tests/analytics10.sql
--- a/sql/test/analytics/Tests/analytics10.sql
+++ b/sql/test/analytics/Tests/analytics10.sql
@@ -1,11 +1,33 @@
 CREATE TABLE tbl_ProductSales (ColID int, Product_Category  varchar(64), 
Product_Name  varchar(64), TotalSales int); 
 INSERT INTO tbl_ProductSales VALUES (1,'Game','Mobo Game',200),(2,'Game','PKO 
Game',400),(3,'Fashion','Shirt',500),(4,'Fashion','Shorts',100);
 
+SELECT CAST(SUM(TotalSales) as BIGINT) AS TotalSales FROM tbl_ProductSales;
+
 SELECT 
     CAST(SUM(TotalSales) as BIGINT) AS TotalSales
 FROM tbl_ProductSales
 GROUP BY (); --global aggregate
 
+SELECT 
+    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY (), (); --does the same global aggregate
+
+SELECT 
+    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY Product_Category;
+
+SELECT 
+    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY Product_Name;
+
+SELECT 
+    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY Product_Category, Product_Name;
+
 -- ROLLUP
 
 SELECT 
@@ -59,6 +81,8 @@ SELECT
 FROM tbl_ProductSales
 GROUP BY CUBE(Product_Category, Product_Name) ORDER BY Product_Category, 
Product_Name;
 
+-- ROLLUP/CUBE with column
+
 SELECT
     Product_Category, CAST(SUM(TotalSales) as BIGINT) AS TotalSales
 FROM tbl_ProductSales
@@ -79,4 +103,31 @@ SELECT
 FROM tbl_ProductSales
 GROUP BY (ColID), CUBE(Product_Category, Product_Name);
 
+-- Combining ROLLUP and CUBE
+
+SELECT 
+    Product_Category, CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY ROLLUP(Product_Category), ROLLUP(Product_Category);
+
+SELECT
+    Product_Category, CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+FROM tbl_ProductSales
+GROUP BY CUBE(Product_Category), CUBE(Product_Category);
+
+SELECT
+    Product_Category, Product_Name, CAST(SUM(TotalSales) as BIGINT) AS 
TotalSales
+FROM tbl_ProductSales
+GROUP BY ROLLUP(Product_Category, Product_Name), ROLLUP(Product_Category, 
Product_Name);
+
+SELECT
+    Product_Category, Product_Name, CAST(SUM(TotalSales) as BIGINT) AS 
TotalSales
+FROM tbl_ProductSales
+GROUP BY CUBE(Product_Category, Product_Name), CUBE(Product_Category, 
Product_Name);
+
+SELECT
+    Product_Category, Product_Name, CAST(SUM(TotalSales) as BIGINT) AS 
TotalSales
+FROM tbl_ProductSales
+GROUP BY ROLLUP(Product_Category, Product_Name), CUBE(Product_Category, 
Product_Name);
+
 DROP TABLE tbl_ProductSales;
diff --git a/sql/test/analytics/Tests/analytics10.stable.out 
b/sql/test/analytics/Tests/analytics10.stable.out
--- a/sql/test/analytics/Tests/analytics10.stable.out
+++ b/sql/test/analytics/Tests/analytics10.stable.out
@@ -26,6 +26,12 @@ stdout of test 'analytics10` in director
 #CREATE TABLE tbl_ProductSales (ColID int, Product_Category clob, Product_Name 
clob, TotalSales int); 
 #INSERT INTO tbl_ProductSales VALUES (1,'Game','Mobo Game',200),(2,'Game','PKO 
Game',400),(3,'Fashion','Shirt',500),(4,'Fashion','Shorts',100);
 [ 4    ]
+#SELECT CAST(SUM(TotalSales) as BIGINT) AS TotalSales FROM tbl_ProductSales;
+% sys.L4 # table_name
+% totalsales # name
+% bigint # type
+% 4 # length
+[ 1200 ]
 #SELECT 
 #    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
 #FROM tbl_ProductSales
@@ -36,6 +42,49 @@ stdout of test 'analytics10` in director
 % 4 # length
 [ 1200 ]
 #SELECT
+#    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+#FROM tbl_ProductSales
+#GROUP BY (), (); --does the same global aggregate
+% sys.L3 # table_name
+% totalsales # name
+% bigint # type
+% 4 # length
+[ 1200 ]
+#SELECT 
+#    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+#FROM tbl_ProductSales
+#GROUP BY Product_Category;
+% sys.L3 # table_name
+% totalsales # name
+% bigint # type
+% 3 # length
+[ 600  ]
+[ 600  ]
+#SELECT 
+#    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+#FROM tbl_ProductSales
+#GROUP BY Product_Name;
+% sys.L3 # table_name
+% totalsales # name
+% bigint # type
+% 3 # length
+[ 200  ]
+[ 400  ]
+[ 500  ]
+[ 100  ]
+#SELECT 
+#    CAST(SUM(TotalSales) as BIGINT) AS TotalSales
+#FROM tbl_ProductSales
+#GROUP BY Product_Category, Product_Name;
+% sys.L3 # table_name
+% totalsales # name
+% bigint # type
+% 3 # length
+[ 200  ]
+[ 400  ]
+[ 500  ]
+[ 100  ]
+#SELECT
 #    Product_Category, CAST(SUM(TotalSales) as BIGINT) AS TotalSales
 #FROM tbl_ProductSales
 #GROUP BY ROLLUP(Product_Category);
@@ -211,6 +260,178 @@ stdout of test 'analytics10` in director
 [ "Game",      "PKO Game",     400     ]
 [ "Fashion",   "Shirt",        500     ]
 [ "Fashion",   "Shorts",       100     ]
+#SELECT Product_Category, CAST(SUM(TotalSales) as BIGINT) AS TotalSales FROM 
tbl_ProductSales GROUP BY ROLLUP(Product_Category), ROLLUP(Product_Category);
+% .tbl_productsales,   .L3 # table_name
+% product_category,    totalsales # name
+% varchar,     bigint # type
+% 7,   4 # length
+[ "Game",      600     ]
+[ "Fashion",   600     ]
+[ "Game",      600     ]
+[ "Fashion",   600     ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to