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

join: if the right side has 0 or 1 columns materialize it directly in the 
dict/group merger


diffs (205 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
@@ -1432,102 +1432,128 @@ join_produce(backend *be, sql_rel *rel, 
        wprintf(wstate, "let v%dvecs = (", result_var);
        wstate->num_parens++;
 
-       /* {appender[{..}], appender[..], appender[..] ... } */
+       /* Build the key in probe_key */
        len = 0;
-       len += sprintf(new_builder + len, "{appender[");
        if (list_length(rel->exps) > 1) {
-               len += sprintf(new_builder + len, "{"); /* key is a struct */
+               len += sprintf(probe_key + len, "{"); /* key is a struct */
        }
        for (en = rel->exps->h; en; en = en->next) {
                /* left cmp */
                exp = ((sql_exp*)en->data)->l;
                /* both have the same type */
                int type = exp_subtype(exp)->type->localtype;
-               len += sprintf(new_builder + len, "%s", getWeldType(type));
+               len += sprintf(probe_key + len, "%s", getWeldType(type));
                if (en->next != NULL) {
-                       len += sprintf(new_builder + len, ", ");
+                       len += sprintf(probe_key + len, ", ");
                }
        }
        if (list_length(rel->exps) > 1) {
-               len += sprintf(new_builder + len, "}"); /* key is a struct */
+               len += sprintf(probe_key + len, "}"); /* key is a struct */
        }
-       len += sprintf(new_builder + len, "]");
-       /* Create a list of right columns that are not part of the join key */
 
-       nulls_len = 0;
-       nulls[0] = 0;
-       for (en = right_cols->h, count = 1; en; en = en->next) {
-               exp = en->data;
-               int type = exp_subtype(exp)->type->localtype;
-               if (type == TYPE_str) {
-                       type = TYPE_lng;
+       if (is_unique && list_length(right_cols) == 0) {
+               sprintf(new_builder, "dictmerger[%s, i64, +]", probe_key);
+       } else if (!is_unique && list_length(right_cols) == 1) {
+               sprintf(new_builder, "groupmerger[%s, ?]", probe_key);
+       } else {
+               /* {appender[{..}], appender[..], appender[..] ... } */
+               len = 0;
+               len += sprintf(new_builder + len, "{appender[%s]", probe_key);
+               /* Create a list of right columns that are not part of the join 
key */
+               nulls_len = 0;
+               nulls[0] = 0;
+               for (en = right_cols->h, count = 1; en; en = en->next) {
+                       exp = en->data;
+                       int type = exp_subtype(exp)->type->localtype;
+                       if (type == TYPE_str) {
+                               type = TYPE_lng;
+                       }
+                       len += sprintf(new_builder + len, ", appender[%s]", 
getWeldType(type));
+                       nulls_len += sprintf(nulls + nulls_len, ", 
merge(v%dvecs.$%d, %snil)", result_var, count, getWeldType(type));
+                       count++;
                }
-               len += sprintf(new_builder + len, ", appender[%s]", 
getWeldType(type));
-               nulls_len += sprintf(nulls + nulls_len, ", merge(v%dvecs.$%d, 
%snil)", result_var, count, getWeldType(type));
-               count++;
+               len += sprintf(new_builder + len, "}"); /* complete the builder 
*/
        }
-       len += sprintf(new_builder + len, "}"); /* complete the builder */
 
        wstate->builder = new_builder;
        right_produce(be, rel->r, wstate);
 
        /* === Consume === */
-       wprintf(wstate, "{merge(b%d.$0, ", wstate->num_loops); /* {key, value} 
*/
        /* Build the key */
+       len = 0;
        if (list_length(right_cmp_cols) > 1) {
-               wprintf(wstate, "{"); /* key is a struct */
+               len += sprintf(probe_key + len, "{"); /* key is a struct */
        }
        for (en = right_cmp_cols->h; en; en = en->next) {
-               wprintf(wstate, "%s", (str)en->data);
+               len += sprintf(probe_key + len, "%s", (str)en->data);
                if (en->next != NULL) {
-                       wprintf(wstate, ", ");
+                       len += sprintf(probe_key + len, ", ");
                }
        }
        if (list_length(right_cmp_cols) > 1) {
-               wprintf(wstate, "}"); /* key is a struct */
-       }
-       wprintf(wstate, "), ");
-       /* Append the values */
-       for (en = right_cols->h, count = 0; en; en = en->next, count++) {
-               exp = en->data;
-               wprintf(wstate, "merge(b%d.$%d, %s", wstate->num_loops, count + 
1, (str)list_fetch(right_cols_names, count));
-               if (exp_subtype(exp)->type->localtype == TYPE_str) {
-                       wprintf(wstate, "_stridx");
-               }
-               wprintf(wstate, ")");
-               if (en->next != NULL) {
-                       wprintf(wstate, ", ");
-               }
-       }
-       wprintf(wstate, "}");
-       for (i = 0; i < wstate->num_parens; i++) {
-               wprintf(wstate, ")");
-       }
-       wprintf(wstate, ";");
-       /* Append the nulls at the end */
-       wprintf(wstate, "let v%dvecs = {v%dvecs.$0 %s};", result_var, 
result_var, nulls);
-       /* Materialize the hashtable */
-       wprintf(wstate, "let v%dkeys = result(v%dvecs.$0);", result_var, 
result_var);
-       for (en = right_cols->h, count = 0; en; en = en->next, count++) {
-               wprintf(wstate, "let v%dvec%d = result(v%dvecs.$%d);", 
result_var, count + 1, result_var, count + 1);
+               len += sprintf(probe_key + len, "}"); /* key is a struct */
        }
 
-       /* Build the hastable with indexes */
-       if (is_unique) {
-               wprintf(wstate, 
-               "let v%dtable = result("
-               "       for(v%dkeys, dictmerger[?, i64, +], |b, i, n|"
-               "               merge(b, {n, i})"
-               "       )"
-               ");", result_var, result_var);
+       if (is_unique && list_length(right_cols) == 0) {
+               /* unique values and no right cols */
+               wprintf(wstate, "merge(b%d, {%s, 0L})", wstate->num_loops, 
probe_key);
+               for (i = 0; i < wstate->num_parens; i++) {
+                       wprintf(wstate, ")");
+               }
+               wprintf(wstate, ";");
+               wprintf(wstate, "let v%dtable = result(v%dvecs);", result_var, 
result_var);
+       } else if (!is_unique && list_length(right_cols) == 1) {
+               /* groupmerger + a single right col */
+               wprintf(wstate, "merge(b%d, {%s, %s})", wstate->num_loops, 
probe_key, (str)right_cols_names->h->data);
+               for (i = 0; i < wstate->num_parens; i++) {
+                       wprintf(wstate, ")");
+               }
+               wprintf(wstate, ";");
+               wprintf(wstate, "let v%dtable = result(v%dvecs);", result_var, 
result_var);
+       } else {
+               wprintf(wstate, "{merge(b%d.$0, %s), ", wstate->num_loops, 
probe_key); /* {key, value} */
+               /* Append the values */
+               for (en = right_cols->h, count = 0; en; en = en->next, count++) 
{
+                       exp = en->data;
+                       wprintf(wstate, "merge(b%d.$%d, %s", wstate->num_loops, 
count + 1, (str)list_fetch(right_cols_names, count));
+                       if (exp_subtype(exp)->type->localtype == TYPE_str) {
+                               wprintf(wstate, "_stridx");
+                       }
+                       wprintf(wstate, ")");
+                       if (en->next != NULL) {
+                               wprintf(wstate, ", ");
+                       }
+               }
+               wprintf(wstate, "}");
+               for (i = 0; i < wstate->num_parens; i++) {
+                       wprintf(wstate, ")");
+               }
+               wprintf(wstate, ";");
+               /* Append the nulls at the end */
+               wprintf(wstate, "let v%dvecs = {v%dvecs.$0 %s};", result_var, 
result_var, nulls);
+               /* Materialize the hashtable */
+               wprintf(wstate, "let v%dkeys = result(v%dvecs.$0);", 
result_var, result_var);
+               for (en = right_cols->h, count = 0; en; en = en->next, count++) 
{
+                       wprintf(wstate, "let v%dvec%d = result(v%dvecs.$%d);", 
result_var, count + 1, result_var, count + 1);
+               }
 
-       } else {
-               wprintf(wstate, 
-               "let v%dtable = result("
-               "       for(v%dkeys, groupmerger[?, i64], |b, i, n|"
-               "               merge(b, {n, i})"
-               "       )"
-               ");", result_var, result_var);
+               /* Build the hastable with indexes */
+               if (is_unique) {
+                       wprintf(wstate, 
+                       "let v%dtable = result("
+                       "       for(v%dkeys, dictmerger[?, i64, +], |b, i, n|"
+                       "               merge(b, {n, i})"
+                       "       )"
+                       ");", result_var, result_var);
+
+               } else {
+                       wprintf(wstate, 
+                       "let v%dtable = result("
+                       "       for(v%dkeys, groupmerger[?, i64], |b, i, n|"
+                       "               merge(b, {n, i})"
+                       "       )"
+                       ");", result_var, result_var);
+               }
        }
 
        /* Resume the pipeline */
@@ -1574,6 +1600,8 @@ join_produce(backend *be, sql_rel *rel, 
        for (en = right_cols->h, count = 0; en; en = en->next, count++) {
                if (is_unique) {
                        sprintf(value, "lookup(v%dvec%d, match)", result_var, 
count + 1);
+               } else if (!is_unique && list_length(right_cols) == 1) {
+                       sprintf(value, "n%d", wstate->num_loops);
                } else {
                        sprintf(value, "lookup(v%dvec%d, n%d)", result_var, 
count + 1, wstate->num_loops);
                }
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to