Changeset: 86d94f21e92c for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=86d94f21e92c
Modified Files:
sql/backends/monet5/sql.mx
sql/include/sql_relation.h
sql/server/rel_bin.c
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_select.c
sql/server/rel_select.h
sql/test/BugTracker-2011/Tests/jena-optional-1-test.Bug-2915.stable.out
sql/test/BugTracker-2012/Tests/All
sql/test/BugTracker-2012/Tests/innerjoin_subquery.Bug-3034.sql
sql/test/BugTracker-2012/Tests/innerjoin_subquery.Bug-3034.stable.err
sql/test/BugTracker-2012/Tests/innerjoin_subquery.Bug-3034.stable.out
sql/test/BugTracker-2012/Tests/outerjoin_predicate.Bug-2964.sql
sql/test/BugTracker-2012/Tests/outerjoin_predicate.Bug-2964.stable.err
sql/test/BugTracker-2012/Tests/outerjoin_predicate.Bug-2964.stable.out
sql/test/BugTracker-2012/Tests/outerjoin_select.Bug-2946.sql
sql/test/BugTracker-2012/Tests/outerjoin_select.Bug-2946.stable.err
sql/test/BugTracker-2012/Tests/outerjoin_select.Bug-2946.stable.out
sql/test/BugTracker-2012/Tests/rangejoin.Bug-3017.sql
sql/test/BugTracker-2012/Tests/rangejoin.Bug-3017.stable.err
sql/test/BugTracker-2012/Tests/rangejoin.Bug-3017.stable.out
Branch: Dec2011
Log Message:
fixed bugs 3034, 2964 2946 and 3017
The rel2bin_join didn't handle a bunch of corner cases
diffs (truncated from 840 to 300 lines):
diff --git a/sql/backends/monet5/sql.mx b/sql/backends/monet5/sql.mx
--- a/sql/backends/monet5/sql.mx
+++ b/sql/backends/monet5/sql.mx
@@ -1693,6 +1693,7 @@ sqlcleanup(mvc *c, int err)
if (err < 0)
c->session->status = err;
scanner_query_processed(&(c->scanner));
+ c->point_query = 0;
return err;
}
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -161,6 +161,12 @@ typedef enum operator_type {
(rel->op == op_ddl && rel->flag == DDL_OUTPUT)
#define is_outerjoin(op) \
(op == op_left || op == op_right || op == op_full)
+#define is_left(op) \
+ (op == op_left)
+#define is_right(op) \
+ (op == op_right)
+#define is_full(op) \
+ (op == op_full)
#define is_join(op) \
(op == op_join || is_outerjoin(op))
#define is_semi(op) \
diff --git a/sql/server/rel_bin.c b/sql/server/rel_bin.c
--- a/sql/server/rel_bin.c
+++ b/sql/server/rel_bin.c
@@ -899,39 +899,34 @@ rel2bin_join( mvc *sql, sql_rel *rel, li
}
if (join_idx != sql->opt_stats[0])
idx = 1;
- if (!join) {
+
+ if (s->type != st_join &&
+ s->type != st_join2 &&
+ s->type != st_joinN) {
+ /* predicate */
+ if (!list_length(jns) && s->nrcols == 0) {
+ stmt *l = bin_first_column(sql->sa,
left);
+ stmt *r = bin_first_column(sql->sa,
right);
+
+ l = stmt_uselect(sql->sa,
stmt_const(sql->sa, l, stmt_bool(sql->sa, 1)), s, cmp_equal);
+ join = stmt_join(sql->sa, l,
stmt_reverse(sql->sa, r), cmp_all);
+ continue;
+ }
+ if (!join) {
+ stmt *l = bin_first_column(sql->sa,
left);
+ stmt *r = bin_first_column(sql->sa,
right);
+ join = stmt_join(sql->sa, l,
stmt_reverse(sql->sa, r), cmp_all);
+ }
+ break;
+ }
+
+ if (!join)
join = s;
- /* stop on first non equality join */
- } else if (s->type != st_join &&
- s->type != st_join2 &&
- s->type != st_joinN) {
- if (s->type == st_reverse) {
- stmt *rs = s->op1;
-
- if (rs->type == st_join ||
- rs->type == st_join2 ||
- rs->type == st_joinN) {
- list_append(jns, s);
- continue;
- }
- }
- /* handle select expressions */
- /*assert(0);*/
- /* should be handled by join list (reljoin) */
- if (s->h == join->h) {
- join = stmt_semijoin(sql->sa, join,s);
- } else {
- join = stmt_reverse(sql->sa, join);
- join = stmt_semijoin(sql->sa, join,s);
- join = stmt_reverse(sql->sa, join);
- }
- continue;
- }
list_append(jns, s);
}
if (list_length(jns) > 1) {
join = stmt_releqjoin(sql->sa, jns);
- } else {
+ } else if (!join) {
join = jns->h->data;
}
} else {
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -781,7 +781,7 @@ exp_is_join(sql_exp *e)
{
/* only simple compare expressions, ie not or lists
or range expressions (e->f)
- */
+ */
if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r &&
!e->f && e->card >= CARD_AGGR && !complex_select(e))
return 0;
if (e->type == e_cmp && e->flag == cmp_filter && e->l && e->r &&
e->card >= CARD_AGGR)
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -834,7 +834,8 @@ order_joins(mvc *sql, list *rels, list *
/* complex expressions may touch multiple base tables
* Should be pushed up to extra selection.
* */
- if (cje->type != e_cmp || !is_complex_exp(cje->flag)) {
+ if (cje->type != e_cmp || !is_complex_exp(cje->flag) /*||
+ (cje->type == e_cmp && cje->f == NULL)*/) {
l = find_one_rel(rels, cje->l);
r = find_one_rel(rels, cje->r);
}
@@ -1294,7 +1295,10 @@ _exp_push_down(mvc *sql, sql_exp *e, sql
if (l && r && r2)
return exp_compare2(sql->sa, l, r, r2,
e->flag);
} else if (l && r) {
- return exp_compare(sql->sa, l, r, e->flag);
+ if (l->card < r->card)
+ return exp_compare(sql->sa, r, l,
swap_compare(e->flag));
+ else
+ return exp_compare(sql->sa, l, r,
e->flag);
}
}
return NULL;
@@ -2671,7 +2675,7 @@ rel_push_select_down_join(int *changes,
sql_exp *re = e->r;
if (re->card >= CARD_AGGR) {
- rel->l = rel_push_join(sql->sa, r,
e->l, re, e);
+ rel->l = rel_push_join(sql->sa, r,
e->l, re, NULL, e);
} else {
rel->l = rel_push_select(sql->sa, r,
e->l, e);
}
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1060,43 +1060,73 @@ rel_push_select(sql_allocator *sa, sql_r
join expression.
*/
sql_rel *
-rel_push_join(sql_allocator *sa, sql_rel *rel, sql_exp *ls, sql_exp *rs,
sql_exp *e)
+rel_push_join(sql_allocator *sa, sql_rel *rel, sql_exp *ls, sql_exp *rs,
sql_exp *rs2, sql_exp *e)
{
list *l = rel_bind_path(sa, rel, ls);
list *r = rel_bind_path(sa, rel, rs);
+ list *r2 = NULL;
node *ln, *rn;
- sql_rel *lrel = NULL, *rrel = NULL, *p = NULL;
-
- if (!l || !r)
+ sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL;
+
+ if (rs2)
+ r2 = rel_bind_path(sa, rel, rs2);
+ if (!l || !r || (rs2 && !r2))
return NULL;
p = rel;
- for (ln = l->h, rn = r->h; ln && rn; ln = ln->next, rn = rn->next ) {
- lrel = ln->data;
- rrel = rn->data;
-
- if (rel_is_ref(lrel) || rel_is_ref(rrel))
- break;
-
- /* push down as long as the operators allow this
- and the relation is equal.
- */
- if (lrel != rrel ||
+ if (r2) {
+ node *rn2;
+
+ for (ln = l->h, rn = r->h, rn2 = r2->h; ln && rn && rn2; ln =
ln->next, rn = rn->next, rn2 = rn2->next ) {
+ lrel = ln->data;
+ rrel = rn->data;
+ rrel2 = rn2->data;
+
+ if (rel_is_ref(lrel) || rel_is_ref(rrel) ||
rel_is_ref(rrel2))
+ break;
+
+ /* push down as long as the operators allow this
+ and the relation is equal.
+ */
+ if (lrel != rrel || lrel != rrel2 ||
(!is_select(lrel->op) &&
!(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
lrel->op != op_join &&
lrel->op != op_left))
- break;
- /* pushing through left head of a left join is allowed */
- if (lrel->op == op_left && (!ln->next || lrel->l !=
ln->next->data))
- break;
- p = lrel;
- }
- if (!lrel || !rrel)
+ break;
+ /* pushing through left head of a left join is allowed
*/
+ if (lrel->op == op_left && (!ln->next || lrel->l !=
ln->next->data))
+ break;
+ p = lrel;
+ }
+ } else {
+ for (ln = l->h, rn = r->h; ln && rn; ln = ln->next, rn =
rn->next ) {
+ lrel = ln->data;
+ rrel = rn->data;
+
+ if (rel_is_ref(lrel) || rel_is_ref(rrel))
+ break;
+
+ /* push down as long as the operators allow this
+ and the relation is equal.
+ */
+ if (lrel != rrel ||
+ (!is_select(lrel->op) &&
+ !(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
+ lrel->op != op_join &&
+ lrel->op != op_left))
+ break;
+ /* pushing through left head of a left join is allowed
*/
+ if (lrel->op == op_left && (!ln->next || lrel->l !=
ln->next->data))
+ break;
+ p = lrel;
+ }
+ }
+ if (!lrel || !rrel || (r2 && !rrel2))
return NULL;
/* filter on columns of this relation */
- if ((lrel == rrel && lrel->op != op_join) || rel_is_ref(p)) {
+ if ((lrel == rrel && (!r2 || lrel == rrel2) && lrel->op != op_join) ||
rel_is_ref(p)) {
if (lrel->op == op_select && !rel_is_ref(lrel)) {
rel_select_add_exp(lrel, e);
} else if (p && p->op == op_select && !rel_is_ref(p)) {
@@ -2115,7 +2145,7 @@ rel_filter_exp_(mvc *sql, sql_rel *rel,
return rel;
}
/* push join into the given relation */
- return rel_push_join(sql->sa, rel, L, R, e);
+ return rel_push_join(sql->sa, rel, L, R, rs2, e);
}
}
@@ -2166,8 +2196,20 @@ rel_compare_exp_(mvc *sql, sql_rel *rel,
return rel_select(sql->sa, rel, e);
if (/*is_semi(rel->op) ||*/ is_outerjoin(rel->op)) {
- rel_join_add_exp(sql->sa, rel, e);
- return rel;
+ if ((is_left(rel->op) || is_full(rel->op)) &&
rel_find_exp(rel->l, ls)) {
+ rel_join_add_exp(sql->sa, rel, e);
+ return rel;
+ } else if ((is_right(rel->op) || is_full(rel->op)) &&
rel_find_exp(rel->r, ls)) {
+ rel_join_add_exp(sql->sa, rel, e);
+ return rel;
+ }
+ if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
+ rel->r = rel_push_select(sql->sa, rel->r, L, e);
+ return rel;
+ } else if (is_right(rel->op) && rel_find_exp(rel->l,
ls)) {
+ rel->l = rel_push_select(sql->sa, rel->l, L, e);
+ return rel;
+ }
}
/* push select into the given relation */
return rel_push_select(sql->sa, rel, L, e);
@@ -2177,7 +2219,7 @@ rel_compare_exp_(mvc *sql, sql_rel *rel,
return rel;
}
/* push join into the given relation */
- return rel_push_join(sql->sa, rel, L, R, e);
+ return rel_push_join(sql->sa, rel, L, R, rs2, e);
}
}
diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h
--- a/sql/server/rel_select.h
+++ b/sql/server/rel_select.h
@@ -58,7 +58,7 @@ extern sql_rel *rel_crossproduct(sql_all
extern void rel_join_add_exp(sql_allocator *sa, sql_rel *rel, sql_exp *e);
extern sql_rel *rel_push_select(sql_allocator *sa, sql_rel *rel, sql_exp *ls,
sql_exp *e);
-extern sql_rel *rel_push_join(sql_allocator *sa, sql_rel *rel, sql_exp *ls,
sql_exp *rs, sql_exp *e);
+extern sql_rel *rel_push_join(sql_allocator *sa, sql_rel *rel, sql_exp *ls,
sql_exp *rs, sql_exp *rs2, sql_exp *e);
/* TODO rename to exp_check_type + move to rel_exp.mx */
extern sql_exp *rel_check_type(mvc *sql, sql_subtype *t, sql_exp *exp, int
tpe);
extern int rel_convert_types(mvc *sql, sql_exp **L, sql_exp **R, int
scale_fixing, int tpe);
diff --git
a/sql/test/BugTracker-2011/Tests/jena-optional-1-test.Bug-2915.stable.out
b/sql/test/BugTracker-2011/Tests/jena-optional-1-test.Bug-2915.stable.out
--- a/sql/test/BugTracker-2011/Tests/jena-optional-1-test.Bug-2915.stable.out
+++ b/sql/test/BugTracker-2011/Tests/jena-optional-1-test.Bug-2915.stable.out
@@ -98,12 +98,8 @@ Ready.
% .r_1, .r_1, .r_1, .r_1, .r_2, .r_2, .r_2, .r_2 #
table_name
% v_1_lex, v_1_datatype, v_1_lang, v_1_type, v_2_lex,
v_2_datatype, v_2_lang, v_2_type # name
% clob, varchar, varchar, int, clob, varchar,
varchar, int # type
-% 16, 0, 0, 1, 16, 40, 0, 1 # length
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list