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

Modified Files:
        sql_optimize.mx sql_rel2bin.mx 
Log Message:
recognize more range joins (also improved stmt_intersect to handle changing
range joins into selects).


Index: sql_rel2bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_rel2bin.mx,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -d -r1.111 -r1.112
--- sql_rel2bin.mx      21 Dec 2007 17:02:25 -0000      1.111
+++ sql_rel2bin.mx      26 Dec 2007 13:24:41 -0000      1.112
@@ -31,9 +31,7 @@
 #include "sql_types.h"
 
 extern stmt *rel2bin(mvc *c, stmt *s);
-extern sql_column * basecolumn(stmt *st);
-extern stmt *head_column(stmt *st);
-extern stmt *tail_column(stmt *st);
+extern sql_column *basecolumn(stmt *st);
 
 #endif /* _SQL_REL2BIN_H */
 
@@ -45,8 +43,9 @@
 #include "sql_env.h"
 #include <stdio.h>
 
+static stmt * head_column(stmt *st);
 
-stmt *
+static stmt *
 tail_column(stmt *st)
 {
        switch (st->type) {
@@ -128,7 +127,7 @@
        }
 }
 
-stmt *
+static stmt *
 head_column(stmt *st)
 {
        switch (st->type) {

Index: sql_optimize.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_optimize.mx,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- sql_optimize.mx     25 Dec 2007 21:34:31 -0000      1.85
+++ sql_optimize.mx     26 Dec 2007 13:24:41 -0000      1.86
@@ -116,17 +116,83 @@
        return -1;
 }
 
+static stmt * headcolumn(stmt *st);
+
+static stmt *
+tailcolumn(stmt *st)
+{
+       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:
+               return tailcolumn(st->op2.lval->h->data);
+
+       case st_semijoin:
+               return tailcolumn(st->op1.stval);
+
+       case st_column:
+       case st_bat:
+               return st;
+       case st_reverse:
+               return headcolumn(st->op1.stval);
+       default:
+               return NULL;
+       }
+}
+
+static stmt *
+headcolumn(stmt *st)
+{
+       switch (st->type) {
+       case st_column:
+       case st_bat:
+               return st;
+       case st_reverse:
+               return tailcolumn(st->op1.stval);
+       case st_semijoin:
+               return headcolumn(st->op1.stval);
+       default:
+               return NULL;
+       }
+       return NULL;
+}
+
+/* getcolumn is used by rangejoin detection */
+static stmt *
+getcolumn(stmt *st)
+{
+       if (!st)
+               return NULL;    
+       switch (st->type) {
+       case st_reverse:
+               return getcolumn(headcolumn(st->op1.stval));
+       case st_pivot:
+               return getcolumn(st->op1.stval);
+       case st_bat:
+       case st_column:
+               return st;
+       default:
+               return getcolumn(tailcolumn(st));
+       }
+}
+
 static int
 cmp_matching_column( stmt *l, stmt *r)
 {
-       sql_column *lbc = basecolumn(l->op1.stval);
-       sql_column *rbc = basecolumn(r->op1.stval);
+       stmt *lc = getcolumn(l->op1.stval);
+       stmt *rc = getcolumn(r->op1.stval);
 
-       if (lbc && rbc && lbc == rbc)
+       if (lc && rc && lc == rc)
                return 0;
-       lbc = basecolumn(tail_column(l->op2.stval));
-       rbc = basecolumn(tail_column(r->op2.stval));
-       if (lbc && rbc && lbc == rbc)
+       lc = getcolumn(tailcolumn(l->op2.stval));
+       rc = getcolumn(tailcolumn(r->op2.stval));
+       if (lc && rc && lc == rc)
                return 0;
        return -1;
 }
@@ -309,25 +375,63 @@
         * 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);
-               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);
+               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(ml),
+                                       stmt_dup(op2->op1.stval), cmp_equal);
+                       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 *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);
+                       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 */
-               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 (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);
+               }
        }
 
        stmt_destroy(op1);
@@ -1110,8 +1214,8 @@
                        n = list_find(nqjoins, o1, (fcmp)&cmp_matching_column);
                        if (n) {
                                stmt *s, *o2 = stmt_dup(n->data);
-                               sql_column *o1bc = basecolumn(o1->op1.stval);
-                               sql_column *o2bc = basecolumn(o2->op1.stval);
+                               stmt *o1c = getcolumn(o1->op1.stval);
+                               stmt *o2c = getcolumn(o2->op1.stval);
                                int cmp = 0;
 
                                list_remove_node(nqjoins, n);
@@ -1131,7 +1235,7 @@
                                else
                                        assert(0);
        
-                               if (o1bc && o2bc && o1bc == o2bc) {
+                               if (o1c && o2c && o1c == o2c) {
                                        s = stmt_join2(
                                                stmt_dup(o1->op1.stval),
                                                
stmt_reverse(stmt_dup(o1->op2.stval)),
@@ -1147,9 +1251,13 @@
                                }
                                stmt_destroy(o1);
                                stmt_destroy(o2);
-                               o1 = s;
-                       } 
-                       list_append(rjoins, o1);
+
+                               /* prepend as 2 joins in one are hopefully 
+                               more restrictive then a single join */
+                               list_prepend(rjoins, s);
+                       }  else {
+                               list_append(rjoins, o1);
+                       }
                }
                if (list_length(rjoins)) {
                        if (list_length(nqjoins) == 1)


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
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