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

Reply via email to