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