Update of /cvsroot/monetdb/sql/src/server
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv32749/src/server

Modified Files:
        bin_optimizer.mx rel_bin.mx rel_select.mx sql_optimize.mx 
        sql_rel2bin.mx sql_select.mx sql_statement.mx sql_updates.mx 
Log Message:
propagated changes of Tuesday Jun 17 2008
from the SQL_2-24 branch to the development trunk

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - nielsnes: src/test/bugs/Tests/All,1.112.2.6
        src/test/bugs/Tests/reljoin_join2_bug.sql,1.1.2.1
        src/test/bugs/Tests/reljoin_join2_bug.stable.err,1.1.2.1
        src/test/bugs/Tests/reljoin_join2_bug.stable.out,1.1.2.1
add for bug in handling combinations of joins with different expressions and
transformation into of joins into filters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - nielsnes: src/backends/monet4/sql_gencode.mx,1.174.2.3
        src/backends/monet5/sql_gencode.mx,1.275.2.3
        src/server/bin_optimizer.mx,1.11.2.1 src/server/rel_bin.mx,1.42.2.3
        src/server/sql_optimize.mx,1.92.2.1 src/server/sql_rel2bin.mx,1.120.2.1
        src/server/sql_select.mx,1.231.2.7
        src/server/sql_statement.mx,1.165.2.2
        src/server/sql_updates.mx,1.138.2.2
fixed bug in handling combinations of joins where some joins needed to be
changed into filters (selects/semijoins).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - sjoerd: NT/MonetDB4-SQL/MonetDB4-SQL-Installer.vdproj,1.11.2.5
        NT/MonetDB5-SQL/MonetDB5-SQL-Installer.vdproj,1.19.2.5
Updated version number.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - nielsnes: src/server/rel_select.mx,1.75.2.2
fixed bug in recusive views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - sjoerd: NT/MonetDB4-SQL64/MonetDB4-SQL-Installer.vdproj,1.6.2.6
        NT/MonetDB5-SQL64/MonetDB5-SQL-Installer.vdproj,1.9.2.5
Updated version numbers.
Removed JDBC jars.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008/06/17 - nielsnes: src/test/BugTracker/Tests/All,1.93.2.12
        src/test/BugTracker/Tests/copy_into_crash.SF-1993999.sql,1.1.2.1
        src/test/BugTracker/Tests/copy_into_crash.SF-1993999.stable.err,1.1.2.1
        src/test/BugTracker/Tests/copy_into_crash.SF-1993999.stable.out,1.1.2.1
added test for (non existing) bug
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Index: sql_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_select.mx,v
retrieving revision 1.235
retrieving revision 1.236
diff -u -d -r1.235 -r1.236
--- sql_select.mx       16 Jun 2008 09:23:26 -0000      1.235
+++ sql_select.mx       17 Jun 2008 10:35:11 -0000      1.236
@@ -1927,7 +1927,7 @@
                dnode *n = js->data.lval->h;
 
                matching_columns = list_create(NULL);
-               s = stmt_reljoin_init();
+               s = stmt_releqjoin_init();
                for (; n; n = n->next) {
                        char *nm = n->data.sval;
 
@@ -1954,7 +1954,7 @@
                        }
                        list_append(matching_columns, lc);
                        list_append(matching_columns, rc);
-                       stmt_reljoin_fill(s, ls, rs);
+                       stmt_releqjoin_fill(s, ls, rs);
                }
        } else {                /* ! js -> natural join */
                node *m;
@@ -1967,7 +1967,7 @@
                        return sql_error(sql, 02, "JOIN: no columns of tables 
'%s' and '%s' match", tv1->tname, tv2->tname);
                }
 
-               s = stmt_reljoin_init();
+               s = stmt_releqjoin_init();
                for (m = matching_columns->h; m; m = m->next->next) {
                        cvar *lc = m->data;
                        cvar *rc = m->next->data;
@@ -1987,7 +1987,7 @@
                                list_destroy(matching_columns);
                                return NULL;
                        }
-                       stmt_reljoin_fill(s, ls, rs);
+                       stmt_releqjoin_fill(s, ls, rs);
                }
        }
 
@@ -2269,7 +2269,7 @@
                rs = stmt_aggr(stmt_dup(rgrp->grp), grp_dup(rgrp), a, 1); 
 
                /* now find the matching groups */
-               s = stmt_reljoin_init();
+               s = stmt_releqjoin_init();
                for (n = tv1->columns->h, m = tv2->columns->h; n && m; n = 
n->next, m = m->next) {
                        cvar *lc = n->data;
                        cvar *rc = m->data;
@@ -2290,7 +2290,7 @@
                        }
                        l = stmt_join(stmt_dup(lgrp->ext), l, cmp_equal);
                        r = stmt_join(stmt_dup(rgrp->ext), r, cmp_equal);
-                       stmt_reljoin_fill(s, l, r);
+                       stmt_releqjoin_fill(s, l, r);
                }
                
                /* the join of the groups removed those in A but not in B,
@@ -2379,7 +2379,7 @@
                rs = stmt_aggr(stmt_dup(rgrp->grp), grp_dup(rgrp), a, 1); 
 
                /* now find the matching groups */
-               s = stmt_reljoin_init();
+               s = stmt_releqjoin_init();
                for (n = tv1->columns->h, m = tv2->columns->h; n && m; n = 
n->next, m = m->next) {
                        cvar *lc = n->data;
                        cvar *rc = m->data;
@@ -2400,7 +2400,7 @@
                        }
                        l = stmt_join(stmt_dup(lgrp->ext), l, cmp_equal);
                        r = stmt_join(stmt_dup(rgrp->ext), r, cmp_equal);
-                       stmt_reljoin_fill(s, l, r);
+                       stmt_releqjoin_fill(s, l, r);
                }
                
                if (!distinct) {

Index: sql_updates.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_updates.mx,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- sql_updates.mx      5 Jun 2008 09:23:25 -0000       1.139
+++ sql_updates.mx      17 Jun 2008 10:35:13 -0000      1.140
@@ -116,12 +116,12 @@
                                stmt_relselect_fill(s, stmt_uselect( 
stmt_bat(c->c, stmt_dup(ts), RDONLY), 
stmt_dup(inserts[c->c->colnr]->op2.stval), cmp_equal));
                        }
                } else {
-                       s = stmt_reljoin_init();
-                       stmt_reljoin_fill(s, stmt_idxbat(k->idx, RDONLY), 
stmt_dup(idx_inserts));
+                       s = stmt_releqjoin_init();
+                       stmt_releqjoin_fill(s, stmt_idxbat(k->idx, RDONLY), 
stmt_dup(idx_inserts));
                        for (m = k->columns->h; m; m = m->next) {
                                sql_kc *c = m->data;
 
-                               stmt_reljoin_fill(s, stmt_bat(c->c, 
stmt_dup(ts), RDONLY), stmt_dup(inserts[c->c->colnr]->op2.stval));
+                               stmt_releqjoin_fill(s, stmt_bat(c->c, 
stmt_dup(ts), RDONLY), stmt_dup(inserts[c->c->colnr]->op2.stval));
                        }
                }
                s = stmt_binop(stmt_aggr(s, NULL, cnt, 1), stmt_atom_int(0), 
ne);
@@ -220,7 +220,7 @@
        if (s->key && s->nrcols == 0) {
                s = stmt_binop(stmt_aggr(stmt_dup(idx_inserts), NULL, cnt, 1), 
stmt_atom_int(1), ne);
        } else {
-               /* reljoin.count <> inserts[col1].count */
+               /* releqjoin.count <> inserts[col1].count */
                stmt *ins = stmt_dup(inserts[0]->op2.stval);
 
                s = stmt_binop(stmt_aggr(stmt_dup(idx_inserts), NULL, cnt, 1), 
stmt_aggr(ins, NULL, sql_dup_aggr(cnt), 1), ne);
@@ -334,12 +334,12 @@
        } else {
                int nulls = 0;
 
-               s = stmt_reljoin_init();
+               s = stmt_releqjoin_init();
                for (m = i->columns->h, o = ri->columns->h; m && o; m = 
m->next, o = o->next) {
                        sql_kc *c = m->data;
                        sql_kc *rc = o->data;
 
-                       stmt_reljoin_fill(s, 
stmt_dup(inserts[c->c->colnr]->op2.stval), stmt_bat(rc->c, stmt_dup(rts), 
RDONLY));
+                       stmt_releqjoin_fill(s, 
stmt_dup(inserts[c->c->colnr]->op2.stval), stmt_bat(rc->c, stmt_dup(rts), 
RDONLY));
                        if (c->c->null)
                                nulls = 1;
                }
@@ -564,8 +564,8 @@
                        This is done using a relation join and a count (which 
                        should be zero)
                */
-               s = stmt_reljoin_init();
-               stmt_reljoin_fill(s, stmt_diff(stmt_idxbat(k->idx, RDONLY), 
stmt_dup(idx_updates)), stmt_dup(idx_updates));
+               s = stmt_releqjoin_init();
+               stmt_releqjoin_fill(s, stmt_diff(stmt_idxbat(k->idx, RDONLY), 
stmt_dup(idx_updates)), stmt_dup(idx_updates));
                for (m = k->columns->h; m; m = m->next) {
                        sql_kc *c = m->data;
                        stmt *upd, *l;
@@ -576,7 +576,7 @@
                                upd = stmt_semijoin(stmt_bat(c->c, 
stmt_dup(ts), RDONLY), stmt_dup(updates[updcol]->op2.stval));
                        }
                        l = stmt_diff(stmt_bat(c->c, stmt_dup(ts), RDONLY), 
stmt_dup(upd));
-                       stmt_reljoin_fill(s, l, upd);
+                       stmt_releqjoin_fill(s, l, upd);
 
                }
                s = stmt_binop(stmt_aggr(s, NULL, cnt, 1), stmt_atom_int(0), 
ne);
@@ -676,7 +676,7 @@
 
        if (!idx_updates)
                return NULL;
-       /* reljoin.count <> updates[updcol].count */
+       /* releqjoin.count <> updates[updcol].count */
        cur = stmt_dup(updates[updcol]->op2.stval);
        s = stmt_binop(stmt_aggr(stmt_dup(idx_updates), NULL, cnt, 1), 
stmt_aggr(cur, NULL, sql_dup_aggr(cnt), 1), ne);
 
@@ -700,7 +700,7 @@
        sql_subfunc *ne = sql_bind_func_result(sql->session->schema, "<>", it, 
it, bt);
 
        fts = stmt_basetable(k->idx->t, k->idx->t->base.name);
-       s = stmt_reljoin_init();
+       s = stmt_releqjoin_init();
 
        rows = stmt_idxbat(k->idx, RDONLY);
        rows = stmt_semijoin(stmt_reverse(rows), 
stmt_dup(updates[updcol]->op2.stval));
@@ -727,7 +727,7 @@
                                null = nn;
                        nulls = 1;
                }
-               stmt_reljoin_fill(s, upd, stmt_semijoin(stmt_dup(
+               stmt_releqjoin_fill(s, upd, stmt_semijoin(stmt_dup(
                  stmt_bat(fc->c, stmt_dup(fts), RDONLY)), stmt_dup(rows) ));
        }
        /* add missing nulls */
@@ -737,7 +737,7 @@
        stmt_destroy(ts);
        stmt_destroy(fts);
 
-       /* reljoin.count <> updates[updcol].count */
+       /* releqjoin.count <> updates[updcol].count */
        s = stmt_binop(stmt_aggr(stmt_dup(s), NULL, cnt, 1), stmt_aggr(rows, 
NULL, sql_dup_aggr(cnt), 1), ne);
 
        /* s should be empty */
@@ -974,7 +974,7 @@
        stmt *null = NULL;
 
        ts = stmt_basetable(i->t, i->t->base.name);
-       s = stmt_reljoin_init();
+       s = stmt_releqjoin_init();
        for (m = i->columns->h, o = ri->columns->h; m && o; m = m->next, o = 
o->next) {
                sql_kc *c = m->data;
                sql_kc *rc = o->data;
@@ -996,7 +996,7 @@
                                null = nn;
                        nulls = 1;
                }
-               stmt_reljoin_fill(s, upd, stmt_dup(stmt_bat(rc->c, 
stmt_dup(rts), RDONLY)));
+               stmt_releqjoin_fill(s, upd, stmt_dup(stmt_bat(rc->c, 
stmt_dup(rts), RDONLY)));
 
        }
        /* add missing nulls */

Index: sql_rel2bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_rel2bin.mx,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- sql_rel2bin.mx      22 May 2008 14:07:52 -0000      1.120
+++ sql_rel2bin.mx      17 Jun 2008 10:35:10 -0000      1.121
@@ -51,14 +51,15 @@
        switch (st->type) {
        case st_join:
        case st_outerjoin:
-       case st_intersect:
        case st_reorder:
                return tail_column(st->op2.stval);
 
        case st_join2:
                return tail_column(st->op2.stval);
-       case st_reljoin:
+       case st_releqjoin:
                return tail_column(st->op2.lval->h->data);
+       case st_reljoin:
+               return tail_column(st->op2.lval->t->data);
 
        case st_filter:
        case st_select:
@@ -148,7 +149,6 @@
        case st_join2:
        case st_outerjoin:
        case st_diff:
-       case st_intersect:
        case st_union:
 
        case st_append:
@@ -170,8 +170,10 @@
                return head_column(st->op1.stval);
 
        case st_relselect:
-       case st_reljoin:
+       case st_releqjoin:
                return head_column(st->op1.lval->h->data);
+       case st_reljoin:
+               return head_column(st->op2.lval->h->data);
 
        case st_table_clear:
        case st_column:
@@ -702,7 +704,7 @@
 
 /* TODO find out if the columns have an (hash) index */
 static stmt *
-reljoin( mvc *sql, list *l1, list *l2 )
+releqjoin( mvc *sql, list *l1, list *l2 )
 {
        node *n1, *n2;
        stmt *l, *r, *res;
@@ -730,6 +732,7 @@
 
                assert(f);
 
+               /* TODO use uselect only */
                cmp = stmt_binop(le, re, f);
 
                cmp = stmt_uselect(cmp, stmt_bool(1), cmp_equal);
@@ -741,6 +744,54 @@
        return res;
 }
 
+static stmt *
+reljoin( mvc *sql, stmt *rj, list *l2 )
+{
+       node *n = l2->h;
+       stmt *l, *r, *res;
+
+       (void)sql;
+       if (!rj && list_length(l2) == 1) 
+               return stmt_dup(l2->h->data);
+
+       if (rj) {
+               l = stmt_mark(stmt_reverse(stmt_dup(rj)), 50);
+               r = stmt_mark(stmt_dup(rj), 50);
+       } else {
+               res = stmt_dup(n->data);
+               l = stmt_mark(stmt_reverse(res), 4);
+               r = stmt_mark(stmt_dup(res), 4);
+               n = n->next;
+       }
+       for (; n; n = n->next) {
+               stmt *j = n->data;
+               stmt *ld = stmt_dup(j->op1.stval);
+               stmt *o2 = stmt_dup(j->op2.stval);
+               stmt *rd = (j->type != st_join2)?stmt_reverse(o2):o2;
+               stmt *le = stmt_join(l, ld, cmp_equal);
+               stmt *re = stmt_join(r, rd, cmp_equal);
+
+               if (j->type == st_join2) {
+                       comp_type c1 = j->flag&2 ? cmp_gte : cmp_gt;
+                       comp_type c2 = j->flag&1 ? cmp_lte : cmp_lt;
+                       stmt *r2 = stmt_join(stmt_dup(r), 
stmt_dup(j->op3.stval), cmp_equal);
+                       stmt *cmp1 = stmt_uselect(le, re, c1);
+                       stmt *cmp2 = stmt_uselect(stmt_dup(le), r2, c2);
+
+                       stmt *cmp = stmt_semijoin(cmp1, cmp2);
+                       l = stmt_semijoin(stmt_dup(l), stmt_dup(cmp));
+                       r = stmt_semijoin(stmt_dup(r), cmp);
+               } else {
+                       stmt *cmp = stmt_uselect(le, re, j->flag);
+
+                       l = stmt_semijoin(stmt_dup(l), stmt_dup(cmp));
+                       r = stmt_semijoin(stmt_dup(r), cmp);
+               }
+       }
+       res = stmt_join(stmt_reverse(l), r, cmp_equal);
+       return res;
+}
+
 int
 find_unique( stmt *s, void *v)
 {
@@ -849,7 +900,7 @@
                s->optimized = 2;
                return stmt_dup(s);
 
-       case st_reljoin:{
+       case st_releqjoin:{
 
                list *l1 = create_stmt_list();
                list *l2 = create_stmt_list();
@@ -860,7 +911,7 @@
                        list_append(l1, rel2bin(c, n1->data));
                        list_append(l2, rel2bin(c, n2->data));
                }
-               res = reljoin(c, l1, l2);
+               res = releqjoin(c, l1, l2);
                list_destroy(l1);
                list_destroy(l2);
                s->optimized = res->optimized = 2;
@@ -871,6 +922,31 @@
                return res;
        }
 
+       case st_reljoin:{
+
+               stmt *rj = NULL;
+               list *l2 = NULL;
+               node *n;
+               stmt *res;
+
+               if (s->op1.stval)
+                       rj = rel2bin(c, s->op1.stval);
+
+               if (s->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = s->op2.lval->h; n; n = n->next) 
+                               list_append(l2, rel2bin(c, n->data));
+               }
+               res = reljoin(c, rj, l2);
+               list_destroy(l2);
+               s->optimized = res->optimized = 2;
+               if (res != s) {
+                       assert(s->rewritten==NULL);
+                       s->rewritten = stmt_dup(res);
+               }
+               return res;
+       }
+
        case st_relselect:{
 
                stmt *res;
@@ -946,7 +1022,6 @@
        case st_temp:
        case st_filter:
        case st_diff:
-       case st_intersect:
        case st_union:
        case st_outerjoin:
        case st_mirror:

Index: sql_statement.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_statement.mx,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -d -r1.166 -r1.167
--- sql_statement.mx    5 Jun 2008 09:23:25 -0000       1.166
+++ sql_statement.mx    17 Jun 2008 10:35:12 -0000      1.167
@@ -83,13 +83,13 @@
        st_semijoin,
        st_relselect,
 
-       st_reljoin,
+       st_releqjoin,
        st_join,
        st_join2,
        st_outerjoin,
        st_diff,
-       st_intersect,
        st_union,
+       st_reljoin,
 
        st_import,
        st_export,
@@ -250,13 +250,14 @@
 extern void stmt_relselect_fill(stmt *relselect, stmt *select);
 extern stmt *stmt_relselect(list *sels);
 
-extern stmt *stmt_reljoin_init(void);
-extern void stmt_reljoin_fill(stmt *reljoin, stmt *lc, stmt *rc);
-extern stmt *stmt_reljoin1(list *joins);
-extern stmt *stmt_reljoin2(list *l1, list *l2);
+extern stmt *stmt_releqjoin_init(void);
+extern void stmt_releqjoin_fill(stmt *releqjoin, stmt *lc, stmt *rc);
+extern stmt *stmt_releqjoin1(list *joins);
+extern stmt *stmt_releqjoin2(list *l1, list *l2);
 extern stmt *stmt_join(stmt *op1, stmt *op2, comp_type cmptype);
 extern stmt *stmt_join2(stmt *l, stmt *ra, stmt *rb, int cmp);
 extern stmt *stmt_outerjoin(stmt *op1, stmt *op2, comp_type cmptype);
+extern stmt *stmt_reljoin(stmt *op1, list *neqjoins);
 
 extern stmt *stmt_diff(stmt *op1, stmt *op2);
 extern stmt *stmt_union(stmt *op1, stmt *op2);
@@ -381,13 +382,13 @@
                ST(semijoin);
                ST(relselect);
 
-               ST(reljoin);
+               ST(releqjoin);
                ST(join);
                ST(join2);
                ST(outerjoin);
                ST(diff);
-               ST(intersect);
                ST(union);
+               ST(reljoin);
 
                ST(import);
                ST(export);
@@ -637,13 +638,18 @@
                case st_connection:
                        list_destroy(s->op1.lval);
                        break;
-               case st_reljoin:
+               case st_releqjoin: 
                        list_destroy(s->op1.lval);
                        list_destroy(s->op2.lval);
                        break;
+               case st_reljoin:
+                       if (s->op1.stval)
+                               stmt_destroy(s->op1.stval);
+                       if (s->op2.lval)
+                               list_destroy(s->op2.lval);
+                       break;
 
                case st_diff:
-               case st_intersect:
                case st_union:
                case st_join:
                case st_join2:
@@ -895,11 +901,18 @@
                        list_deps(dep_list, s->op1.lval, depend_type, dir);
                        break;
 
-               case st_reljoin:
+               case st_releqjoin: 
                        list_deps(dep_list, s->op1.lval, depend_type, dir);
                        list_deps(dep_list, s->op2.lval, depend_type, dir);
                        break;
 
+               case st_reljoin:
+                       if (s->op1.stval)
+                               push(s->op1.stval);
+                       if (s->op2.lval)
+                               list_deps(dep_list, s->op2.lval, depend_type, 
dir);
+                       break;
+
                case st_pivot:
                        if (s->op2.stval)
                                push(s->op2.stval);
@@ -911,7 +924,6 @@
                        break;
                case st_diff:
                case st_alias:
-               case st_intersect:
                case st_union:
                case st_join:
                case st_join2:
@@ -1667,10 +1679,25 @@
 }
 
 stmt *
-stmt_reljoin_init()
+stmt_reljoin( stmt *op1, list *neqjoins )
 {
        stmt *s = stmt_create(st_reljoin);
 
+       s->op1.stval = op1;
+       s->op2.lval = neqjoins;
+       s->nrcols = 2;
+       if (!op1)
+               op1 = neqjoins->h->data;
+       s->h = stmt_dup(op1->h);
+       s->t = stmt_dup(op1->t);
+       return s;
+}
+
+stmt *
+stmt_releqjoin_init()
+{
+       stmt *s = stmt_create(st_releqjoin);
+
        s->op1.lval = list_create((fdestroy) &stmt_destroy);
        s->op2.lval = list_create((fdestroy) &stmt_destroy);
        s->nrcols = 2;
@@ -1678,7 +1705,7 @@
 }
 
 void
-stmt_reljoin_fill(stmt *rj, stmt *lc, stmt *rc)
+stmt_releqjoin_fill(stmt *rj, stmt *lc, stmt *rc)
 {
        list_append(rj->op1.lval, lc);
        list_append(rj->op2.lval, rc);
@@ -1689,9 +1716,9 @@
 }
 
 stmt *
-stmt_reljoin2(list *l1, list *l2)
+stmt_releqjoin2(list *l1, list *l2)
 {
-       stmt *s = stmt_create(st_reljoin);
+       stmt *s = stmt_create(st_releqjoin);
 
        s->op1.lval = l1;
        s->op2.lval = l2;
@@ -1702,7 +1729,7 @@
 }
 
 stmt *
-stmt_reljoin1(list *joins)
+stmt_releqjoin1(list *joins)
 {
        list *l1 = list_create((fdestroy) &stmt_destroy);
        list *l2 = list_create((fdestroy) &stmt_destroy);
@@ -1741,7 +1768,7 @@
        }
        if (L != NULL)
                stmt_destroy(L);
-       return stmt_reljoin2(l1, l2);
+       return stmt_releqjoin2(l1, l2);
 }
 
 stmt *
@@ -2229,10 +2256,15 @@
                /* The tail type of a join2 is the head of the second operant!,
                   ie should be 'oid' */
                return head_type(st->op2.stval);
-       case st_reljoin:
-               /* The tail type of a reljoin is the head of the second list!,
+       case st_releqjoin:
+               /* The tail type of a releqjoin is the head of the second list!,
                   ie should be 'oid' */
                return head_type(st->op2.lval->h->data);
+       case st_reljoin:
+               if (st->op1.stval)
+                       return tail_type(st->op1.stval);
+               else
+                       return tail_type(st->op2.lval->h->data);
 
        case st_diff:
        case st_filter:
@@ -2337,9 +2369,15 @@
        case st_mark:
                return head_type(st->op1.stval);
        case st_relselect:
-       case st_reljoin:
+       case st_releqjoin:
                return head_type(st->op1.lval->h->data);
 
+       case st_reljoin:
+               if (st->op1.stval)
+                       return head_type(st->op1.stval);
+               else
+                       return head_type(st->op2.lval->h->data);
+
        case st_list:
                return head_type(st->op1.lval->h->data);
 
@@ -2504,6 +2542,7 @@
                return _strdup("single_value");
 
        case st_relselect:
+       case st_releqjoin:
        case st_reljoin:
        case st_list:
                if (list_length(st->op1.lval))
@@ -2566,6 +2605,7 @@
        case st_var:
        case st_temp:
        case st_relselect:
+       case st_releqjoin:
        case st_reljoin:
        default:
                return NULL;
@@ -2624,6 +2664,7 @@
        case st_temp:
                return NULL;
        case st_relselect:
+       case st_releqjoin:
        case st_reljoin:
        case st_list:
                if (list_length(st->op1.lval))
@@ -2741,7 +2782,7 @@
 
                switch (s->type) {
                case st_relselect:
-               case st_reljoin:
+               case st_releqjoin:
                        if (s->op1.lval)
                            for (j=1, n=s->op1.lval->h; n; n=n->next, j++)
                                fprintf(fp, "id%d -> id%d 
[headlabel=\"1.%d\"];\n",
@@ -2752,6 +2793,16 @@
                                        stmt_stmt2dot(n->data, l, i, fp), 
-(s->optimized), j);
                        break;
 
+               case st_reljoin:
+                       if (s->op1.stval)
+                               fprintf(fp, "id%d -> id%d [headlabel=\"1\"];\n",
+                                       stmt_stmt2dot(s->op1.stval, l, i, fp), 
-(s->optimized));
+                       if (s->op2.lval)
+                           for (j=1, n=s->op2.lval->h; n; n=n->next, j++)
+                               fprintf(fp, "id%d -> id%d 
[headlabel=\"2.%d\"];\n",
+                                       stmt_stmt2dot(n->data, l, i, fp), 
-(s->optimized), j);
+                       break;
+
                case st_sets: 
                        if (s->op1.lval)
                           for (j=1, n=s->op1.lval->h; n; n=n->next, j++)
@@ -2833,7 +2884,7 @@
                case st_temp:
                case st_aggr:
                case st_op: case st_unop: case st_binop: case st_Nop:
-               case st_diff: case st_intersect: case st_union:
+               case st_diff: case st_union:
                case st_join: case st_join2: case st_outerjoin:
                case st_derive:
                case st_unique:
@@ -3007,7 +3058,6 @@
                        dump2(s, "join", nr); break;
        case st_join2:  
                        dump3(s, "join", nr); break;
-       case st_intersect: dump2(s, "intersect", nr); break;
        case st_group:  dump1(s, "group", nr); break;
        case st_group_ext:      dump1(s, "extent", nr); break;
        case st_derive: dump2(s, "derive", nr); break;
@@ -3052,8 +3102,8 @@
                for (n = s->op1.lval->h; n; n = n->next) 
                        (void) print_stmt(n->data, nr);
                break;
-       case st_reljoin:
-               printf("s%d = reljoin(\n", -s->nr);
+       case st_releqjoin:
+               printf("s%d = releqjoin(\n", -s->nr);
                printf("R(\n");
                for (n = s->op1.lval->h; n; n = n->next) 
                        (void) print_stmt(n->data, nr);
@@ -3062,6 +3112,16 @@
                        (void) print_stmt(n->data, nr);
                printf("))\n");
                break;
+       case st_reljoin:
+               printf("s%d = reljoin(\n", -s->nr);
+               if (s->op1.stval)
+                       print_stmt(s->op1.stval, nr);
+               printf("(\n");
+               if (s->op2.lval)
+                       for (n = s->op2.lval->h; n; n = n->next) 
+                               (void) print_stmt(n->data, nr);
+               printf("))\n");
+               break;
        case st_ptable:
                if (ptable_parent(s)) 
                        print_stmt(ptable_parent(s), nr);

Index: sql_optimize.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_optimize.mx,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- sql_optimize.mx     9 Apr 2008 09:56:23 -0000       1.92
+++ sql_optimize.mx     17 Jun 2008 10:35:09 -0000      1.93
@@ -124,13 +124,12 @@
        switch (st->type) {
        case st_join:
        case st_outerjoin:
-       case st_intersect:
        case st_reorder:
                return tailcolumn(st->op2.stval);
 
        case st_join2:
                return tailcolumn(st->op2.stval);
-       case st_reljoin:
+       case st_releqjoin:
                return tailcolumn(st->op2.lval->h->data);
 
        case st_semijoin:
@@ -204,12 +203,7 @@
        case st_column:
        case st_alias:
                return 0;
-/*
-               return select_count(s->op1.stval);
-*/
-       case st_intersect:
-               return select_count(s->op1.stval ) + select_count(s->op2.stval);
-       case st_reljoin:{
+       case st_releqjoin:{
                int sc = 0;
                node *n = NULL;
 
@@ -221,6 +215,17 @@
                }
                return sc;
        }
+       case st_reljoin:{
+               int sc = 0;
+               node *n = NULL;
+
+               if (s->op1.stval)
+                       sc += select_count(s->op1.stval);
+               if (s->op2.lval)
+                       for (n = s->op2.lval->h; n; n = n->next) 
+                               sc += select_count(n->data);
+               return sc;
+       }
        case st_join:
                /* we don't like thetajoins */
                if (s->flag != cmp_equal)
@@ -332,119 +337,62 @@
        return -1;
 }
 
-#define TYPE_JOIN(type)  (type == st_join || type == st_join2 || type == 
st_reljoin)
-
 static stmt *
-stmt_intersect(stmt *op1, stmt *op2)
+releqjoin2select( stmt *rj )
 {
-       stmt *res = NULL;
-       int reverse = 0;
+       node *n1 = rj->op1.lval->h;
+       node *n2 = rj->op2.lval->h;
 
-       while (op1->type == st_reverse) {
-               stmt *r = op1;
+       stmt *cmp, *le, *re;
 
-               op1 = stmt_dup(op1->op1.stval);
-               stmt_destroy(r);
+       le = stmt_dup(n1->data);
+       re = stmt_dup(n2->data);
+       cmp = stmt_uselect(le, re, cmp_equal);
+       for(n1 = n1->next, n2 = n2->next; 
+           n1 && n2; n1 = n1->next, n2 = n2->next) {
+               le = stmt_semijoin(stmt_dup(n1->data), stmt_dup(cmp));
+               re = stmt_semijoin(stmt_dup(n2->data), cmp);
+               cmp = stmt_uselect(le, re, cmp_equal);
        }
-       while (op2->type == st_reverse) {
-               stmt *r = op2;
+       return cmp;
+}
 
-               op2 = stmt_dup(op2->op1.stval);
-               stmt_destroy(r);
-       }
-       if (op1->h != op2->h) {
-               reverse = 1;
-       }
-       assert((TYPE_JOIN(op1->type)) && (TYPE_JOIN(op2->type)));
+static stmt * stmt_join2select(stmt *j);
+static stmt *
+stmt_join2select_(stmt *j)
+{
+       return stmt_join2select(stmt_dup(j));
+}
 
-       /* only keep the join, ie forget about the cross product */
-       if (TYPE_JOIN(op1->type) && op1->flag == cmp_all) {
-               stmt_destroy(op1);
-               return op2;
-       } else if (TYPE_JOIN(op2->type) && op2->flag == cmp_all) {
-               stmt_destroy(op2);
-               return op1;
-       }
+static stmt *
+reljoin2select( stmt *joins )
+{
+       stmt *join = NULL;
+       stmt *releqjoin = joins->op1.stval;
+       list *nqjoins = joins->op2.lval;
 
-       /* this case should have been transformed into a proper
-          multi-att join ("st_reljoin") by push_selects_down()
-        */
-       assert(!(op1->type == st_reljoin && op2->type == st_reljoin));
-       assert(op1->type != st_idxbat && op2->type != st_idxbat);
+       if (releqjoin) 
+               join = stmt_join2select(stmt_dup(releqjoin));
 
-       /*
-        * need to add the mark trick as [].select(true) on tables
-        * without unique head identifiers + semijoin is wrong
-        */
-       if (!reverse) {
-               stmt *ml = stmt_mark(stmt_reverse(stmt_dup(op1)), 50);
-               stmt *mr = stmt_mark(stmt_dup(op1), 50);
-               stmt *l = stmt_join(stmt_dup(ml),
-                               stmt_dup(op2->op1.stval), cmp_equal);
-               if (op2->type == st_join2) {
-                       stmt *r1 = stmt_join(stmt_dup(mr),
-                                       stmt_dup(op2->op2.stval), cmp_equal);
-                       stmt *r2 = stmt_join(stmt_dup(mr),
-                                       stmt_dup(op2->op3.stval), cmp_equal);
-                       comp_type c1 = op2->flag&2 ? cmp_gte : cmp_gt;
-                       comp_type c2 = op2->flag&1 ? cmp_lte : cmp_lt;
-                       stmt *v1 = stmt_uselect(l, r1, c1);
-                       stmt *v2 = stmt_uselect(stmt_dup(l), r2, c2);
-                       
-                       ml = stmt_semijoin(ml, v1);
-                       ml = stmt_semijoin(ml, v2);
-                       res = stmt_join(stmt_reverse(ml), mr, cmp_equal);
-               } else {
-                       stmt *r = stmt_join(stmt_dup(mr),
-                                       stmt_reverse(stmt_dup(op2->op2.stval)), 
cmp_equal);
-                       stmt *v = stmt_uselect(l, r, (comp_type) op2->flag);
-       
-                       res = stmt_join(stmt_reverse(stmt_semijoin(ml, v)), mr, 
cmp_equal);
-               }
-       } else {                /* reverse */
-               if (op2->type == st_join2) {
-                       stmt *ml = stmt_mark(stmt_reverse(stmt_dup(op1)), 50);
-                       stmt *mr = stmt_mark(stmt_dup(op1), 50);
-                       stmt *l = stmt_join(stmt_dup(mr),
-                                       stmt_dup(op2->op1.stval), cmp_equal);
-                       stmt *r1 = stmt_join(stmt_dup(ml),
-                                       stmt_dup(op2->op2.stval), cmp_equal);
-                       stmt *r2 = stmt_join(stmt_dup(ml),
-                                       stmt_dup(op2->op3.stval), cmp_equal);
-                       comp_type c1 = op2->flag&2 ? cmp_gte : cmp_gt;
-                       comp_type c2 = op2->flag&1 ? cmp_lte : cmp_lt;
-                       stmt *v1 = stmt_uselect(l, r1, c1);
-                       stmt *v2 = stmt_uselect(stmt_dup(l), r2, c2);
-       
-                       ml = stmt_semijoin(ml, v1);
-                       ml = stmt_semijoin(ml, v2);
-                       res = stmt_join(stmt_reverse(ml), mr, cmp_equal);
-               } else {
-                       stmt *ml = stmt_mark(stmt_reverse(stmt_dup(op1)), 50);
-                       stmt *mr = stmt_mark(stmt_dup(op1), 50);
-                       stmt *l = stmt_join(stmt_dup(mr),
-                                       stmt_dup(op2->op1.stval), cmp_equal);
-                       stmt *r = stmt_join(stmt_dup(ml),
-                                       stmt_reverse(stmt_dup(op2->op2.stval)), 
cmp_equal);
-                       stmt *v = stmt_uselect(l, r, (comp_type) op2->flag);
-       
-                       res = stmt_join(stmt_reverse(stmt_semijoin(ml, v)), mr, 
cmp_equal);
-               }
+       if (list_length(nqjoins)) {
+               list *sels = list_map(nqjoins, NULL, (fmap) &stmt_join2select_);
+               stmt *nj = (stmt *) list_reduce(sels, (freduce) &stmt_semijoin, 
(fdup) &stmt_dup);
+               if (join)
+                       join = stmt_semijoin(join, nj);
+               else
+                       join = nj;
+               list_destroy(sels);
        }
-
-       stmt_destroy(op1);
-       stmt_destroy(op2);
-       return res;
+       return join;
 }
 
-
 static stmt *stmt_push_down_tail(stmt *join, stmt *select);
 static stmt *
 stmt_push_down_head(stmt *join, stmt *select)
 {
        stmt *res = NULL;
 
-       if (join->type == st_reljoin) {
+       if (join->type == st_releqjoin) {
                list *l1 = create_stmt_list();
                list *l2 = list_dup(join->op2.lval, (fdup) &stmt_dup);
                node *n;
@@ -454,7 +402,24 @@
                }
                stmt_destroy(select);
                stmt_destroy(join);
-               return stmt_reljoin2(l1, l2);
+               return stmt_releqjoin2(l1, l2);
+       } else if (join->type == st_reljoin) {
+               stmt *reljoin = NULL;
+               list *l2 = NULL;
+               node *n;
+
+               if (join->op1.stval)
+                       reljoin = 
stmt_push_down_head(stmt_dup(join->op1.stval), stmt_dup(select));
+
+               if (join->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = join->op2.lval->h; n; n = n->next) {
+                               l2 = list_append(l2, 
stmt_push_down_head(stmt_dup(n->data), stmt_dup(select)));
+                       }
+               }
+               stmt_destroy(select);
+               stmt_destroy(join);
+               return stmt_reljoin(reljoin, l2);
        } else if (join->type == st_join) {
                res = stmt_join(stmt_push_down_head(stmt_dup(join->op1.stval), 
select), stmt_dup(join->op2.stval), (comp_type) join->flag);
                stmt_destroy(join);
@@ -463,11 +428,6 @@
                res = stmt_join2(stmt_push_down_head(stmt_dup(join->op1.stval), 
select), stmt_dup(join->op2.stval), stmt_dup(join->op3.stval), join->flag);
                stmt_destroy(join);
                return res;
-       } else if (join->type == st_intersect) {
-               res = 
stmt_intersect(stmt_push_down_head(stmt_dup(join->op1.stval), select), 
stmt_push_down_head(stmt_dup(join->op2.stval), stmt_dup(select))
-                   );
-               stmt_destroy(join);
-               return res;
        } else if (join->type == st_reverse) {
                res = 
stmt_reverse(stmt_push_down_tail(stmt_dup(join->op1.stval), select));
                stmt_destroy(join);
@@ -531,7 +491,7 @@
 {
        stmt *res;
 
-       if (join->type == st_reljoin) {
+       if (join->type == st_releqjoin) {
                list *l1 = list_dup(join->op2.lval, (fdup) &stmt_dup);
                list *l2 = create_stmt_list();
                node *n;
@@ -541,7 +501,24 @@
                }
                stmt_destroy(select);
                stmt_destroy(join);
-               return stmt_reljoin2(l1, l2);
+               return stmt_releqjoin2(l1, l2);
+       } else if (join->type == st_reljoin) {
+               stmt *reljoin = NULL;
+               list *l2 = NULL;
+               node *n;
+
+               if (join->op1.stval)
+                       reljoin = 
stmt_push_down_tail(stmt_dup(join->op1.stval), stmt_dup(select));
+
+               if (join->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = join->op2.lval->h; n; n = n->next) {
+                               l2 = list_append(l2, 
stmt_push_down_tail(stmt_dup(n->data), stmt_dup(select)));
+                       }
+               }
+               stmt_destroy(select);
+               stmt_destroy(join);
+               return stmt_reljoin(reljoin, l2);
        } else if (join->type == st_join) {
                res = stmt_join(stmt_dup(join->op1.stval), 
stmt_push_down_tail(stmt_dup(join->op2.stval), select), (comp_type) join->flag);
                stmt_destroy(join);
@@ -550,12 +527,6 @@
                res = stmt_join2(stmt_dup(join->op1.stval), 
stmt_reverse(stmt_push_down_tail(stmt_reverse(stmt_dup(join->op2.stval)), 
select)), 
stmt_reverse(stmt_push_down_tail(stmt_reverse(stmt_dup(join->op3.stval)), 
select)), join->flag);
                stmt_destroy(join);
                return res;
-       } else if (join->type == st_intersect) {
-               select = stmt_dup(select);
-               res = 
stmt_intersect(stmt_push_down_tail(stmt_dup(join->op1.stval), select), 
stmt_push_down_tail(stmt_dup(join->op2.stval), select)
-                   );
-               stmt_destroy(join);
-               return res;
        } else if (join->type == st_reverse) {
                res = 
stmt_reverse(stmt_push_down_head(stmt_dup(join->op1.stval), select));
                stmt_destroy(join);
@@ -604,7 +575,7 @@
 stmt_push_join_head(stmt *s, stmt *join)
 {
        /* found target of push-down: a [rel]join */
-       if (s->type == st_reljoin) {
+       if (s->type == st_releqjoin) {
                list *l1 = create_stmt_list();
                list *l2 = list_dup(s->op2.lval, (fdup) &stmt_dup);
                node *n;
@@ -614,7 +585,27 @@
                }
                stmt_destroy(join);
                stmt_destroy(s);
-               return stmt_reljoin2(l1, l2);
+               return stmt_releqjoin2(l1, l2);
+       } else if (s->type == st_reljoin) {
+               stmt *reljoin = NULL;
+               list *l2 = NULL;
+               node *n;
+
+               if (s->op1.stval)
+                       reljoin = stmt_push_join_head(stmt_dup(s->op1.stval), 
stmt_dup(join));
+
+               if (s->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = s->op2.lval->h; n; n = n->next) {
+                               stmt *j = stmt_dup(n->data);
+                               stmt *nj = stmt_push_join_head(j, 
stmt_dup(join));
+
+                               l2 = list_append(l2, nj);
+                       }
+               }
+               stmt_destroy(join);
+               stmt_destroy(s);
+               return stmt_reljoin(reljoin, l2);
        } else if (s->type == st_join) {
                stmt *op1 = stmt_join(join, stmt_dup(s->op1.stval), cmp_equal);
                stmt *res = stmt_join(op1, stmt_dup(s->op2.stval), (comp_type) 
s->flag);
@@ -636,12 +627,6 @@
 
                stmt_destroy(s);
                return res;
-       } else if (s->type == st_intersect) {
-               stmt *res = 
stmt_intersect(stmt_push_join_head(stmt_dup(s->op1.stval), join),
-                                          
stmt_push_join_head(stmt_dup(s->op2.stval), stmt_dup(join)));
-
-               stmt_destroy(s);
-               return res;
        } else if (s->type == st_diff) {
                stmt *op1 = stmt_join(join, stmt_dup(s->op1.stval), cmp_equal);
                stmt *res = stmt_diff(op1, stmt_dup(s->op2.stval));
@@ -707,7 +692,7 @@
 stmt_push_join_tail(stmt *s, stmt *join)
 {
        /* found target of push-down: a [rel]join */
-       if (s->type == st_reljoin) {
+       if (s->type == st_releqjoin) {
                list *l1 = list_dup(s->op1.lval, (fdup) &stmt_dup);
                list *l2 = create_stmt_list();
                node *n;
@@ -717,7 +702,27 @@
                }
                stmt_destroy(s);
                stmt_destroy(join);
-               return stmt_reljoin2(l1, l2);
+               return stmt_releqjoin2(l1, l2);
+       } else if (s->type == st_reljoin) {
+               stmt *reljoin = NULL;
+               list *l2 = NULL;
+               node *n;
+
+               if (s->op1.stval)
+                       reljoin = stmt_push_join_tail(stmt_dup(s->op1.stval), 
stmt_dup(join));
+
+               if (s->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = s->op2.lval->h; n; n = n->next) {
+                               stmt *j = stmt_dup(n->data);
+                               stmt *nj = stmt_push_join_tail(j, 
stmt_dup(join));
+
+                               l2 = list_append(l2, nj);
+                       }
+               }
+               stmt_destroy(join);
+               stmt_destroy(s);
+               return stmt_reljoin(reljoin, l2);
        } else if (s->type == st_join) {
                stmt *op2 = stmt_join(stmt_dup(s->op2.stval), join, cmp_equal);
                stmt *res = stmt_join(stmt_dup(s->op1.stval), op2,
@@ -745,13 +750,6 @@
 
                stmt_destroy(s);
                return res;
-       } else if (s->type == st_intersect) {
-               stmt *res = 
stmt_intersect(stmt_push_join_tail(stmt_dup(s->op1.stval), join),
-                                          
stmt_push_join_tail(stmt_dup(s->op2.stval), stmt_dup(join))
-                   );
-
-               stmt_destroy(s);
-               return res;
        } else if (s->type == st_diff) {
                stmt *op2 = stmt_join(stmt_dup(s->op2.stval), join, cmp_equal);
                stmt *res = stmt_diff(stmt_dup(s->op1.stval), op2);
@@ -804,10 +802,13 @@
        } else if (j->type == st_idxbat) {
                assert(0); /* handled earlier */
        } else if (j->type == st_join2) {
-               stmt *res = stmt_select2(stmt_dup(j->op1.stval),
-                                        stmt_dup(j->op2.stval),
-                                        stmt_dup(j->op3.stval),
-                                        j->flag);
+               comp_type c1 = j->flag&2 ? cmp_gte : cmp_gt;
+               comp_type c2 = j->flag&1 ? cmp_lte : cmp_lt;
+               stmt *le = stmt_dup(stmt_dup(j->op1.stval));
+               stmt *cmp1 = stmt_uselect(le, stmt_dup(j->op2.stval), c1);
+               stmt *cmp2 = stmt_uselect(le, stmt_dup(j->op3.stval), c2);
+               stmt *res = stmt_semijoin(cmp1, cmp2);
+
                stmt_destroy(j);
                return res;
        } else if (j->type == st_reverse) {
@@ -815,21 +816,25 @@
 
                stmt_destroy(j);
                return res;
-       } else if (j->type == st_intersect) {
-               stmt *res = 
stmt_semijoin(stmt_join2select(stmt_dup(j->op1.stval)),
-                                         
stmt_join2select(stmt_dup(j->op2.stval)));
-
-               stmt_destroy(j);
-               return res;
        } else if (j->type == st_semijoin) {
-               stmt *res = 
stmt_semijoin(stmt_join2select(stmt_dup(j->op1.stval)),
+               stmt *res = stmt_semijoin(stmt_join2select(
+                                         stmt_dup(j->op1.stval)),
                                          stmt_dup(j->op2.stval));
 
                stmt_destroy(j);
                return res;
+       } else if (j->type == st_releqjoin) {
+               stmt *res = releqjoin2select(j);
+               stmt_destroy(j);
+               return res;
+       } else if (j->type == st_reljoin) {
+               stmt *res = reljoin2select(j);
+               stmt_destroy(j);
+               return res;
 #ifndef NDEBUG
        } else {
                printf("= TODO: common/optimize.c: join2select %s\n", 
st_type2string(j->type));
+               assert(0);
 #endif
        }
        return j;
@@ -1064,12 +1069,11 @@
        }
        list_destroy(sels);
 
-       /* TODO join order rewrites */
        for (n = djoins->h; n; n = n->next) {
                list *ejoins = list_select(joins, n->data, (fcmp) 
&stmt_cmp_head_tail, (fdup) &stmt_dup);
                stmt *join = ejoins->h->data;
                list *eqjoins = NULL, *nqjoins = NULL, *rjoins = NULL;
-               stmt *reljoin = NULL, *jdx = NULL;
+               stmt *releqjoin = NULL, *jdx = NULL;
                node *hsel = NULL, *tsel = NULL;
                node * jn;
 
@@ -1082,15 +1086,15 @@
                                stmt *jt = stmt_reverse(stmt_dup(j->op1.stval));
                                jn->data = stmt_join(jh, jt, 
swap_compare((comp_type)j->flag));
                                stmt_destroy(j);
-                       } else if (j->type == st_reljoin &&
+                       } else if (j->type == st_releqjoin &&
                                   STMT_BAT(j->op1.stval->type) && 
                                   STMT_BAT(j->op2.stval->op1.stval->type) &&
                                   j->t == join->h) {
                                list *l1 = list_dup(j->op1.lval, 
(fdup)&stmt_dup);
                                list *l2 = list_dup(j->op2.lval, 
(fdup)&stmt_dup);
-                               /* change order reljoin ? */
+                               /* change order releqjoin ? */
                                assert(0);
-                               jn->data = stmt_reljoin2(l2,l1);
+                               jn->data = stmt_releqjoin2(l2,l1);
                                stmt_destroy(j);
                        }
                }
@@ -1191,13 +1195,13 @@
                eqjoins = list_select(ejoins, (void *) 1L, (fcmp) &join_cmp_eq, 
(fdup) &stmt_dup);
                if (list_length(eqjoins) > 1) {
                        /* rewrite conjuction of equi-join into multi-att 
equi-join */
-                       reljoin = stmt_reljoin1(eqjoins);
+                       releqjoin = stmt_releqjoin1(eqjoins);
                        /* collect the remaining non-equi joins */
                        nqjoins = list_select(ejoins, (void *) 1L, (fcmp) 
&join_cmp_neq, (fdup) &stmt_dup);
                        list_destroy(ejoins);
                } else {
                        /* no multi-att equi-join found; treat all joins 
equally */
-                       reljoin = NULL;
+                       releqjoin = NULL;
                        nqjoins = ejoins;
                }
                list_destroy(eqjoins);
@@ -1270,14 +1274,14 @@
                if (jdx) 
                        list_append(nqjoins, jdx);
 
-               /* changes to [].().select(TRUE) */
-               join = (stmt *) list_reduce(nqjoins, (freduce) &stmt_intersect, 
(fdup) &stmt_dup);
-               list_destroy(nqjoins);
-
-               if (reljoin && join) {
-                       join = stmt_intersect(reljoin, join);
-               } else if (reljoin) {
-                       join = reljoin;
+               if (list_length(nqjoins) > 0){
+                       if (releqjoin || list_length(nqjoins) > 1)
+                               join = stmt_reljoin(releqjoin, nqjoins);
+                       else
+                               join = stmt_dup(nqjoins->h->data);
+               } else {
+                       list_destroy(nqjoins);
+                       join = releqjoin;
                }
 
                if (!join)
@@ -1688,7 +1692,7 @@
                s->optimized = 1;
                return stmt_dup(s);
 
-       case st_reljoin:{
+       case st_releqjoin:{
 
                list *l1 = create_stmt_list();
                list *l2 = create_stmt_list();
@@ -1699,7 +1703,7 @@
                        list_append(l1, optimize(c, n1->data));
                        list_append(l2, optimize(c, n2->data));
                }
-               res = stmt_reljoin2(l1, l2);
+               res = stmt_releqjoin2(l1, l2);
                s->optimized = res->optimized = 1;
                if (res != s) {
                        assert(s->rewritten==NULL);
@@ -1708,6 +1712,29 @@
                return res;
        }
 
+       case st_reljoin:{
+
+               stmt *reljoin = NULL;
+               list *l2 = NULL;
+               node *n;
+               stmt *res;
+
+               if (s->op1.stval)
+                       reljoin = optimize(c, s->op1.stval);
+               if (s->op2.lval) {
+                       l2 = create_stmt_list();
+                       for (n = s->op2.lval->h; n; n = n->next) {
+                               list_append(l2, optimize(c, n->data));
+                       }
+               }
+               res = stmt_reljoin(reljoin, l2);
+               s->optimized = res->optimized = 1;
+               if (res != s) {
+                       assert(s->rewritten==NULL);
+                       s->rewritten = stmt_dup(res);
+               }
+               return res;
+       }
        case st_relselect:{
 
                list *l = create_stmt_list();
@@ -1734,7 +1761,6 @@
        case st_uselect2:
        case st_semijoin:
        case st_diff:
-       case st_intersect:
        case st_union:
        case st_outerjoin:
        case st_join:

Index: bin_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/bin_optimizer.mx,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- bin_optimizer.mx    10 Mar 2008 10:16:25 -0000      1.11
+++ bin_optimizer.mx    17 Jun 2008 10:35:01 -0000      1.12
@@ -205,7 +205,7 @@
        case st_uselect2:
        case st_semijoin:
        case st_limit:
-       case st_reljoin:
+       case st_releqjoin:
        case st_join2:
                return 1;
 
@@ -513,7 +513,6 @@
        case st_temp:
        case st_filter:
        case st_diff:
-       case st_intersect:
        case st_union:
        case st_outerjoin:
        case st_mirror:
@@ -607,7 +606,7 @@
                return res;
        }
 
-       case st_reljoin:
+       case st_releqjoin:
        case st_relselect:
 
        case st_pivot:

Index: rel_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_select.mx,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- rel_select.mx       30 May 2008 09:31:29 -0000      1.76
+++ rel_select.mx       17 Jun 2008 10:35:08 -0000      1.77
@@ -4283,6 +4283,8 @@
 
                if (!instantiate)
                        sql->emode = m_instantiate;
+               if (instantiate) /* we also need the other views instantiated */
+                       sql->emode = 0;
                sq = rel_subquery(sql, NULL, query, ek);
                sql->emode = emode;
                if (!sq)

Index: rel_bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_bin.mx,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- rel_bin.mx  16 Jun 2008 09:23:25 -0000      1.44
+++ rel_bin.mx  17 Jun 2008 10:35:06 -0000      1.45
@@ -556,6 +556,14 @@
                return NULL;    
        }
        if (rel->exps) {
+               /* TODO introduce hash optimized reljoin (see rel2bin.mx) */
+               /* probably better to simply generate stmt_reljoin here */
+
+               /* simply keep a list of joins */
+               /* at end split the lists in 2, ie those with equi joins and
+                  those not. With those results create releqjoin and reljoin   
+                  statements.
+                */
                for( en = rel->exps->h; en; en = en->next ) {
                        stmt *s = exp_bin(sql, en->data, left, right, NULL, 
NULL);
 
@@ -894,14 +902,14 @@
        rs = stmt_aggr(stmt_dup(rgrp->grp), grp_dup(rgrp), a, 1); 
 
        /* now find the matching groups */
-       s = stmt_reljoin_init();
+       s = stmt_releqjoin_init();
        for (n = left->op1.lval->h, m = right->op1.lval->h; n && m; n = 
n->next, m = m->next) {
                stmt *l = stmt_dup(n->data);
                stmt *r = stmt_dup(m->data);
 
                l = stmt_join(stmt_dup(lgrp->ext), l, cmp_equal);
                r = stmt_join(stmt_dup(rgrp->ext), r, cmp_equal);
-               stmt_reljoin_fill(s, l, r);
+               stmt_releqjoin_fill(s, l, r);
        }
 
        /* the join of the groups removed those in A but not in B,
@@ -1012,14 +1020,14 @@
        rs = stmt_aggr(stmt_dup(rgrp->grp), grp_dup(rgrp), a, 1); 
 
        /* now find the matching groups */
-       s = stmt_reljoin_init();
+       s = stmt_releqjoin_init();
        for (n = left->op1.lval->h, m = right->op1.lval->h; n && m; n = 
n->next, m = m->next) {
                stmt *l = stmt_dup(n->data);
                stmt *r = stmt_dup(m->data);
 
                l = stmt_join(stmt_dup(lgrp->ext), l, cmp_equal);
                r = stmt_join(stmt_dup(rgrp->ext), r, cmp_equal);
-               stmt_reljoin_fill(s, l, r);
+               stmt_releqjoin_fill(s, l, r);
        }
                
        /*if (!distinct) */


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins

Reply via email to