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 -- [email protected]
To unsubscribe send an email to [email protected]