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

Modified Files:
        rel_bin.mx rel_dump.mx rel_exp.mx rel_optimizer.mx 
        rel_select.mx 
Log Message:
rel optimizer detects more join indices (problem was caused by aliased columns)
Approved output after select->uselect changes


Index: rel_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_select.mx,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- rel_select.mx       6 Mar 2008 08:36:00 -0000       1.67
+++ rel_select.mx       8 Mar 2008 07:27:02 -0000       1.68
@@ -168,6 +168,17 @@
        return NULL;
 }
 
+static sql_exp*
+exp_label( sql_exp *e, int nr)
+{
+       char name[16], *nme;
+
+       nme = number2name(name, 16, nr);
+       assert(e->name == NULL);
+       e->name = _strdup(nme);
+       return e;
+}
+
 static void
 rel_label( sql_rel *r, int nr)
 {
@@ -2237,7 +2248,7 @@
                                if (z) {
                                        rl = z;
                                } else {
-                                       rl = rel_project_exp(r);
+                                       rl = rel_project_exp(exp_label(r, 
++sql->label));
                                }
                                if (right) {
                                        rl = rel_setop(right, rl, op_union);

Index: rel_exp.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_exp.mx,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- rel_exp.mx  25 Feb 2008 19:07:43 -0000      1.7
+++ rel_exp.mx  8 Mar 2008 07:27:01 -0000       1.8
@@ -478,6 +478,16 @@
                        if (rel->exps && exps_bind_column(rel->exps, e->r)) 
                                ne = e;
                        break;
+               case op_union:
+               case op_except:
+               case op_inter:
+               {
+                       if (rel->l)
+                               ne = rel_find_exp(rel->l, e);
+                       else if (rel->exps)
+                               ne = exps_bind_column(rel->exps, e->r);
+               }
+               break;
                case op_basetable: 
                {
                        sql_table *t = rel->l;
@@ -502,6 +512,7 @@
                        }
                        break;
                }
+               
                default:
                        if (!is_project(rel->op) && rel->l)
                                ne = rel_find_exp(rel->l, e);

Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- rel_optimizer.mx    25 Feb 2008 19:07:43 -0000      1.11
+++ rel_optimizer.mx    8 Mar 2008 07:27:01 -0000       1.12
@@ -271,31 +271,6 @@
 }
 
 static void
-cond_append( list *l, char *n)
-{
-       if (n) {
-               if (!list_find(l,n,(fcmp)strcmp))
-                       append(l,n);
-       }
-}
-
-static list *
-relation_names(list *exps) 
-{
-       node *n;
-       list *l = list_create(NULL);
-
-       for(n = exps->h; n; n = n->next) {
-               sql_exp *e = n->data;
-               if (e->type == e_cmp) {
-                       cond_append(l, exp_find_rel_name(e->l));
-                       cond_append(l, exp_find_rel_name(e->r));
-               }
-       }
-       return l;
-}
-
-static void
 get_relations(sql_rel *rel, list *rels)
 {
        if (rel->op == op_join) {
@@ -349,26 +324,6 @@
        return cnt;
 }
 
-/* return matching relation */
-static int 
-matching_rel(sql_rel *r, sql_exp *je) 
-{
-       if (je->type == e_cmp) {
-               char *name = exp_find_rel_name(je->l);
-               if (name && r->name && strcmp(name,r->name) == 0)
-                       return 0; 
-               name = exp_find_rel_name(je->r);
-               if (name && r->name && strcmp(name,r->name) == 0)
-                       return 0; 
-       } 
-       if (je->type == e_column) {
-               char *name = exp_find_rel_name(je);
-               if (name && r->name && strcmp(name,r->name) == 0)
-                       return 0; 
-       }
-       return -1;
-}
-
 static int
 rel_has_exp(sql_rel *rel, sql_exp *e) 
 {
@@ -404,11 +359,10 @@
 }
 
 static sql_exp *
-joinexp_col(sql_exp *e, char *rel_name)
+joinexp_col(sql_exp *e, sql_rel *r)
 {
        if (e->type == e_cmp) {
-               char *rname = exp_find_rel_name(e->l);
-               if (rname && strcmp(rname, rel_name) == 0)
+               if (rel_has_exp(r, e->l) >= 0) 
                        return exp_dup(e->l);
                return exp_dup(e->r);
        }
@@ -417,12 +371,23 @@
 }
 
 static sql_column *
-table_colexp(sql_exp *e, sql_table *t)
+table_colexp(sql_exp *e, sql_rel *r)
 {
+       sql_table *t = r->l;
+
        if (e->type == e_column) {
                char *name = e->name;
                node *cn;
 
+               if (r->exps) { /* use alias */
+                       for (cn = r->exps->h; cn; cn = cn->next) {
+                               sql_exp *ce = cn->data;
+                               if (strcmp(ce->name, name) == 0) {
+                                       name = ce->r;
+                                       break;
+                               }
+                       }
+               }
                for (cn = t->columns.set->h; cn; cn = cn->next) {
                        sql_column *c = cn->data;
                        if (strcmp(c->base.name, name) == 0) 
@@ -432,55 +397,6 @@
        return NULL;
 }
 
-
-static int
-relation_name( sql_rel *r, char *name) 
-{
-       if (r->name && strcmp(r->name, name) == 0)
-               return 0;
-       return -1;
-}
-
-static sql_table *
-rel_find_table(sql_rel *rel)
-{
-       switch(rel->op) {
-       case op_basetable: 
-               return rel->l;
-       case op_table:
-
-       case op_join: 
-       case op_left: 
-       case op_right: 
-       case op_full: 
-
-       case op_semi: 
-       case op_anti: 
-               return NULL;
-
-       case op_select: 
-       case op_union: 
-       case op_inter: 
-       case op_except: 
-       case op_topn: 
-
-       case op_project:
-       case op_groupby: 
-               if (rel->l)
-                       return rel_find_table(rel->l);
-       }
-       return NULL;
-}
-
-static sql_table *
-find_table(list *rels, char *rel_name)
-{
-       node *n = list_find(rels, rel_name, (fcmp)&relation_name);
-       if (n) 
-               return rel_find_table(n->data);
-       return NULL;
-}
-
 static int
 exp_joins_rels(sql_exp *e, list *rels)
 {
@@ -547,6 +463,21 @@
 }
 
 static sql_rel *
+find_basetable( sql_rel *r)
+{
+       if (!r)
+               return NULL;
+       switch(r->op) {
+       case op_basetable:      
+               return r;
+       case op_select:
+               return find_basetable(r->l);
+       default:
+               return NULL;
+       }
+}
+
+static sql_rel *
 order_joins(list *rels, list *exps)
 {
        sql_rel *top = NULL, *l, *r;
@@ -568,22 +499,27 @@
                        int swapped = 0;
                        list *aaje = matching_joins(rels, aje, je);
                        list *eje = list_select(aaje, (void*)1, (fcmp) 
&exp_is_eqjoin, (fdup) &exp_dup);
+                       sql_rel *lr = find_rel(rels, le);
+                       sql_rel *rr = find_rel(rels, re);
 
-                       char *lname = exp_find_rel_name(le);
-                       char *rname = exp_find_rel_name(re);
-                       list *lexps = list_map(eje, lname, (fmap) &joinexp_col);
-                       list *rexps = list_map(eje, rname, (fmap) &joinexp_col);
-                       sql_table *l = find_table(rels, lname);
-                       sql_table *r = find_table(rels, rname);
+                       sql_table *l, *r;
+                       list *lexps = list_map(eje, lr, (fmap) &joinexp_col);
+                       list *rexps = list_map(eje, rr, (fmap) &joinexp_col);
                        list *lcols, *rcols;
 
-                       if (!l || !r) {
+                       lr = find_basetable(lr);
+                       rr = find_basetable(rr);
+                       if (!lr || !rr) {
                                list_destroy(lexps);
                                list_destroy(rexps);
+                               list_destroy(eje);
+                               list_destroy(aaje);
                                continue;
                        }
-                       lcols = list_map(lexps, l, (fmap) &table_colexp);
-                       rcols = list_map(rexps, r, (fmap) &table_colexp);
+                       l = lr->l;
+                       r = rr->l;
+                       lcols = list_map(lexps, lr, (fmap) &table_colexp);
+                       rcols = list_map(rexps, rr, (fmap) &table_colexp);
                        list_destroy(lexps);
                        list_destroy(rexps);
                        if (list_length(lcols) != list_length(rcols)) {
@@ -591,6 +527,8 @@
                                rcols->destroy = NULL;
                                list_destroy(lcols);
                                list_destroy(rcols);
+                               list_destroy(eje);
+                               list_destroy(aaje);
                                continue;
                        }
 
@@ -680,8 +618,8 @@
                        node *ln, *rn, *en;
                        
                        cje = djn->data;
-                       ln = list_find(n_rels, cje->l, (fcmp)&matching_rel);
-                       rn = list_find(n_rels, cje->r, (fcmp)&matching_rel);
+                       ln = list_find(n_rels, cje->l, (fcmp)&rel_has_exp);
+                       rn = list_find(n_rels, cje->r, (fcmp)&rel_has_exp);
 
                        if (ln || rn) {
                                /* remove the expression from the lists */
@@ -754,6 +692,7 @@
        get_relations(rel, rels);
 
 #ifdef DEBUG
+printf("SPLIT RELATIONS\n");
        for(n = rels->h; n; n = n->next) 
                rel_print(sql, n->data, 0);
 #endif
@@ -792,56 +731,17 @@
 static sql_rel *
 rel_join_order(mvc *sql, sql_rel *rel) 
 {
-       if (rel->op == op_join) {
-               if (rel->exps) {
-                       /* use other (sub) relation count */
-                       list *rels = relation_names(rel->exps);
-                       int len = list_length(rels);
-                       switch(len) {
-                       case 0: 
-                       case 1: /* crosstables */
-                               /* also column refs fall into this because 
-                                  they have no relation names */
-#ifdef DEBUG
-                               rel_print(sql, rel, 0);
-#endif
-                               break;
-#ifdef DEBUG_2
-                       case 2:
-                               printf("%d\n", len);
-                               for(n = rels->h; n; n = n->next) 
-                                       printf(" %s", (char*)n->data);
-                               printf("\n");
-                               list_destroy(rels);
-                               return rel;
-#endif
-                       default: 
-                               /* lets try too rewrite */
+       if (rel->op == op_join && rel->exps) {
 #ifdef DEBUG
-                               rel_print(sql, rel, 0);
-
-                               printf("%d", len);
-                               if (len) {
-                                       node *n;
-
-                                       for(n = rels->h; n; n = n->next) 
-                                               printf(" %s", (char*)n->data);
-                               }
-                               printf("\n");
+printf("BEFORE\n");
+               rel_print(sql, rel, 0);
 #endif
-
-                               rel->exps = push_up_join_exps(rel);
-                               rel = reorder_join(sql, rel);
-
+               rel->exps = push_up_join_exps(rel);
+               rel = reorder_join(sql, rel);
 #ifdef DEBUG
-                               rel_print(sql, rel, 0);
+printf("AFTER\n");
+               rel_print(sql, rel, 0);
 #endif
-                               break;
-                       }
-                       list_destroy(rels);
-                       return rel;
-               }
-               return rel;
        }
        return rel;
 }
@@ -966,7 +866,7 @@
        return NULL;
 }
 
-static sql_rel *
+sql_rel *
 rel_push_select_down(mvc *sql, sql_rel *rel) 
 {
        //sql_rel *rr, *rl;
@@ -1163,9 +1063,12 @@
 
        /* TODO add optimizer which removes unions 
                (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_join])
                rel = rewrite(sql, rel, &rel_join_order); 

Index: rel_dump.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_dump.mx,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- rel_dump.mx 25 Feb 2008 19:07:43 -0000      1.24
+++ rel_dump.mx 8 Mar 2008 07:27:00 -0000       1.25
@@ -141,7 +141,7 @@
        default:
                ;
        }
-       if (is_ascending(e))
+       if (e->type != e_atom && is_ascending(e))
                printf(" ASC");
        if (e->name && alias) {
                printf(" as ");
@@ -310,7 +310,7 @@
                        printf(" as %s", rel->name);
                break;
        default:
-               printf("todo: print %u\n", rel->op);
+               assert(0);
        }
        if (!depth)
                printf("\n");

Index: rel_bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_bin.mx,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- rel_bin.mx  6 Mar 2008 08:36:00 -0000       1.36
+++ rel_bin.mx  8 Mar 2008 07:27:00 -0000       1.37
@@ -275,7 +275,7 @@
         }      break;
        case e_cmp: {
                stmt *l = NULL, *r = NULL;
-               int swapped = 0;
+               int swapped = 0, sel = 0;
                sql_exp *re = e->r;
                prop *p;
 
@@ -339,13 +339,17 @@
                        r = exp_bin(sql, e->r, left, NULL, grp);
                else
                        r = exp_bin(sql, e->r, right, NULL, grp);
+               if (!r && !swapped) {
+                       r = exp_bin(sql, e->r, left, NULL, grp);
+                       sel = 1;
+               }
                if (!l || !r) {
                        assert(0);
                        if (l) stmt_destroy(l);
                        if (r) stmt_destroy(r);
                        return NULL;
                }
-               if (left && right && re->card > CARD_ATOM) {
+               if (left && right && re->card > CARD_ATOM && !sel) {
                        if (l->nrcols == 0)
                                l = 
stmt_const(bin_first_column(swapped?right:left), l); 
                        if (r->nrcols == 0)
@@ -534,6 +538,15 @@
                        }
                        if (!join) {
                                join = s;
+                       } else if (s->type != st_join) {
+                               /* handle select expressions */
+                               if (s->h == join->h) {
+                                       join = stmt_semijoin(join,s);
+                               } else {
+                                       join = stmt_reverse(join);
+                                       join = stmt_semijoin(join,s);
+                                       join = stmt_reverse(join);
+                               }
                        } else {
                                /* break column join */
                                stmt *l = stmt_mark(stmt_reverse(join), 100);


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins

Reply via email to