Changeset: fd5a3cab2c5b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fd5a3cab2c5b
Modified Files:
        monetdb5/modules/kernel/algebra.mal
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/server/rel_select.c
        
sql/test/BugTracker-2010/Tests/ORDER_BY_over_UNION_EXCEPT_INTERSECT.Bug-2606.stable.out
Branch: default
Log Message:

cleanup except/intersect implementations. removed use of
stmt_union/stmt_diff.


diffs (truncated from 708 to 300 lines):

diff --git a/monetdb5/modules/kernel/algebra.mal 
b/monetdb5/modules/kernel/algebra.mal
--- a/monetdb5/modules/kernel/algebra.mal
+++ b/monetdb5/modules/kernel/algebra.mal
@@ -72,20 +72,20 @@ comment "Produces a new BAT with groups 
 #command join( left:bat[:any_1,:any_2], right:bat[:any_2,:any_3], 
estimate:lng) :bat[:any_1,:any_3]
 #address ALGjoinestimate;
 
+command join(l:bat[:any_1,:any_2], rl:bat[:any_3,:any_2], 
rh:bat[:any_3,:any_2], li:bit, hi:bit) :bat[:any_1,:any_3]
+address ALGrangejoin;
+
 command leftjoin( left:bat[:any_1,:any_2], right:bat[:any_2,:any_3]) 
:bat[:any_1,:any_3]
 address ALGleftjoin;
 command leftjoin( left:bat[:any_1,:any_2], right:bat[:any_2,:any_3], 
estimate:lng) :bat[:any_1,:any_3]
 address ALGleftjoinestimate;
 
+#END OF HEADLESS PLANS
+
 command leftfetchjoin ( left:bat[:oid,:oid], right:bat[:oid,:any_3] ) 
:bat[:oid,:any_3]
 address ALGleftfetchjoin
 comment "Hook directly into the left fetch join implementation.";
 
-command join(l:bat[:any_1,:any_2], rl:bat[:any_3,:any_2], 
rh:bat[:any_3,:any_2], li:bit, hi:bit) :bat[:any_1,:any_3]
-address ALGrangejoin;
-
-#END OF HEADLESS PLANS
-
 command revert( b:bat[:oid,:any_1]) :bat[:oid,:any_1]
 address ALGrevert
 comment "Returns a BAT copy with buns in reverse order";
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
@@ -753,7 +753,6 @@ exp_bin(mvc *sql, sql_exp *e, stmt *left
 
 static stmt *check_types(mvc *sql, sql_subtype *ct, stmt *s, check_type tpe);
 
-/* TODO pass optional selection */
 static stmt *
 stmt_col( mvc *sql, sql_column *c, stmt *del) 
 { 
@@ -1470,7 +1469,7 @@ releqjoin( mvc *sql, list *l1, list *l2,
 
                if (cmp_op == cmp_equal)
                        f = sql_bind_func(sql->sa, sql->session->schema, "=", 
tail_type(le), tail_type(le), F_FUNC);
-               else    /* cmp_equal_nil ? */
+               else    /* TODO cmp_equal_nil */
                        f = sql_bind_func(sql->sa, sql->session->schema, "=", 
tail_type(le), tail_type(le), F_FUNC);
                assert(f);
 
@@ -1878,6 +1877,29 @@ rel2bin_distinct(mvc *sql, stmt *s, stmt
 }
 
 static stmt *
+rel_rename(mvc *sql, sql_rel *rel, stmt *sub)
+{
+       if (rel->exps) {
+               node *en, *n;
+               list *l = sa_list(sql->sa);
+
+               for( en = rel->exps->h, n = sub->op4.lval->h; en && n; en = 
en->next, n = n->next ) {
+                       sql_exp *exp = en->data;
+                       stmt *s = n->data;
+
+                       if (!s) {
+                               assert(0);
+                               return NULL;
+                       }
+                       s = stmt_rename(sql, rel, exp, s);
+                       list_append(l, s);
+               }
+               sub = stmt_list(sql->sa, l);
+       }
+       return sub;
+}
+
+static stmt *
 rel2bin_union( mvc *sql, sql_rel *rel, list *refs)
 {
        list *l; 
@@ -1901,45 +1923,18 @@ rel2bin_union( mvc *sql, sql_rel *rel, l
                char *nme = column_name(sql->sa, c1);
                stmt *s;
 
-               /* append isn't save, ie use union 
-                       (also not save loses unique head oids) 
-
-                  so we create append on copies.
-                       TODO: mark columns non base columns, ie were no
-                       copy is needed
-               */
                s = stmt_append(sql->sa, Column(sql->sa, c1), c2);
                s = stmt_alias(sql->sa, s, rnme, nme);
                list_append(l, s);
        }
        sub = stmt_list(sql->sa, l);
 
-       /* union exp list is a rename only */
-       if (rel->exps) {
-               node *en, *n;
-               list *l = sa_list(sql->sa);
-
-               for( en = rel->exps->h, n = sub->op4.lval->h; en && n; en = 
en->next, n = n->next ) {
-                       sql_exp *exp = en->data;
-                       stmt *s = n->data;
-
-                       if (!s) {
-                               assert(0);
-                               return NULL;
-                       }
-                       s = stmt_rename(sql, rel, exp, s);
-                       list_append(l, s);
-               }
-               sub = stmt_list(sql->sa, l);
-       }
-
+       sub = rel_rename(sql, rel, sub);
        if (need_distinct(rel)) 
                sub = rel2bin_distinct(sql, sub, NULL);
        return sub;
 }
 
-/* Both EXCEPT and INTERSECT need work, current versions aren't mergetable 
save 
- * (bails out on the gen_group) */
 static stmt *
 rel2bin_except( mvc *sql, sql_rel *rel, list *refs)
 {
@@ -1947,12 +1942,13 @@ rel2bin_except( mvc *sql, sql_rel *rel, 
        list *stmts; 
        node *n, *m;
        stmt *left = NULL, *right = NULL, *sub;
+       sql_subfunc *min;
 
        stmt *lg = NULL, *rg = NULL;
        stmt *lgrp = NULL, *rgrp = NULL;
-       stmt *lext = NULL, *rext = NULL;
-       stmt *lcnt = NULL, *rcnt = NULL;
-       stmt *s, *lm, *rm, *ecnt = NULL;
+       stmt *lext = NULL, *rext = NULL, *next = NULL;
+       stmt *lcnt = NULL, *rcnt = NULL, *ncnt = NULL, *zero = NULL;
+       stmt *s, *lm, *rm;
        list *lje = sa_list(sql->sa);
        list *rje = sa_list(sql->sa);
 
@@ -1963,18 +1959,13 @@ rel2bin_except( mvc *sql, sql_rel *rel, 
        if (!left || !right) 
                return NULL;    
        left = row2cols(sql, left);
-
-       /* construct relation */
-       stmts = sa_list(sql->sa);
+       right = row2cols(sql, right);
+
        /*
-        * The multi column intersect is handled using group by's and
+        * The multi column except is handled using group by's and
         * group size counts on both sides of the intersect. We then
-        * return for each group of A with min(A.count,B.count), 
+        * return for each group of L with min(L.count,R.count), 
         * number of rows.
-        * 
-        * The problem with this approach is that the groups should
-        * have equal group identifiers. So we take the union of all
-        * columns before the group by.
         */
        for (n = left->op4.lval->h; n; n = n->next) {
                lg = stmt_group(sql->sa, column(sql->sa, n->data), lgrp, lext, 
lcnt);
@@ -1994,10 +1985,12 @@ rel2bin_except( mvc *sql, sql_rel *rel, 
        stmt_group_done(lg);
        stmt_group_done(rg);
 
+       if (need_distinct(rel)) {
+               lcnt = stmt_const(sql->sa, lcnt, stmt_atom_wrd(sql->sa, 1));
+               rcnt = stmt_const(sql->sa, rcnt, stmt_atom_wrd(sql->sa, 1));
+       }
+
        /* now find the matching groups */
-
-       /* TODO change to left outer join semantics to keep those in A not in B 
*/
-       /* would need outerjoin eqjoin and outer project code, cleans up 
following mess */
        for (n = left->op4.lval->h, m = right->op4.lval->h; n && m; n = 
n->next, m = m->next) {
                stmt *l = column(sql->sa, n->data);
                stmt *r = column(sql->sa, m->data);
@@ -2011,33 +2004,32 @@ rel2bin_except( mvc *sql, sql_rel *rel, 
        lm = stmt_result(sql->sa, s, 0);
        rm = stmt_result(sql->sa, s, 1);
 
-       /* the join of the groups removed those in A but not in B,
-        * we need these later so keep these in 'ecnt' */
-       ecnt = stmt_diff(sql->sa, lcnt, stmt_reverse(sql->sa, lm));
-               
-       /*if (!distinct) */
-       {
-               stmt *glcnt, *grcnt, *o;
-               sql_subfunc *sub;
-
-               /* nil + count -> ? */
-               glcnt = stmt_project(sql->sa, lm, lcnt);
-               grcnt = stmt_project(sql->sa, rm, rcnt);
-
-               sub = sql_bind_func(sql->sa, sql->session->schema, "sql_sub", 
wrd, wrd, F_FUNC);
-               s = stmt_binop(sql->sa, glcnt, grcnt, sub); /* use count */
-
-               /* now we need to add the groups which weren't in B */
-               lcnt = stmt_reorder_project(sql->sa, stmt_reverse(sql->sa, lm), 
s);
-               s = stmt_union(sql->sa, ecnt, lcnt);
-               o = stmt_mark_tail(sql->sa, lext, 0);
-               s = stmt_reorder_project(sql->sa, stmt_reverse(sql->sa, o), s);
-
-               /* now we have gid,cnt, blowup to full groupsizes */
-               s = stmt_gen_group(sql->sa, lext, s);
-       }
+       s = stmt_mirror(sql->sa, lext);
+       s = stmt_tdiff(sql->sa, s, lm);
+
+       /* first we find those missing in R */
+       next = stmt_project(sql->sa, s, lext);
+       ncnt = stmt_project(sql->sa, s, lcnt);
+       zero = stmt_const(sql->sa, s, stmt_atom_wrd(sql->sa, 0));
+
+       /* ext, lcount, rcount */
+       lext = stmt_project(sql->sa, lm, lext);
+       lcnt = stmt_project(sql->sa, lm, lcnt);
+       rcnt = stmt_project(sql->sa, rm, rcnt);
+
+       /* append those missing in L */
+       lext = stmt_append(sql->sa, lext, next);
+       lcnt = stmt_append(sql->sa, lcnt, ncnt);
+       rcnt = stmt_append(sql->sa, rcnt, zero);
+
+       min = sql_bind_func(sql->sa, sql->session->schema, "sql_sub", wrd, wrd, 
F_FUNC);
+       s = stmt_binop(sql->sa, lcnt, rcnt, min); /* use count */
+
+       /* now we have gid,cnt, blowup to full groupsizes */
+       s = stmt_gen_group(sql->sa, lext, s);
 
        /* project columns of left hand expression */
+       stmts = sa_list(sql->sa);
        for (n = left->op4.lval->h; n; n = n->next) {
                stmt *c1 = column(sql->sa, n->data);
                char *rnme = NULL;
@@ -2051,30 +2043,7 @@ rel2bin_except( mvc *sql, sql_rel *rel, 
                list_append(stmts, c1);
        }
        sub = stmt_list(sql->sa, stmts);
-
-       /* TODO put in sep function !!!, and add to all is_project(op) */
-       /* except can be a projection too */
-       if (rel->exps) {
-               node *en;
-               list *l = sa_list(sql->sa);
-
-               for( en = rel->exps->h; en; en = en->next ) {
-                       sql_exp *exp = en->data;
-                       stmt *s = exp_bin(sql, exp, sub, NULL, NULL, NULL, 
NULL, NULL);
-
-                       if (!s) {
-                               assert(0);
-                               return NULL;
-                       }
-                       s = stmt_rename(sql, rel, exp, s);
-                       list_append(l, s);
-               }
-               sub = stmt_list(sql->sa, l);
-       }
-
-       if (need_distinct(rel))
-               sub = rel2bin_distinct(sql, sub, NULL);
-       return sub;
+       return rel_rename(sql, rel, sub);
 }
 
 static stmt *
@@ -2084,6 +2053,7 @@ rel2bin_inter( mvc *sql, sql_rel *rel, l
        list *stmts; 
        node *n, *m;
        stmt *left = NULL, *right = NULL, *sub;
+       sql_subfunc *min;
 
        stmt *lg = NULL, *rg = NULL;
        stmt *lgrp = NULL, *rgrp = NULL;
@@ -2101,17 +2071,11 @@ rel2bin_inter( mvc *sql, sql_rel *rel, l
                return NULL;    
        left = row2cols(sql, left);
 
-       /* construct relation */
-       stmts = sa_list(sql->sa);
        /*
         * The multi column intersect is handled using group by's and
         * group size counts on both sides of the intersect. We then
-        * return for each group of A with min(A.count,B.count), 
+        * return for each group of L with min(L.count,R.count), 
         * number of rows.
-        * 
-        * The problem with this approach is that the groups should
-        * have equal group identifiers. So we take the union of all
-        * columns before the group by.
         */
        for (n = left->op4.lval->h; n; n = n->next) {
                lg = stmt_group(sql->sa, column(sql->sa, n->data), lgrp, lext, 
lcnt);
@@ -2131,6 +2095,11 @@ rel2bin_inter( mvc *sql, sql_rel *rel, l
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to