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