Changeset: 57cde1d14e40 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/57cde1d14e40
Branch: default
Log Message:

Merge balanced_union branch into default.


diffs (truncated from 3330 to 300 lines):

diff --git a/monetdb5/optimizer/opt_support.c b/monetdb5/optimizer/opt_support.c
--- a/monetdb5/optimizer/opt_support.c
+++ b/monetdb5/optimizer/opt_support.c
@@ -264,6 +264,8 @@ isUpdateInstruction(InstrPtr p)
                && (getFunctionId(p) == appendRef || getFunctionId(p) == 
replaceRef
                        || getFunctionId(p) == deleteRef))
                return TRUE;
+       if (getModuleId(p) == matRef)
+               return TRUE;
        return FALSE;
 }
 
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -2328,6 +2328,13 @@ rel2bin_args(backend *be, sql_rel *rel, 
                args = rel2bin_args(be, rel->l, args);
                args = rel2bin_args(be, rel->r, args);
                break;
+       case op_munion:
+               if (rel->l) {
+                       for (node* n = ((list*)rel->l)->h; n; n = n->next) {
+                               args = rel2bin_args(be, n->data, args);
+                       }
+               }
+               break;
        case op_groupby:
                if (rel->r)
                        args = exps2bin_args(be, rel->r, args);
@@ -3864,6 +3871,65 @@ rel_rename(backend *be, sql_rel *rel, st
 }
 
 static stmt *
+rel2bin_munion(backend *be, sql_rel *rel, list *refs)
+{
+       mvc *sql = be->mvc;
+       list *l, *rstmts;
+       node *n, *m;
+       stmt *rel_stmt = NULL, *sub;
+       int i, len = 0, nr_unions = list_length((list*)rel->l);
+
+       /* convert to stmt and store the munion operands in rstmts list */
+       rstmts = sa_list(sql->sa);
+       for (n = ((list*)rel->l)->h; n; n = n->next) {
+               rel_stmt = subrel_bin(be, n->data, refs);
+               rel_stmt = subrel_project(be, rel_stmt, refs, n->data);
+               if (!rel_stmt)
+                       return NULL;
+               list_append(rstmts, rel_stmt);
+               if (!len || len > list_length(rel_stmt->op4.lval))
+                       len = list_length(rel_stmt->op4.lval);
+       }
+
+       /* construct relation */
+       l = sa_list(sql->sa);
+
+       /* for every op4 lval node */
+       //len = list_length(((stmt*)rstmts->h->data)->op4.lval);
+       for (i = 0; i < len; i++) {
+               /* extract t and c name from the first stmt */
+               stmt *s = list_fetch(((stmt*)rstmts->h->data)->op4.lval, i);
+               if (s == NULL)
+                       return NULL;
+               const char *rnme = table_name(sql->sa, s);
+               const char *nme = column_name(sql->sa, s);
+               /* create a const column also from the first stmt */
+               s = stmt_pack(be, column(be, s), nr_unions);
+               /* for every other rstmt */
+               for (m = rstmts->h->next; m; m = m->next) {
+                       stmt *t = list_fetch(((stmt*)m->data)->op4.lval, i);
+                       if (t == NULL)
+                               return NULL;
+                       s = stmt_pack_add(be, s, column(be, t));
+                       if (s == NULL)
+                               return NULL;
+               }
+               s = stmt_alias(be, s, rnme, nme);
+               if (s == NULL)
+                       return NULL;
+               list_append(l, s);
+       }
+       sub = stmt_list(be, l);
+
+       sub = rel_rename(be, rel, sub);
+       if (need_distinct(rel))
+               sub = rel2bin_distinct(be, sub, NULL);
+       if (is_single(rel))
+               sub = rel2bin_single(be, sub);
+       return sub;
+}
+
+static stmt *
 rel2bin_union(backend *be, sql_rel *rel, list *refs)
 {
        mvc *sql = be->mvc;
@@ -7294,6 +7360,10 @@ subrel_bin(backend *be, sql_rel *rel, li
                s = rel2bin_union(be, rel, refs);
                sql->type = Q_TABLE;
                break;
+       case op_munion:
+               s = rel2bin_munion(be, rel, refs);
+               sql->type = Q_TABLE;
+               break;
        case op_except:
                s = rel2bin_except(be, rel, refs);
                sql->type = Q_TABLE;
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -3447,6 +3447,78 @@ stmt_append_bulk(backend *be, stmt *c, l
 }
 
 stmt *
+stmt_pack(backend *be, stmt *c, int n)
+{
+       MalBlkPtr mb = be->mb;
+       InstrPtr q = NULL;
+
+       if (c == NULL || c->nr < 0)
+               goto bailout;
+       q = newStmtArgs(mb, matRef, packIncrementRef, 3);
+       if (q == NULL)
+               goto bailout;
+       q = pushArgument(mb, q, c->nr);
+       q = pushInt(mb, q, n);
+       bool enabled = be->mvc->sa->eb.enabled;
+       be->mvc->sa->eb.enabled = false;
+       stmt *s = stmt_create(be->mvc->sa, st_append);
+       be->mvc->sa->eb.enabled = enabled;
+       if(!s) {
+               freeInstruction(q);
+               goto bailout;
+       }
+       s->op1 = c;
+       s->nrcols = c->nrcols;
+       s->key = c->key;
+       s->nr = getDestVar(q);
+       s->q = q;
+       pushInstruction(mb, q);
+       return s;
+
+  bailout:
+       if (be->mvc->sa->eb.enabled)
+               eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr 
: mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
+       return NULL;
+
+}
+
+stmt *
+stmt_pack_add(backend *be, stmt *c, stmt *a)
+{
+       MalBlkPtr mb = be->mb;
+       InstrPtr q = NULL;
+
+       if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
+               goto bailout;
+       q = newStmtArgs(mb, matRef, packIncrementRef, 3);
+       if (q == NULL)
+               goto bailout;
+       q = pushArgument(mb, q, c->nr);
+       q = pushArgument(mb, q, a->nr);
+       bool enabled = be->mvc->sa->eb.enabled;
+       be->mvc->sa->eb.enabled = false;
+       stmt *s = stmt_create(be->mvc->sa, st_append);
+       be->mvc->sa->eb.enabled = enabled;
+       if(!s) {
+               freeInstruction(q);
+               goto bailout;
+       }
+       s->op1 = c;
+       s->op2 = a;
+       s->nrcols = c->nrcols;
+       s->key = c->key;
+       s->nr = getDestVar(q);
+       s->q = q;
+       pushInstruction(mb, q);
+       return s;
+
+  bailout:
+       if (be->mvc->sa->eb.enabled)
+               eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr 
: mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
+       return NULL;
+}
+
+stmt *
 stmt_claim(backend *be, sql_table *t, stmt *cnt)
 {
        MalBlkPtr mb = be->mb;
diff --git a/sql/backends/monet5/sql_statement.h 
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -174,6 +174,8 @@ extern stmt *stmt_append(backend *be, st
 extern stmt *stmt_append_bulk(backend *be, stmt *c, list *l);
 extern stmt *stmt_replace(backend *be, stmt *c, stmt *id, stmt *val);
 extern stmt *stmt_table_clear(backend *be, sql_table *t, int 
restart_sequences);
+extern stmt *stmt_pack(backend *be, stmt *c, int nr);
+extern stmt *stmt_pack_add(backend *be, stmt *c, stmt *values);
 
 extern stmt *stmt_export(backend *be, stmt *t, const char *sep, const char 
*rsep, const char *ssep, const char *null_string, int onclient, stmt *file);
 extern stmt *stmt_export_bin(backend *be, stmt *colstmt, bool byteswap, const 
char *filename, int on_client);
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -162,6 +162,7 @@ typedef enum operator_type {
        op_semi,
        op_anti,
        op_union,
+       op_munion,
        op_inter,
        op_except,
        op_groupby,
@@ -200,11 +201,13 @@ typedef enum operator_type {
 #define is_joinop(op)          (is_join(op) || is_semi(op))
 #define is_select(op)          (op == op_select)
 #define is_set(op)                     (op == op_union || op == op_inter || op 
== op_except)
+#define is_mset(op)            (op == op_munion || op == op_inter || op == 
op_except)
 #define is_union(op)           (op == op_union)
 #define is_inter(op)           (op == op_inter)
 #define is_except(op)          (op == op_except)
+#define is_munion(op)          (op == op_munion)
 #define is_simple_project(op)  (op == op_project)
-#define is_project(op)                 (op == op_project || op == op_groupby 
|| is_set(op))
+#define is_project(op)                 (op == op_project || op == op_groupby 
|| is_set(op) || is_munion(op))
 #define is_groupby(op)                 (op == op_groupby)
 #define is_topn(op)            (op == op_topn)
 #define is_modify(op)          (op == op_insert || op == op_update || op == 
op_delete || op == op_truncate || op == op_merge)
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -57,6 +57,12 @@ UNION|EXCEPT|INTERSECT
        -> l            is left relation
        -> r            is right relation
 
+MUNION
+       (card ATOM, AGGR or MULTI (same card as lower relation))
+    -> exps     is list of projection expressions
+    -> l        is list of union relations
+       -> flag         (0) no flags
+
 PROJECT  (card ATOM, AGGR or MULTI (same card as lower relation))
        -> exps         is list of projection expressions
        -> l            is relation
diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c
--- a/sql/server/rel_distribute.c
+++ b/sql/server/rel_distribute.c
@@ -80,7 +80,13 @@ has_remote_or_replica( sql_rel *rel )
        case op_insert:
        case op_update:
        case op_delete:
-               return has_remote_or_replica( rel->l) || has_remote_or_replica( 
rel->r );
+               return has_remote_or_replica( rel->l ) || 
has_remote_or_replica( rel->r );
+       case op_munion:
+               for (node *n = ((list*)rel->l)->h; n; n = n->next) {
+                       if (has_remote_or_replica(n->data))
+                               return true;
+               }
+               break;
        case op_project:
        case op_select:
        case op_groupby:
@@ -436,6 +442,9 @@ rel_rewrite_remote_(visitor *v, sql_rel 
                        }
                }
                break;
+       case op_munion:
+               /*assert(0);*/
+               break;
        case op_project:
        case op_select:
        case op_groupby:
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -574,6 +574,29 @@ rel_print_rel(mvc *sql, stream  *fout, s
                if (is_join(rel->op) && rel->attr) /* group joins */
                        exps_print(sql, fout, rel->attr, depth, refs, 1, 0, 
decorate);
                break;
+       case op_munion:
+               r = "munion";
+               if (is_dependent(rel))
+                       mnstr_printf(fout, "dependent ");
+               if (need_distinct(rel))
+                       mnstr_printf(fout, "distinct ");
+               mnstr_printf(fout, "%s (", r);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next) {
+                       if (rel_is_ref(n->data)) {
+                               int nr = find_ref(refs, n->data);
+                               print_indent(sql, fout, depth+1, decorate);
+                               mnstr_printf(fout, "& REF %d ", nr);
+                       } else {
+                               rel_print_rel(sql, fout, n->data, depth+1, 
refs, decorate);
+                       }
+                       if (n->next)
+                               mnstr_printf(fout, ",");
+               }
+               print_indent(sql, fout, depth, decorate);
+               mnstr_printf(fout, ")");
+               exps_print(sql, fout, rel->exps, depth, refs, 1, 0, decorate);
+               break;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to