Changeset: cddad7ccf85b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/cddad7ccf85b
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/rel.txt
        sql/server/rel_distribute.c
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_optimize_others.c
        sql/server/rel_optimize_proj.c
        sql/server/rel_optimize_sel.c
        sql/server/rel_partition.c
        sql/server/rel_propagate.c
        sql/server/rel_rel.c
        sql/server/rel_rewriter.c
        sql/server/rel_select.c
        sql/server/rel_statistics.c
        sql/server/rel_unnest.c
        sql/server/sql_partition.c
Branch: balanced_union
Log Message:

Handling multi-union op in most cases WIP


diffs (truncated from 425 to 300 lines):

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
@@ -2230,7 +2230,11 @@ rel2bin_args(backend *be, sql_rel *rel, 
                args = rel2bin_args(be, rel->r, args);
                break;
        case op_munion:
-               assert(0);
+               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)
@@ -6716,6 +6720,7 @@ subrel_bin(backend *be, sql_rel *rel, li
                sql->type = Q_TABLE;
                break;
        case op_munion:
+               // TODO: rel2bin_munion()
                assert(0);
                break;
        case op_except:
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -57,8 +57,7 @@ MUNION
        (card ATOM, AGGR or MULTI (same card as lower relation))
     -> exps     is list of projection expressions
     -> l        is list of union relations
-    -> r        TBD # probably NULL
-    -> flag     TBD
+       -> flag         (0) no flags
 
 PROJECT  (card ATOM, AGGR or MULTI (same card as lower relation))
        -> exps         is list of projection expressions
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
@@ -48,7 +48,10 @@ has_remote_or_replica( sql_rel *rel )
        case op_delete:
                return has_remote_or_replica( rel->l ) || 
has_remote_or_replica( rel->r );
        case op_munion:
-               assert(0);
+               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:
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
@@ -505,7 +505,25 @@ rel_print_rel(mvc *sql, stream  *fout, s
                        exps_print(sql, fout, rel->attr, depth, refs, 1, 0);
                break;
        case op_munion:
-               assert(0);
+               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);
+                       }
+               }
+               print_indent(sql, fout, depth, decorate);
+               mnstr_printf(fout, ")");
+               exps_print(sql, fout, rel->exps, depth, refs, 1, 0);
                break;
        case op_project:
        case op_select:
@@ -660,7 +678,16 @@ rel_print_refs(mvc *sql, stream* fout, s
                }
                break;
        case op_munion:
-               assert(0);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next) {
+                       // TODO: do we need to check n->data?
+                       if (n->data)
+                               rel_print_refs(sql, fout, n->data, depth, refs, 
decorate);
+                       if (n->data && rel_is_ref(n->data) && !find_ref(refs, 
n->data)) {
+                               rel_print_rel(sql, fout, n->data, depth, refs, 
decorate);
+                               list_append(refs, n->data);
+                       }
+               }
                break;
        case op_insert:
        case op_update:
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -3357,11 +3357,11 @@ rel_find_parameter(mvc *sql, sql_subtype
                        break;
                case op_union: /* TODO for set relations this needs further 
improvement */
                case op_inter:
-               case op_except: {
+               case op_except:
+               case op_munion: {
                        (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set 
parameter types under set relations at the moment");
                        return -1;
                }
-               case op_munion:
                default: /* For table returning functions, the type must be set 
when the relation is created */
                        return 0;
        }
diff --git a/sql/server/rel_optimize_others.c b/sql/server/rel_optimize_others.c
--- a/sql/server/rel_optimize_others.c
+++ b/sql/server/rel_optimize_others.c
@@ -621,7 +621,29 @@ rel_mark_used(mvc *sql, sql_rel *rel, in
                break;
 
        case op_munion:
-               assert(0);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next) {
+                       // TODO: here we blindly follow the same logic as 
op_union. RE-evaluate
+                       if (proj && (need_distinct(rel) || !rel->exps)) {
+                               rel_used(rel);
+                               if (!rel->exps) {
+                                       rel_used(n->data);
+                               }
+                               rel_mark_used(sql, n->data, 0);
+                       } else if (proj && !need_distinct(rel)) {
+                               sql_rel *l = n->data;
+
+                               positional_exps_mark_used(rel, l);
+                               rel_exps_mark_used(sql->sa, rel, l);
+                               rel_mark_used(sql, rel->l, 0);
+                               /* based on child check set expression list */
+                               if (is_project(l->op) && need_distinct(l))
+                                       positional_exps_mark_used(l, rel);
+                               positional_exps_mark_used(rel, n->data);
+                               rel_exps_mark_used(sql->sa, rel, n->data);
+                               rel_mark_used(sql, n->data, 0);
+                       }
+               }
                break;
        case op_join:
        case op_left:
@@ -717,6 +739,7 @@ rel_remove_unused(mvc *sql, sql_rel *rel
        case op_union:
        case op_inter:
        case op_except:
+       case op_munion:
 
        case op_insert:
        case op_update:
@@ -733,9 +756,6 @@ rel_remove_unused(mvc *sql, sql_rel *rel
        case op_semi:
        case op_anti:
                return rel;
-       case op_munion:
-               assert(0);
-               break;
        case op_ddl:
                if (rel->flag == ddl_output || rel->flag == ddl_create_seq || 
rel->flag == ddl_alter_seq || rel->flag == ddl_alter_table || rel->flag == 
ddl_create_table || rel->flag == ddl_create_view) {
                        if (rel->l)
@@ -798,7 +818,9 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis
                        rel_dce_refs(sql, rel->r, refs);
                break;
        case op_munion:
-               assert(0);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next)
+                       rel_dce_refs(sql, n->data, refs);
                break;
        case op_ddl:
 
@@ -878,8 +900,13 @@ rel_dce_down(mvc *sql, sql_rel *rel, int
                return rel;
 
        case op_munion:
-               assert(0);
-               break;
+               if (skip_proj) {
+                       for (node *n = ((list*)rel->l)->h; n; n = n->next)
+                               n->data = rel_dce_down(sql, n->data, 0);
+               }
+               if (!skip_proj)
+                       rel_dce_sub(sql, rel);
+               return rel;
        case op_select:
                if (rel->l)
                        rel->l = rel_dce_down(sql, rel->l, 0);
@@ -975,8 +1002,14 @@ rel_add_projects(mvc *sql, sql_rel *rel)
                }
                return rel;
        case op_munion:
-               assert(0);
-               break;
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next) {
+                       sql_rel* r = n->data;
+                       if (!is_project(r->op) && !need_distinct(rel))
+                               r = rel_project(sql->sa, r, 
rel_projections(sql, r, NULL, 1, 1));
+                       r = rel_add_projects(sql, r);
+               }
+               return rel;
        case op_topn:
        case op_sample:
        case op_project:
diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -3310,11 +3310,9 @@ has_no_selectivity(mvc *sql, sql_rel *re
        case op_union:
        case op_inter:
        case op_except:
+       case op_munion:
        case op_select:
                return false;
-       case op_munion:
-               assert(0);
-               return false;
        }
        return true;
 }
diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -2407,7 +2407,9 @@ rel_join_order_(visitor *v, sql_rel *rel
                rel->r = rel_join_order_(v, rel->r);
                break;
        case op_munion:
-               assert(0);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next)
+                       n->data = rel_join_order_(v, n->data);
                break;
        case op_project:
        case op_select:
diff --git a/sql/server/rel_partition.c b/sql/server/rel_partition.c
--- a/sql/server/rel_partition.c
+++ b/sql/server/rel_partition.c
@@ -78,7 +78,9 @@ find_basetables(mvc *sql, sql_rel *rel, 
                        find_basetables(sql, rel->r, tables);
                break;
        case op_munion:
-               assert(0);
+               assert(rel->l);
+               for (node *n = ((list*)rel->l)->h; n; n = n->next)
+                       find_basetables(sql, n->data, tables);
                break;
        case op_semi:
        case op_anti:
diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c
--- a/sql/server/rel_propagate.c
+++ b/sql/server/rel_propagate.c
@@ -567,7 +567,9 @@ rel_change_base_table(mvc* sql, sql_rel*
                                rel->r = rel_change_base_table(sql, rel->r, 
oldt, newt);
                        break;
                case op_munion:
-                       assert(0);
+                       assert(rel->l);
+                       for (node *n = ((list*)rel->l)->h; n; n = n->next)
+                               n->data = rel_change_base_table(sql, n->data, 
oldt, newt);
                        break;
                case op_groupby:
                case op_project:
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -118,7 +118,6 @@ rel_destroy_(sql_rel *rel)
                break;
        case op_munion:
                for (node *n = ((list*)rel->l)->h; n; n = n->next)
-                       // TODO: should we check for n->data == NULL?
                        rel_destroy(n->data);
                break;
        case op_project:
@@ -467,6 +466,7 @@ rel_first_column(mvc *sql, sql_rel *r)
        return NULL;
 }
 
+/* rel_inplace_* used to convert a rel node into another flavor */
 static void
 rel_inplace_reset_props(sql_rel *rel)
 {
@@ -572,7 +572,7 @@ rel_inplace_munion(sql_rel *rel, list *r
        rel_destroy_(rel);
        rel_inplace_reset_props(rel);
        // TODO: what is the semantics of cardinality? is that right?
-       rel->card = CARD_ATOM;
+       rel->card = CARD_MULTI;
        rel->nrcols = 0;
        if (rels)
                rel->l = rels;
@@ -1190,7 +1190,8 @@ list *
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to