Changeset: bb15c82c31bb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bb15c82c31bb
Modified Files:
        sql/backends/monet5/rel_weld.c
Branch: rel-weld
Log Message:

rel_weld: group_by - put all non aggr exps in the key


diffs (209 lines):

diff --git a/sql/backends/monet5/rel_weld.c b/sql/backends/monet5/rel_weld.c
--- a/sql/backends/monet5/rel_weld.c
+++ b/sql/backends/monet5/rel_weld.c
@@ -153,6 +153,10 @@ get_weld_func(sql_subfunc *f) {
                return "|";
        else if (strcmp(name, "<>") == 0 || strcmp(name, "!=") == 0)
                return "!=";
+       else if (strcmp(name, "min") == 0)
+               return "min";
+       else if (strcmp(name, "max") == 0)
+               return "max";
        else if (strcmp(name, "like") == 0)
                return "like";
        else if (strcmp(name, "year") == 0)
@@ -735,20 +739,36 @@ groupby_produce(backend *be, sql_rel *re
        int len = 0, i, col_count, aggr_count;
        node *en;
        sql_exp *exp;
-       list *group_by_exps = rel->r;
+       str aggr_func = NULL;
+       produce_func  input_produce;
+       list *group_by_exps = sa_list(wstate->sa);
+       list *aggr_exps = sa_list(wstate->sa);
+       list *project_exps = sa_list(wstate->sa);
 
        /* === Produce === */
        int old_num_parens = wstate->num_parens;
        int old_num_loops = wstate->num_loops;
        str old_builder = wstate->builder;
 
+       for (en = rel->exps->h; en; en = en->next) {
+               exp = en->data;
+               if (exp->type == e_aggr) {
+                       list_append(aggr_exps, exp);
+               } else {
+                       if (exp->type == e_column && exp->r && exp->name && 
strcmp((str)exp->r, exp->name) != 0) {
+                               list_append(project_exps, exp);
+                       } else {
+                               list_append(group_by_exps, exp);
+                       }
+               }
+       }
        /* Create a new builder */
        wstate->num_parens = wstate->num_loops = 0;
        int result_var = wstate->next_var++;
        wprintf(wstate, "let v%d = (", result_var);
        wstate->num_parens++;
        len = 0;
-       if (group_by_exps->h) {
+       if (list_length(group_by_exps) > 0) {
                len += sprintf(new_builder + len, "dictmerger[");
                if (list_length(group_by_exps) > 1) {
                        len += sprintf(new_builder + len, "{"); /* key is a 
struct */
@@ -772,45 +792,41 @@ groupby_produce(backend *be, sql_rel *re
        } else {
                len += sprintf(new_builder + len, "merger[");
        }
-       str aggr_func = NULL;
-       if (list_length(rel->exps) - list_length(group_by_exps) > 1) {
+       if (list_length(aggr_exps) > 1) {
                len += sprintf(new_builder + len, "{"); /* value is a struct */
        }
-       for (en = rel->exps->h; en; en = en->next) {
+       for (en = aggr_exps->h; en; en = en->next) {
                exp = en->data;
-               if (exp->type == e_aggr) {
-                       int type = exp_subtype(exp)->type->localtype;
-                       if (aggr_func == NULL) {
-                               aggr_func = get_weld_func(exp->f);
-                       } else if (aggr_func != get_weld_func(exp->f)) {
-                               /* Currently Weld only supports a single 
operation for mergers */
-                               wstate->error = 1;
-                       }
-                       len += sprintf(new_builder + len, "%s", 
getWeldType(type));
-                       if (en->next != NULL) {
-                               len += sprintf(new_builder + len, ", ");
-                       }
+               int type = exp_subtype(exp)->type->localtype;
+               if (aggr_func == NULL) {
+                       aggr_func = get_weld_func(exp->f);
+               } else if (aggr_func != get_weld_func(exp->f)) {
+                       /* Currently Weld only supports a single operation for 
mergers */
+                       wstate->error = 1;
+                       goto cleanup;
+               }
+               len += sprintf(new_builder + len, "%s", getWeldType(type));
+               if (en->next != NULL) {
+                       len += sprintf(new_builder + len, ", ");
                }
        }
-       if (list_length(rel->exps) - list_length(group_by_exps) > 1) {
+       if (list_length(aggr_exps) > 1) {
                len += sprintf(new_builder + len, "}"); /* value is a struct */
        }
        len += sprintf(new_builder + len, ", %s]", aggr_func);
        wstate->builder = new_builder;
-       produce_func input_produce = getproduce_func(rel->l);
+       input_produce = getproduce_func(rel->l);
        if (input_produce == NULL) {
                wstate->error = 1;
-               return;
+               goto cleanup;
        }
        input_produce(be, rel->l, wstate);
 
        /* === Consume === */
        wprintf(wstate, "merge(b%d, ", wstate->num_loops);
-       if (group_by_exps->h) { /* {key, value} */
+       if (list_length(group_by_exps) > 0) { /* {key, value} */
+               /* Build the key */
                wprintf(wstate, "{");
-       }
-       if (group_by_exps->h) {
-               /* Build the key */
                if (list_length(group_by_exps) > 1) {
                        wprintf(wstate, "{"); /* key is a struct */
                }
@@ -830,26 +846,24 @@ groupby_produce(backend *be, sql_rel *re
                }
                wprintf(wstate, ", ");
        }
-       if (list_length(rel->exps) - list_length(group_by_exps) > 1) {
+       if (list_length(aggr_exps) > 1) {
                wprintf(wstate, "{"); /* value is a struct */
        }
-       for (en = rel->exps->h; en; en = en->next) {
+       for (en = aggr_exps->h; en; en = en->next) {
                exp = en->data;
-               if (exp->type == e_aggr) {
-                       /* We might have different types when doing the 
aggregation */
-                       str weld_type = 
getWeldType(exp_subtype(exp)->type->localtype);
-                       wprintf(wstate, "%s(", weld_type);
-                       exp_to_weld(be, wstate, exp);
-                       wprintf(wstate, ")");
-                       if (en->next != NULL) {
-                               wprintf(wstate, ", ");
-                       }
+               /* We might have different types when doing the aggregation so 
we need to cast */
+               str weld_type = getWeldType(exp_subtype(exp)->type->localtype);
+               wprintf(wstate, "%s(", weld_type);
+               exp_to_weld(be, wstate, exp);
+               wprintf(wstate, ")");
+               if (en->next != NULL) {
+                       wprintf(wstate, ", ");
                }
        }
-       if (list_length(rel->exps) - list_length(group_by_exps) > 1) {
+       if (list_length(aggr_exps) > 1) {
                wprintf(wstate, "}"); /* value is a struct */
        }
-       if (group_by_exps->h) {
+       if (list_length(group_by_exps) > 0) {
                wprintf(wstate, "}"); /* {key, value} */
        }
        wprintf(wstate, ")");
@@ -876,25 +890,29 @@ groupby_produce(backend *be, sql_rel *re
        /* Column renaming */
        for (en = rel->exps->h; en; en = en->next) {
                exp = en->data;
-               if (group_by_exps->h) {
-                       if (exp->type == e_column) {
-                               len = sprintf(struct_mbr, "n%d.$0", 
wstate->num_loops);
-                               if (list_length(group_by_exps) > 1) {
-                                       len += sprintf(struct_mbr + len, 
".$%d", col_count++);
-                               }
-                       } else {
-                               len = sprintf(struct_mbr, "n%d.$1", 
wstate->num_loops);
-                               if (list_length(rel->exps) - 
list_length(group_by_exps) > 1) {
-                                       len += sprintf(struct_mbr + len, 
".$%d", aggr_count++);
-                               }
+               col_name = get_col_name(wstate->sa, exp, ALIAS);
+               if (list_find(project_exps, exp, NULL)) {
+                       /* Just use the old name */
+                       sprintf(struct_mbr, "%s", get_col_name(wstate->sa, exp, 
REL));
+               } else if (list_find(group_by_exps, exp, NULL)) {
+                       /* Set the name of a group by column */
+                       len = sprintf(struct_mbr, "n%d.$0", wstate->num_loops);
+                       if (list_length(group_by_exps) > 1) {
+                               len += sprintf(struct_mbr + len, ".$%d", 
col_count++);
+                       }
+               } else if (list_find(aggr_exps, exp, NULL) && 
list_length(group_by_exps) > 0) {
+                       /* Set the name of an aggregate if we used a dictmerger 
*/
+                       len = sprintf(struct_mbr, "n%d.$1", wstate->num_loops);
+                       if (list_length(aggr_exps) > 1) {
+                               len += sprintf(struct_mbr + len, ".$%d", 
aggr_count++);
                        }
                } else {
+                       /* Set the name of an aggregate if we used a merger */
                        len = sprintf(struct_mbr, "v%d", wstate->next_var);
-                       if (list_length(rel->exps) > 1) {
+                       if (list_length(aggr_exps) > 1) {
                                len += sprintf(struct_mbr + len, ".$%d", 
col_count++);
                        }
                }
-               col_name = get_col_name(wstate->sa, exp, ALIAS);
                if (exp_subtype(exp)->type->localtype == TYPE_str) {
                        wprintf(wstate, "let %s = strslice(%s_strcol, i64(%s) + 
%s_stroffset);", 
                                                   col_name, col_name, 
struct_mbr, col_name);
@@ -909,6 +927,10 @@ groupby_produce(backend *be, sql_rel *re
                        wprintf(wstate, "let %s = %s;", col_name, struct_mbr);
                }
        }
+cleanup:
+       list_destroy(group_by_exps);
+       list_destroy(aggr_exps);
+       list_destroy(project_exps);
 }
 
 static void
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to