Changeset: 98ab85dad2b6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/98ab85dad2b6 Modified Files: sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_select.c Branch: balanced_union Log Message:
Implements setquery for n-ary set op multi-union WIP diffs (200 lines): 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 @@ -757,6 +757,117 @@ rel_setop_set_exps(mvc *sql, sql_rel *re } sql_rel * +rel_setop_n_ary(sql_allocator *sa, list *rels, operator_type setop) +{ + // TODO: for now we support only n-ary union + assert(setop == op_munion); + + if (!rels) + return NULL; + + sql_rel *rel = rel_create(sa); + if(!rel) + return NULL; + + rel->l = rels; + rel->r = NULL; + rel->op = setop; + rel->exps = NULL; + rel->card = CARD_MULTI; + // TODO: properly introduce the assertion over rels elements + /*assert(l->nrcols == r->nrcols);*/ + rel->nrcols = ((sql_rel*)rels->h->data)->nrcols; + return rel; +} + +sql_rel * +rel_setop_n_ary_check_types(mvc *sql, sql_rel *l, sql_rel *r, list *ls, list *rs, operator_type op) +{ + // TODO: for now we support only 2 relation in the list at ->l of + // the n-ary operator. In the future this function should be variadic (?) + // TODO: for now we support only n-ary union + assert(op == op_munion); + + /* NOTE: this is copied logic from rel_setop_check_types. A DRY-er approach + * would be to call rel_setop_check_types which will return a binary + * setop from which we could extract ->l and ->r and add them in a list + * for the op_munion. This is kind of ugly though... + */ + list *nls = new_exp_list(sql->sa); + list *nrs = new_exp_list(sql->sa); + node *n, *m; + list* rels; + + if(!nls || !nrs) + return NULL; + + for (n = ls->h, m = rs->h; n && m; n = n->next, m = m->next) { + sql_exp *le = n->data; + sql_exp *re = m->data; + + if (rel_convert_types(sql, l, r, &le, &re, 1, type_set) < 0) + return NULL; + append(nls, le); + append(nrs, re); + } + l = rel_project(sql->sa, l, nls); + r = rel_project(sql->sa, r, nrs); + set_processed(l); + set_processed(r); + + /* create a list with only 2 sql_rel entries for the n-ary set op */ + rels = sa_list(sql->sa); + append(rels, l); + append(rels, r); + + return rel_setop_n_ary(sql->sa, rels, op); +} + +void +rel_setop_n_ary_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props) +{ + list *rexps; + sql_rel *r; + + /* set the exps properties first */ + for (node *m = exps->h; m; m = m->next) { + /* the nil/no_nil property will be set in the next loop where + * we go through the exps of every rel of the rels. For now no_nil + */ + sql_exp *e = (sql_exp*)m->data; + set_has_no_nil(e); + /* remove all the properties on unions on the general case */ + if (!keep_props) { + e->p = NULL; + set_not_unique(e); + } + } + + /* for every relation in the list of relations */ + for (node *n = ((list*)rel->l)->h; n; n = n->next) { + r = n->data; + rexps = r->exps; + + if (!is_project(r->op)) + rexps = rel_projections(sql, r, NULL, 0, 1); + + /* go through the relation's exps */ + for (node *m = exps->h, *o = rexps->h; m && o; m = m->next, n = n->next) { + sql_exp *e = m->data, *f = o->data; + /* for multi-union if any operand has nil then set the nil prop for the op exp */ + if (is_munion(rel->op) && has_nil(f)) + set_has_nil(e); + e->card = CARD_MULTI; + } + } + + rel->exps = exps; + // TODO: probably setting nrcols is redundant as we have allready done + // that when we create the setop_n_ary. check rel_setop_n_ary() + rel->nrcols = ((sql_rel*)((list*)rel->l)->h->data)->nrcols; +} + +sql_rel * rel_crossproduct(sql_allocator *sa, sql_rel *l, sql_rel *r, operator_type join) { sql_rel *rel = rel_create(sa); diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h --- a/sql/server/rel_rel.h +++ b/sql/server/rel_rel.h @@ -87,6 +87,9 @@ extern int rel_convert_types(mvc *sql, s extern sql_rel *rel_setop(sql_allocator *sa, sql_rel *l, sql_rel *r, operator_type setop); extern sql_rel *rel_setop_check_types(mvc *sql, sql_rel *l, sql_rel *r, list *ls, list *rs, operator_type op); extern void rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props); +extern sql_rel *rel_setop_n_ary(sql_allocator *sa, list *rels, operator_type setop); +extern sql_rel *rel_setop_n_ary_check_types(mvc *sql, sql_rel *l, sql_rel *r, list *ls, list *rs, operator_type op); +extern void rel_setop_n_ary_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props); extern sql_rel *rel_crossproduct(sql_allocator *sa, sql_rel *l, sql_rel *r, operator_type join); /* in case e is an constant and rel is a simple project of only e, free rel */ diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -6103,6 +6103,7 @@ rel_query(sql_query *query, symbol *sq, return rel; } +/* NOTE: does NOT "set" query but instead generate set ops (union, except, intersect) */ static sql_rel * rel_setquery_(sql_query *query, sql_rel *l, sql_rel *r, dlist *cols, int op ) { @@ -6127,6 +6128,46 @@ rel_setquery_(sql_query *query, sql_rel return rel; } +/* Generate n-ary set operator */ +static sql_rel * +rel_setquery_n_ary_(sql_query *query, sql_rel *l, sql_rel *r, dlist *cols, int op) +{ + /* even though this is for a general n-ary operators in this phase of the query + * processing we gonna have only two operands (so technically it's binary). In + * general this op supports arbitrary number of operands. + */ + // TODO: for now we support only multi-union + assert(op == op_munion); + + mvc *sql = query->sql; + sql_rel *rel; + + if (!cols) { + // TODO: make rel_setop_n_ary_check_types to accept a list of rels + // and a list of lists of exps + list *ls, *rs; + + l = rel_unique_names(sql, l); + r = rel_unique_names(sql, r); + ls = rel_projections(sql, l, NULL, 0, 1); + rs = rel_projections(sql, r, NULL, 0, 1); + rel = rel_setop_n_ary_check_types(sql, l, r, ls, rs, (operator_type)op); + } else { + list *rels = sa_list(sql->sa); + append(rels, l); + append(rels, r); + rel = rel_setop_n_ary(sql->sa, rels, (operator_type)op); + } + + if (rel) { + rel_setop_n_ary_set_exps(sql, rel, rel_projections(sql, rel, NULL, 0, 1), false); + set_processed(rel); + } + + return rel; + +} + static sql_rel * rel_setquery(sql_query *query, symbol *q) { @@ -6168,6 +6209,7 @@ rel_setquery(sql_query *query, symbol *q if (t2 && distinct) t2 = rel_distinct(t2); res = rel_setquery_(query, t1, t2, corresponding, op_union ); + /*res = rel_setquery_n_ary_(query, t1, t2, corresponding, op_munion);*/ } else if ( q->token == SQL_EXCEPT) res = rel_setquery_(query, t1, t2, corresponding, op_except ); else if ( q->token == SQL_INTERSECT) _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org