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

Modified Files:
        rel_bin.mx rel_optimizer.mx rel_select.mx sql_mvc.mx 
        sql_select.mx 
Log Message:
cleanup scale fixing in functions, this is now stored inside a new field
in the sql_subfunc structure (ie no longer in the sql_func result type
scale field)

rel_optimizer now pushes selects also through renaming projections
rel_optimizer now orders the select expressions on reducing quality

rel_bin now generates (like bin version) stmt_releqjoin and stmt_reljoin
(which are then by sql_rel2bin optimized, ie using hash for multi attribute 
joins)



U sql_mvc.mx
Index: sql_mvc.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_mvc.mx,v
retrieving revision 1.202
retrieving revision 1.203
diff -u -d -r1.202 -r1.203
--- sql_mvc.mx  5 Jun 2008 09:23:22 -0000       1.202
+++ sql_mvc.mx  20 Jun 2008 20:50:31 -0000      1.203
@@ -772,7 +772,7 @@
 sql_table *
 mvc_bind_table(mvc *m, sql_schema *s, char *tname)
 {
-       sql_table *t;
+       sql_table *t = NULL;
 
        if (!s) { /* Declared tables during query compilation have no schema */
                sql_subtype *tpe = stack_find_type(m, tname);

U rel_select.mx
Index: rel_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_select.mx,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -d -r1.77 -r1.78
--- rel_select.mx       17 Jun 2008 10:35:08 -0000      1.77
+++ rel_select.mx       20 Jun 2008 20:50:31 -0000      1.78
@@ -2572,14 +2572,14 @@
                }
        }
        if (f) {
-               if (f->func->res.scale == SCALE_FIX) {
+               if (f->func->fix_scale == SCALE_FIX) {
                        l = exp_fix_scale(sql, t2, l, 0, 0);
                        r = exp_fix_scale(sql, t1, r, 0, 0);
-               } else if (f->func->res.scale == SCALE_SUB) {
+               } else if (f->func->fix_scale == SCALE_SUB) {
                        l = exp_scale_algebra(sql, f, l, r);
-               } else if (f->func->res.scale == SCALE_ADD) {
+               } else if (f->func->fix_scale == SCALE_ADD) {
                        l = exp_sum_scales(sql, f, l, r);
-               } else if (f->func->res.scale == DIGITS_ADD) {
+               } else if (f->func->fix_scale == DIGITS_ADD) {
                        f->res.digits = t1->digits + t2->digits;
                }
                return exp_binop(l, r, f);
@@ -2621,14 +2621,14 @@
                        t2 = exp_subtype(r);
                        f = sql_bind_func(s, fname, t1, t2);
                        if (f) {
-                               if (f->func->res.scale == SCALE_FIX) {
+                               if (f->func->fix_scale == SCALE_FIX) {
                                        l = exp_fix_scale(sql, t2, l, 0, 0);
                                        r = exp_fix_scale(sql, t1, r, 0, 0);
-                               } else if (f->func->res.scale == SCALE_SUB) {
+                               } else if (f->func->fix_scale == SCALE_SUB) {
                                        l = exp_scale_algebra(sql, f, l, r);
-                               } else if (f->func->res.scale == SCALE_ADD) {
+                               } else if (f->func->fix_scale == SCALE_ADD) {
                                        l = exp_sum_scales(sql, f, l, r);
-                               } else if (f->func->res.scale == DIGITS_ADD) {
+                               } else if (f->func->fix_scale == DIGITS_ADD) {
                                        f->res.digits = digits;
                                }
                                exp_destroy(ol);

U rel_optimizer.mx
Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- rel_optimizer.mx    14 May 2008 20:18:24 -0000      1.16
+++ rel_optimizer.mx    20 Jun 2008 20:50:30 -0000      1.17
@@ -762,70 +762,11 @@
        return rel;
 }
 
-#if 0
-static sql_exp *
-exp_remove_alias(sql_exp *e, list *exps) 
-{
-       sql_exp *r = NULL;
-
-       switch(e->type) {
-       case e_column:
-               if (e->l) 
-                       r = exps_bind_column2(exps, e->l, e->r);
-               else
-                       r = exps_bind_column(exps, e->r);
-               if (r) {
-                       r = exp_dup(r);
-                       exp_destroy(e);
-                       return r;
-               }
-               break;
-       case e_cmp: 
-               e->l = exp_remove_alias(e->l, exps);
-               e->r = exp_remove_alias(e->r, exps);
-               if (e->f)
-                       e->f = exp_remove_alias(e->f, exps);
-               return e;
-       case e_convert:
-               e->l = exp_remove_alias(e->l, exps);
-               return e;
-       case e_aggr:
-       case e_func: {
-               list *l = e->l;
-               if (l) {
-                       node *n;
-                       list *nl = new_exp_list();
-                       for(n=l->h; n; n=n->next) {
-                               sql_exp *arg = n->data;
-
-                               arg = exp_dup(exp_remove_alias(arg, exps));
-                               append(nl, arg);
-                       }
-                       list_destroy(l);
-                       e->l = nl;
-               }
-       }       return e;
-       case e_atom:
-               return e;
-       }
-       return NULL;
-}
-#endif
-
-/*
-static sql_exp *
-exps_remove_alias(sql_exp *e, list *exps) 
-{
-       return exp_dup(exp_remove_alias(e, exps));
-}
-*/
-
-#if 0
 /* push the expression down, ie translate colum references from relation f 
into expression of relation t */ 
 static sql_exp *
 exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) 
 {
-       sql_exp *ne = NULL;
+       sql_exp *ne = NULL, *l, *r, *r2;
 
        switch(e->type) {
        case e_column:
@@ -839,25 +780,35 @@
                        ne = exps_bind_column(f->exps, e->r);
                assert(ne);
                e = NULL;
-               if (ne->name && strcmp(ne->r, ne->name) == 0){ /* no alias */ 
+               if (ne->name && ne->r && strcmp(ne->r, ne->name) == 0){ 
                        if (ne->l) {
                                e = rel_bind_column2(sql, t, ne->l, ne->r);
                                if (!e && t->name && strcmp(ne->l, t->name) == 
0) 
                                        e = rel_bind_column(sql, t, ne->r);
                        }
                }
-               if (!e)
+               if (!e && ne->r)
                        e = rel_bind_column(sql, t, ne->r);
-               assert(e);
-               //return exp_dup(e);
                return e;
        case e_cmp: 
-               if (e->f) 
-                       return exp_compare2( exp_push_down(sql, e->l, f, t), 
exp_push_down(sql, e->r, f, t), exp_push_down(sql, e->f, f, t), e->flag);
-               else
-                       return exp_compare( exp_push_down(sql, e->l, f, t), 
exp_push_down(sql, e->r, f, t), e->flag);
+               l = exp_push_down(sql, e->l, f, t);
+               r = exp_push_down(sql, e->r, f, t);
+               if (e->f) {
+                       r2 = exp_push_down(sql, e->f, f, t);
+                       if (l && r && r2)
+                               return exp_compare2( l, r, r2, e->flag);
+               } else if (l && r) {
+                       return exp_compare( l, r, e->flag);
+               }
+               exp_destroy(l);
+               exp_destroy(r);
+               return NULL;
        case e_convert:
-               return exp_convert( exp_push_down(sql, e->l, f, t), 
exp_fromtype(e), exp_totype(e));
+               l = exp_push_down(sql, e->l, f, t);
+               if (l)
+                       return exp_convert( l, exp_fromtype(e), exp_totype(e));
+               exp_destroy(l);
+               return NULL;
        case e_aggr:
        case e_func: {
                list *l = e->l, *nl = NULL;
@@ -872,31 +823,52 @@
                                sql_exp *arg = n->data;
 
                                arg = exp_push_down(sql, arg, f, t);
+                               if (!arg) {
+                                       list_destroy(nl);
+                                       return NULL;
+                               }
                                append(nl, arg);
                        }
                }
                if (e->type == e_func)
                        return exp_op(nl, sql_dup_func(e->f));
-               return exp_aggr(nl, sql_dup_aggr(e->f), e->flag&1, 
(e->flag>>1), e->card);
+               else 
+                       return exp_aggr(nl, sql_dup_aggr(e->f), e->flag&1, 
(e->flag>>1), e->card);
        }       
        case e_atom:
                return exp_dup(e);
        }
        return NULL;
 }
-#endif
 
 sql_rel *
 rel_push_select_down(mvc *sql, sql_rel *rel) 
 {
-       //sql_rel *rr, *rl;
-
-(void)sql;
+       (void)sql;
+       if ((is_join(rel->op) || is_project(rel->op) || rel->op == op_topn) && 
rel->l) {
+               sql_rel *l = rel->l;
+               if (l->op == op_select && 
+                  (!l->exps || list_length(l->exps) == 0)) {
+                       rel->l = l->l;
+                       l->l = NULL;
+                       rel_destroy(l);
+               } 
+       }
+       if ((is_join(rel->op) || is_set(rel->op)) && rel->r) {
+               sql_rel *r = rel->r;
+               if (r->op == op_select && 
+                  (!r->exps || list_length(r->exps) == 0)) {
+                       rel->r = r->l;
+                       r->l = NULL;
+                       rel_destroy(r);
+               }
+       } 
        if (rel->op == op_select && rel->l) {
+               list *exps = rel->exps;
                sql_rel *r = rel->l; 
-       //      node *n;
+               node *n;
 
-               assert(rel->exps);
+               assert(exps);
 
                switch(r->op) {
                case op_basetable:
@@ -917,7 +889,7 @@
 
                        /* for each exp check if we can push it left or right */
 /*
-                       for (n=rel->exps->h; n; n = n->next) { 
+                       for (n=exps->h; n; n = n->next) { 
                                sql_exp *e = n->data;
                        
                                if (e->type == e_cmp) {
@@ -931,7 +903,7 @@
                                        } else {
                                                nr =rel_push_select(r, le, re);
                                        }
-                                       assert(nr==r);
+                                       //assert(nr==r);
                                        (void)nr;
                                }
                        }
@@ -951,7 +923,7 @@
                        r = rel_dup(rel->l); 
                        rl = rel_select(rel_dup(r->l), NULL);
                        rr = rel_select(rel_dup(r->r), NULL);
-                       for (n=rel->exps->h; n; n = n->next) { 
+                       for (n=exps->h; n; n = n->next) { 
                                sql_exp *le, *re, *e = n->data;
 */
 
@@ -959,6 +931,7 @@
 /*
                                le = exp_push_down(sql, e, r, r->l);
                                re = exp_push_down(sql, e, r, r->r);
+                               
                                rel_select_add_exp(rl, exp_dup(le));
                                rel_select_add_exp(rr, exp_dup(re));
                        }
@@ -987,34 +960,37 @@
 
                        /* here we need to fix aliases */
 
-//                     r = r->l;
+                       rel->exps = new_exp_list(); 
                        /* for each exp check if we can rename it */
-/*
-                       for (n=rel->exps->h; n; n = n->next) { 
-                               sql_exp *e = n->data;
-                       
+                       for (n = exps->h; n; n = n->next) { 
+                               sql_exp *e = n->data, *ne = NULL, *le, *re;
+                               sql_rel *prj = r, *nr, *nl;
+
+                               /* sometimes we also have functions in the 
expression list (TODO change them to e_cmp (predicates like (1=0))) */
                                if (e->type == e_cmp) {
-                                       sql_exp *le, *re;
-                                       sql_rel *nr, *p = rel->l;
-               
-                                       e = exps_remove_alias(e, p->exps);
-                                       le = e->l;
-                                       re = e->r;
+                                       ne = exp_push_down(sql, e, prj, prj->l);
+                                       /* can we move it down */
+                                       if (ne && ne != e) {
+                                               nr = prj->l;
+                                       } else {
+                                               nr = rel;
+                                               exp_destroy(ne);
+                                               ne = exp_dup(e);
+                                       }
+                                       le = ne->l;
+                                       re = ne->r;
                                        if (re->card >= CARD_AGGR) {
-                                               nr = rel_push_join(r, le, re, 
e);
+                                               nl = rel_push_join(nr, le, re, 
ne);
                                        } else {
-                                               nr = rel_push_select(r, le, re);
+                                               nl = rel_push_select(nr, le, 
ne);
                                        }
-                                       assert(nr==r);
-                                       (void)nr;
+                                       if (nl != nr)
+                                               prj->l = nl;
+                               } else {
+                                       list_append(rel->exps, exp_dup(e));
                                }
                        }
-                       r = rel->l;
-                       rel->l = NULL;
-                       rel_destroy( rel );
-                       rel = r;
-                       rel_print(sql, rel, 0);
-*/
+                       list_destroy(exps);
                        return rel;
 
                case op_groupby: 
@@ -1175,6 +1151,51 @@
        return rel;
 }
 
+/* TODO CSE */
+static list *
+exp_merge(list *exps)
+{
+       node *n, *m;
+       for (n=exps->h; n && n->next; n = n->next) {
+               sql_exp *e = n->data;
+               //sql_exp *le = e->l;
+               sql_exp *re = e->r;
+
+               assert(e->type == e_cmp);
+               /* only look for gt, gte, lte, lt */
+               if (re->card == CARD_ATOM && e->flag < cmp_equal) {
+                       for (m=n->next; m; m = m->next) {
+                               sql_exp *f = m->data;
+                               //sql_exp *lf = f->l;
+                               sql_exp *rf = f->r;
+
+                               assert(f->type == e_cmp);
+                               if (rf->card == CARD_ATOM && e->flag < 
cmp_equal) {
+                                       //printf("possible candidate\n");
+                               }
+                       }
+               }
+       }
+       return exps;
+}
+
+static sql_rel *
+rel_select_order(mvc *sql, sql_rel *rel) 
+{
+       (void)sql;
+       if (rel->op == op_select && rel->exps && list_length(rel->exps)>1) {
+               list *exps = NULL;
+                       
+#ifdef DEBUG
+               rel_print(sql, rel, 0);
+#endif
+               exps = list_sort(rel->exps, (fkeyvalue)&exp_keyvalue, 
(fdup)&exp_dup);
+               list_destroy(rel->exps);
+               rel->exps = exp_merge(exps);
+       }
+       return rel;
+}
+
 static sql_rel *
 rewrite(mvc *sql, sql_rel *rel, rewrite_fptr rewriter) 
 {
@@ -1235,16 +1256,18 @@
                (for example common rels, with only one different expression) */
        /* TODO common sub relation/expression optimizer */
 
-/*
        if (gp.cnt[op_select])
                rel = rewrite(sql, rel, &rel_push_select_down); 
-*/
+
        if (gp.cnt[op_select])
                rel = rewrite(sql, rel, &rel_select_use_index); 
 
        if (gp.cnt[op_join])
                rel = rewrite(sql, rel, &rel_join_order); 
 
+       if (gp.cnt[op_select])
+               rel = rewrite(sql, rel, &rel_select_order); 
+
 #ifdef DEBUG
        rel_print(sql, rel, 0);
 #endif

U rel_bin.mx
Index: rel_bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_bin.mx,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- rel_bin.mx  17 Jun 2008 10:35:06 -0000      1.45
+++ rel_bin.mx  20 Jun 2008 20:50:30 -0000      1.46
@@ -537,6 +537,22 @@
        return sub;
 }
 
+static int
+equi_join(stmt *j)
+{
+       if (j->flag == cmp_equal)
+               return 0;
+       return -1;
+}
+
+static int
+not_equi_join(stmt *j)
+{
+       if (j->flag != cmp_equal)
+               return 0;
+       return -1;
+}
+
 static stmt *
 rel2bin_join( mvc *sql, sql_rel *rel )
 {
@@ -556,29 +572,28 @@
                return NULL;    
        }
        if (rel->exps) {
-               /* TODO introduce hash optimized reljoin (see rel2bin.mx) */
-               /* probably better to simply generate stmt_reljoin here */
+               int idx = 0;
+               list *jns = create_stmt_list();
 
-               /* 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.
-                */
+               /* generate a stmt_reljoin */
                for( en = rel->exps->h; en; en = en->next ) {
+                       int join_idx = sql->opt_stats[0];
                        stmt *s = exp_bin(sql, en->data, left, right, NULL, 
NULL);
 
                        if (!s) {
                                assert(0);
                                stmt_destroy(left);
                                stmt_destroy(right);
-                               if (join)
-                                       stmt_destroy(join);
+                               list_destroy(jns);
                                return NULL;
                        }
+                       if (join_idx != sql->opt_stats[0])
+                               idx = 1;
                        if (!join) {
                                join = s;
                        } else if (s->type != st_join && s->type != st_join2) {
                                /* handle select expressions */
+                               assert(0);
                                if (s->h == join->h) {
                                        join = stmt_semijoin(join,s);
                                } else {
@@ -586,44 +601,25 @@
                                        join = stmt_semijoin(join,s);
                                        join = stmt_reverse(join);
                                }
+                               continue;
+                       }
+                       list_append(jns, s);
+               }
+               if (list_length(jns) > 1) {
+                       int o = 1, *O = &o;
+                       /* move all equi joins into a releqjoin */
+                       list *eqjns = list_select(jns, O, (fcmp)&equi_join, 
(fdup)stmt_dup);
+                       if (!idx && list_length(eqjns) > 1) {
+                               list *neqjns = list_select(jns, O, 
(fcmp)&not_equi_join, (fdup)stmt_dup);
+                               list_destroy(jns);
+                               join = stmt_reljoin(stmt_releqjoin1(eqjns), 
neqjns);
                        } else {
-                               /* break column join */
-                               stmt *l = stmt_mark(stmt_reverse(join), 100);
-                               stmt *r = stmt_mark(stmt_dup(join), 100);
-                               stmt *ld = stmt_dup(s->op1.stval);
-                               stmt *le = stmt_join(l, ld, cmp_equal);
-                               if (s->type == st_join2) {
-                                       stmt *rd = stmt_dup(s->op2.stval);
-                                       stmt *re = stmt_join(r, rd, cmp_equal);
-                                       stmt *r2 = stmt_dup(s->op3.stval);
-                                       stmt *re2 = stmt_join(stmt_dup(r), r2, 
cmp_equal);
-                                       comp_type c1 = s->flag&2?cmp_gte:cmp_gt;
-                                       comp_type c2 = s->flag&1?cmp_lte:cmp_lt;
-                                       stmt *v1 = stmt_uselect(le, re, c1);
-                                       stmt *v2 = stmt_uselect(stmt_dup(le), 
re2, c2);
-                                       l = stmt_semijoin(stmt_dup(l), 
stmt_dup(v1));
-                                       l = stmt_semijoin(l, stmt_dup(v2));
-                                       r = stmt_semijoin(stmt_dup(r), v1);
-                                       r = stmt_semijoin(r, v2);
-                                       join = stmt_join(stmt_reverse(l), r, 
cmp_equal);
-                                       stmt_destroy(s);
-                               } else {
-                                       stmt *rd = 
stmt_reverse(stmt_dup(s->op2.stval));
-                                       stmt *re = stmt_join(r, rd, cmp_equal);
-                                       sql_subfunc *f = 
sql_bind_func(sql->session->schema, compare_func((comp_type)s->flag), 
tail_type(le), tail_type(le));
-                                       stmt * cmp;
-       
-                                       assert(f);
-
-                                       cmp = stmt_binop(le, re, f);
-                                       cmp = stmt_uselect(cmp, stmt_bool(1), 
cmp_equal);
-
-                                       l = stmt_semijoin(stmt_dup(l), 
stmt_dup(cmp));
-                                       r = stmt_semijoin(stmt_dup(r), cmp);
-                                       join = stmt_join(stmt_reverse(l), r, 
cmp_equal);
-                                       stmt_destroy(s);
-                               }
+                               join = stmt_reljoin(NULL, jns);
+                               list_destroy(eqjns);
                        }
+               } else {
+                       join = stmt_dup(jns->h->data); 
+                       list_destroy(jns);
                }
        } else {
                stmt *l = bin_first_column(left);

U sql_select.mx
Index: sql_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_select.mx,v
retrieving revision 1.236
retrieving revision 1.237
diff -u -d -r1.236 -r1.237
--- sql_select.mx       17 Jun 2008 10:35:11 -0000      1.236
+++ sql_select.mx       20 Jun 2008 20:50:31 -0000      1.237
@@ -894,14 +894,14 @@
                }
        }
        if (f) {
-               if (f->func->res.scale == SCALE_FIX) {
+               if (f->func->fix_scale == SCALE_FIX) {
                        ls = fix_scale(sql, t2, ls, 0, 0);
                        rs = fix_scale(sql, t1, rs, 0, 0);
-               } else if (f->func->res.scale == SCALE_SUB) {
+               } else if (f->func->fix_scale == SCALE_SUB) {
                        ls = scale_algebra(sql, f, ls, rs);
-               } else if (f->func->res.scale == SCALE_ADD) {
+               } else if (f->func->fix_scale == SCALE_ADD) {
                        ls = sum_scales(sql, f, ls, rs);
-               } else if (f->func->res.scale == DIGITS_ADD) {
+               } else if (f->func->fix_scale == DIGITS_ADD) {
                        f->res.digits = t1->digits + t2->digits;
                }
                return stmt_binop(ls, rs, f);
@@ -943,14 +943,14 @@
                        t2 = tail_type(rs);
                        f = sql_bind_func(s, fname, t1, t2);
                        if (f) {
-                               if (f->func->res.scale == SCALE_FIX) {
+                               if (f->func->fix_scale == SCALE_FIX) {
                                        ls = fix_scale(sql, t2, ls, 0, 0);
                                        rs = fix_scale(sql, t1, rs, 0, 0);
-                               } else if (f->func->res.scale == SCALE_SUB) {
+                               } else if (f->func->fix_scale == SCALE_SUB) {
                                        ls = scale_algebra(sql, f, ls, rs);
-                               } else if (f->func->res.scale == SCALE_ADD) {
+                               } else if (f->func->fix_scale == SCALE_ADD) {
                                        ls = sum_scales(sql, f, ls, rs);
-                               } else if (f->func->res.scale == DIGITS_ADD) {
+                               } else if (f->func->fix_scale == DIGITS_ADD) {
                                        f->res.digits = digits;
                                }
                                stmt_destroy(ols);


-------------------------------------------------------------------------
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