Changeset: 180f3e64fd15 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=180f3e64fd15 Modified Files: sql/backends/monet5/rel_bin.c sql/include/sql_relation.h sql/server/rel_distribute.c sql/server/rel_dump.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/rel_partition.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_select.c sql/server/sql_parser.y sql/server/sql_scan.c Branch: graph0 Log Message:
SEMA: unnest operator diffs (truncated from 730 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 @@ -1226,7 +1226,7 @@ exp2bin_args(backend *be, sql_exp *e, li if (e->flag == cmp_or || get_cmp(e) == cmp_filter) { args = exps2bin_args(be, e->l, args); args = exps2bin_args(be, e->r, args); - } else if (e->flag == cmp_in || e->flag == cmp_notin) { + } else if (e->flag == cmp_in || e->flag == cmp_notin || e->flag == cmp_unnest) { args = exp2bin_args(be, e->l, args); args = exps2bin_args(be, e->r, args); } else { @@ -1319,6 +1319,7 @@ rel2bin_args(backend *be, sql_rel *rel, case op_select: case op_topn: case op_sample: + case op_unnest: if (rel->exps) args = exps2bin_args(be, rel->exps, args); args = rel2bin_args(be, rel->l, args); @@ -4771,6 +4772,9 @@ subrel_bin(backend *be, sql_rel *rel, li s = rel2bin_sample(be, rel, refs); sql->type = Q_TABLE; break; + case op_unnest: + assert("Not handled yet"); + break; case op_insert: s = rel2bin_insert(be, rel, refs); if (sql->type == Q_TABLE) @@ -4995,6 +4999,7 @@ rel_deps(sql_allocator *sa, sql_rel *r, case op_groupby: case op_topn: case op_sample: + case op_unnest: if (rel_deps(sa, r->l, refs, l) != 0) return -1; break; 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 @@ -60,7 +60,7 @@ typedef struct expression { #define APPLY_NOTEXISTS 64 /* ASCENDING > 15 else we have problems with cmp types */ -#define ASCENDING 16 +#define ASCENDING 32 #define CMPMASK (ASCENDING-1) #define get_cmp(e) (e->flag&CMPMASK) #define ANTISEL 32 @@ -200,8 +200,10 @@ typedef enum operator_type { (op == op_join || is_outerjoin(op)) #define is_semi(op) \ (op == op_semi || op == op_anti) +#define is_unnest(op) \ + (op == op_unnest) #define is_joinop(op) \ - (is_join(op) || is_semi(op)) + (is_join(op) || is_semi(op) || is_unnest(op)) #define is_apply(op) \ (op == op_apply) #define is_select(op) \ @@ -227,6 +229,7 @@ typedef enum operator_type { #define is_sample(op) \ (op == op_sample) + /* NO NIL semantics of aggr operations */ #define need_no_nil(e) \ ((e->flag&NO_NIL)==NO_NIL) 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 @@ -52,6 +52,7 @@ has_remote_or_replica( sql_rel *rel ) case op_groupby: case op_topn: case op_sample: + case op_unnest: if (has_remote_or_replica( rel->l )) return 1; break; @@ -163,6 +164,7 @@ replica(mvc *sql, sql_rel *rel, char *ur case op_groupby: case op_topn: case op_sample: + case op_unnest: rel->l = replica(sql, rel->l, uri); break; case op_ddl: @@ -252,6 +254,7 @@ distribute(mvc *sql, sql_rel *rel) case op_groupby: case op_topn: case op_sample: + case op_unnest: rel->l = distribute(sql, rel->l); l = rel->l; if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) { @@ -304,6 +307,7 @@ rel_remote_func(mvc *sql, sql_rel *rel) case op_groupby: case op_topn: case op_sample: + case op_unnest: rel->l = rel_remote_func(sql, rel->l); break; case op_ddl: 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 @@ -183,6 +183,10 @@ exp_print(mvc *sql, stream *fout, sql_ex mnstr_printf(fout, " !"); mnstr_printf(fout, " FILTER %s ", f->func->base.name); exps_print(sql, fout, e->r, depth, alias, 1); + } else if (get_cmp(e) == cmp_unnest){ + exp_print(sql, fout, e->l, depth, 0, alias); + mnstr_printf(fout, " => "); + exps_print(sql, fout, e->r, depth, alias, 1); } else if (e->f) { exp_print(sql, fout, e->r, depth+1, 0, 0); if (is_anti(e)) @@ -472,6 +476,25 @@ rel_print_(mvc *sql, stream *fout, sql_ if (rel->r && rel->op == op_project) /* order by columns */ exps_print(sql, fout, rel->r, depth, 1, 0); break; + case op_unnest: { + print_indent(sql, fout, depth, decorate); + mnstr_printf(fout, "unnest ("); + + // lhs + if (rel_is_ref(rel->l)) { + int nr = find_ref(refs, rel->l); + print_indent(sql, fout, depth+1, decorate); + mnstr_printf(fout, "& REF %d ", nr); + } else + rel_print_(sql, fout, rel->l, depth+1, refs, decorate); + mnstr_printf(fout, ","); + + // rhs + exps_print(sql, fout, rel->exps, depth, 1, 0); + + mnstr_printf(fout, ")"); + break; + } case op_insert: case op_update: case op_delete: { @@ -555,6 +578,7 @@ rel_print_refs(mvc *sql, stream* fout, s case op_groupby: case op_topn: case op_sample: + case op_unnest: rel_print_refs(sql, fout, rel->l, depth, refs, decorate); if (rel->l && rel_is_ref(rel->l) && !find_ref(refs, rel->l)) { rel_print_(sql, fout, rel->l, depth, refs, decorate); 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 @@ -12,6 +12,7 @@ #include "rel_prop.h" /* for prop_copy() */ #include "rel_optimizer.h" #include "rel_distribute.h" +#include "rel_rel.h" #ifdef HAVE_HGE #include "mal.h" /* for have_hge */ #endif @@ -106,6 +107,17 @@ exp_compare(sql_allocator *sa, sql_exp * return e; } + +sql_exp* +exp_unnest(sql_allocator* sa, sql_exp* column, list* attributes){ + sql_exp *e = exp_create(sa, e_cmp); + e->card = CARD_MULTI; + e->l = column; + e->r = attributes; + e->flag = cmp_unnest; + return e; +} + sql_exp * exp_compare2(sql_allocator *sa, sql_exp *l, sql_exp *r, sql_exp *h, int cmptype) { @@ -1188,11 +1200,14 @@ rel_find_exp_( sql_rel *rel, sql_exp *e) return NULL; switch(e->type) { case e_column: - if (rel->exps && (is_project(rel->op) || is_base(rel->op))) { + if (rel->exps && (is_project(rel->op) || is_base(rel->op) || is_unnest(rel->op))) { + list* exps = rel->exps; + if (is_unnest(rel->op)) + exps = rel_unnest_attributes(rel); if (e->l) { - ne = exps_bind_column2(rel->exps, e->l, e->r); + ne = exps_bind_column2(exps, e->l, e->r); } else { - ne = exps_bind_column(rel->exps, e->r, NULL); + ne = exps_bind_column(exps, e->r, NULL); } } return ne; diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -28,6 +28,7 @@ extern sql_exp *exp_compare2(sql_allocat extern sql_exp *exp_filter(sql_allocator *sa, list *l, list *r, sql_subfunc *f, int anti); extern sql_exp *exp_or(sql_allocator *sa, list *l, list *r); extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype); +extern sql_exp* exp_unnest(sql_allocator* sa, sql_exp* column, list* attributes); #define exp_fromtype(e) ((list*)e->r)->h->data #define exp_totype(e) ((list*)e->r)->h->next->data diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -117,6 +117,7 @@ name_find_column( sql_rel *rel, char *rn case op_select: case op_topn: case op_sample: + case op_unnest: return name_find_column( rel->l, rname, name, pnr, bt); case op_union: case op_inter: @@ -243,6 +244,7 @@ rel_properties(mvc *sql, global_props *g break; case op_project: case op_select: + case op_unnest: case op_groupby: case op_topn: case op_sample: @@ -283,6 +285,7 @@ rel_properties(mvc *sql, global_props *g case op_topn: case op_sample: case op_select: + case op_unnest: break; case op_insert: @@ -1080,7 +1083,8 @@ rel_join_order(mvc *sql, sql_rel *rel) case op_select: case op_groupby: case op_topn: - case op_sample: + case op_sample: + case op_unnest: rel->l = rel_join_order(sql, rel->l); break; case op_ddl: @@ -5581,6 +5585,9 @@ exp_mark_used(sql_rel *subrel, sql_exp * l = e->r; for (n = l->h; n != NULL; n = n->next) nr += exp_mark_used(subrel, n->data); + } else if (e->flag == cmp_unnest) { + nr += exp_mark_used(subrel, e->l); + // do not mark the attributes here } else if (e->flag == cmp_in || e->flag == cmp_notin) { list *r = e->r; node *n; @@ -5775,6 +5782,7 @@ rel_mark_used(mvc *sql, sql_rel *rel, in break; case op_select: + case op_unnest: if (rel->l) { exps_mark_used(sql->sa, rel, rel->l); rel_mark_used(sql, rel->l, 0); @@ -5912,7 +5920,27 @@ rel_remove_unused(mvc *sql, sql_rel *rel rel->exps = exps; } return rel; - + case op_unnest: { // similar to above + list* attributes = rel_unnest_attributes(rel); + bool needed = false; + + for(node* n = attributes->h; n && !needed; n = n->next){ + needed = !((sql_exp*) n->data)->used; + } + + if(needed){ + list* new_attributes = new_exp_list(sql->sa); + for(node* n = attributes->h; n; n = n->next){ + sql_exp *e = n->data; + + if (e->used) + append(new_attributes, e); + } + + ((sql_exp*)rel->exps->h->data)->r = new_attributes; + } + return rel; + } break; case op_union: case op_inter: case op_except: @@ -5980,7 +6008,7 @@ rel_dce_refs(mvc *sql, sql_rel *rel) case op_project: case op_groupby: case op_select: - _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list