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