Changeset: c3a8ef159903 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c3a8ef159903
Modified Files:
sql/backends/monet5/rel_bin.c
Branch: Jun2020
Log Message:
cleanup rel2bin_join, ie first split in list of join and select (+ too complex
mal-join cases)
diffs (truncated from 303 to 300 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -890,9 +890,9 @@ exp_bin(backend *be, sql_exp *e, stmt *l
for( n = args->h; n; n = n->next ) {
s = NULL;
if (!swapped)
- s = exp_bin(be, n->data, left, NULL,
grp, ext, cnt, NULL, NULL, depth+1, reduce);
+ s = exp_bin(be, n->data, left, NULL,
grp, ext, cnt, NULL, NULL, depth+1, 0);
if (!s && (first || swapped)) {
- s = exp_bin(be, n->data, right, NULL,
grp, ext, cnt, NULL, NULL, depth+1, reduce);
+ s = exp_bin(be, n->data, right, NULL,
grp, ext, cnt, NULL, NULL, depth+1, 0);
swapped = 1;
}
if (!s)
@@ -906,7 +906,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
ops = sa_list(sql->sa);
args = e->r;
for( n = args->h; n; n = n->next ) {
- s = exp_bin(be, n->data, (swapped ||
!right)?left:right, NULL, grp, ext, cnt, NULL, NULL, depth+1, reduce);
+ s = exp_bin(be, n->data, (swapped ||
!right)?left:right, NULL, grp, ext, cnt, NULL, NULL, depth+1, 0);
if (!s)
return s;
list_append(ops, s);
@@ -1016,27 +1016,27 @@ exp_bin(backend *be, sql_exp *e, stmt *l
sql->opt_stats[0]++;
if (!l) {
- l = exp_bin(be, e->l, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ l = exp_bin(be, e->l, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
swapped = 0;
}
if (!l && right) {
- l = exp_bin(be, e->l, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ l = exp_bin(be, e->l, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
swapped = 1;
}
if (swapped || !right)
- r = exp_bin(be, re, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ r = exp_bin(be, re, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
else
- r = exp_bin(be, re, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ r = exp_bin(be, re, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
if (!r && !swapped) {
- r = exp_bin(be, re, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ r = exp_bin(be, re, left, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
is_select = 1;
}
if (!r && swapped) {
- r = exp_bin(be, re, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ r = exp_bin(be, re, right, NULL, grp, ext, cnt, sel,
NULL, depth+1, 0);
is_select = 1;
}
if (re2)
- r2 = exp_bin(be, re2, left, right, grp, ext, cnt, sel,
NULL, depth+1, reduce);
+ r2 = exp_bin(be, re2, left, right, grp, ext, cnt, sel,
NULL, depth+1, 0);
if (!l || !r || (re2 && !r2)) {
TRC_ERROR(SQL_EXECUTION, "Query: '%s'\n", sql->query);
@@ -1066,7 +1066,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
}
} else {
if (r2) {
- if (depth || !reduce || (l->nrcols == 0 &&
r->nrcols == 0 && r2->nrcols == 0)) {
+ if (!reduce || (l->nrcols == 0 && r->nrcols ==
0 && r2->nrcols == 0)) {
sql_subtype *bt =
sql_bind_localtype("bit");
sql_subfunc *lf =
sql_bind_func(sql->sa, sql->session->schema,
compare_func(range2lcompare(e->flag), 0),
@@ -1109,7 +1109,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
}
} else {
/* value compare or select */
- if (depth || !reduce || (l->nrcols == 0 &&
r->nrcols == 0 && (e->flag == mark_in || e->flag == mark_notin))) {
+ if (!reduce || (l->nrcols == 0 && r->nrcols ==
0 && (e->flag == mark_in || e->flag == mark_notin))) {
sql_subfunc *f = sql_bind_func(sql->sa,
sql->session->schema, "=", tail_type(l), tail_type(l), F_FUNC);
assert(f);
s = stmt_binop(be, l, r, f);
@@ -2171,7 +2171,7 @@ static stmt *
rel2bin_join(backend *be, sql_rel *rel, list *refs)
{
mvc *sql = be->mvc;
- list *l;
+ list *l, *sexps = NULL;
node *en = NULL, *n;
stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr;
stmt *ld = NULL, *rd = NULL;
@@ -2199,86 +2199,91 @@ rel2bin_join(backend *be, sql_rel *rel,
list *lje = sa_list(sql->sa);
list *rje = sa_list(sql->sa);
list *exps = sa_list(sql->sa);
- char *handled = SA_ZNEW_ARRAY(sql->sa, char,
list_length(rel->exps));
-
- /* get equi-joins/filters first */
- if (list_length(rel->exps) > 1 || is_outerjoin(rel->op)) {
+ sexps = sa_list(sql->sa);
+
+ /* stage one split join and select expressions (include complex
expressions which physical layer cannot handle without a crossproduct first) */
+ if (!list_empty(rel->exps)) {
for( en = rel->exps->h, i=0; en; en = en->next, i++) {
sql_exp *e = en->data;
- if (e->type == e_cmp) {
- if (e->flag == cmp_equal &&
!((rel_find_exp(rel->l, e->l) && rel_find_exp(rel->l, e->r)) ||
(rel_find_exp(rel->r, e->l) && rel_find_exp(rel->r, e->r)))) {
- append(jexps, e);
- handled[i] = 1;
+ /* we can handle thetajoins, rangejoins and
filter joins (like) */
+ /* ToDo how about in/notin, mark_in/notin,
mark_exists/not_exists */
+ if (e->type <= e_cmp) {
+ int flag = e->flag & ~CMP_BETWEEN;
+ /* check if its a select or join
expression, ie use only expressions of one relation left and of the other right
(than join) */
+ if (flag <= cmp_filter && !e->f) { /*
theta join */
+ /* join or select ? */
+ if ((rel_find_exp(rel->l, e->l)
&& !rel_find_exp(rel->r, e->l) &&
+ rel_find_exp(rel->r, e->r)
&& !rel_find_exp(rel->l, e->r)) ||
+ (rel_find_exp(rel->r, e->l)
&& !rel_find_exp(rel->l, e->l) &&
+ rel_find_exp(rel->l, e->r)
&& !rel_find_exp(rel->r, e->r))) {
+ append(jexps, e);
+ continue;
+ }
+ } else if (flag <= cmp_filter && e->f)
{ /* range */
+ int nrcr = 0, nrcl = 0;
+ if ((rel_find_exp(rel->l, e->l)
&& !rel_find_exp(rel->r, e->l) &&
+ ((rel_find_exp(rel->r, e->r)
&& !rel_find_exp(rel->l, e->r)) || (nrcr += exp_is_atom(e->r))) &&
+ ((rel_find_exp(rel->r, e->f)
&& !rel_find_exp(rel->l, e->f)) || (nrcr += exp_is_atom(e->f))) && nrcr <= 1) ||
+ (rel_find_exp(rel->r, e->l)
&& !rel_find_exp(rel->l, e->l) &&
+ ((rel_find_exp(rel->l, e->r)
&& !rel_find_exp(rel->r, e->r)) || (nrcl += exp_is_atom(e->r))) &&
+ ((rel_find_exp(rel->l, e->f)
&& !rel_find_exp(rel->r, e->f)) || (nrcl += exp_is_atom(e->f))) && nrcl <= 1)) {
+ append(jexps, e);
+ continue;
+ }
} else if (e->flag == cmp_filter) {
+ int nrcl = 0, nrcr = 0;
bool fll = true, flr = true,
frl = true, frr = true;
-
- for (node *n = ((list*)e->l)->h
; n ; n = n->next) {
+ list *l = e->l, *r = e->r;
+
+ for (node *n = l->h ; n ; n =
n->next) {
sql_exp *ee = n->data;
fll &=
rel_find_exp(rel->l, ee) != NULL;
frl &=
rel_find_exp(rel->r, ee) != NULL;
+ nrcl += exp_is_atom(ee);
}
- for (node *n = ((list*)e->r)->h
; n ; n = n->next) {
+ for (node *n = r->h ; n ; n =
n->next) {
sql_exp *ee = n->data;
flr &=
rel_find_exp(rel->l, ee) != NULL;
frr &=
rel_find_exp(rel->r, ee) != NULL;
+ nrcr += exp_is_atom(ee);
}
- if (!((fll && flr) || (frl &&
frr))) {
+ if (!((fll && flr) || (frl &&
frr)) &&
+ nrcl < list_length(l) &&
nrcr < list_length(r)) {
append(jexps, e);
- handled[i] = 1;
+ continue;
}
+
}
+
}
+ append(sexps, e);
}
- if (list_empty(jexps)) {
- stmt *l = bin_first_column(be, left);
- stmt *r = bin_first_column(be, right);
- join = stmt_join(be, l, r, 0, cmp_all, 0,
false);
- }
- for( en = rel->exps->h, i=0; en; en = en->next, i++) {
- sql_exp *e = en->data;
- if (!handled[i])
- append(jexps, e);
- }
- rel->exps = jexps;
}
- /* generate a relational join */
+ if (list_empty(jexps)) { /* cross product and continue after
project */
+ stmt *l = bin_first_column(be, left);
+ stmt *r = bin_first_column(be, right);
+ join = stmt_join(be, l, r, 0, cmp_all, 0, false);
+ }
+
if (join)
en = rel->exps->h;
else
- for( en = rel->exps->h; en; en = en->next ) {
+ /* generate a relational join (releqjoin) which does a
multi attribute (equi) join */
+ for( en = jexps->h; en; en = en->next ) {
int join_idx = sql->opt_stats[0];
sql_exp *e = en->data;
stmt *s = NULL;
prop *p;
- /* only handle simple joins here */
- if ((exp_has_func(e) && e->flag != cmp_filter) ||
- e->flag == cmp_or || (e->f && e->anti) ||
- (e->type == e_cmp && e->flag == cmp_equal &&
- ((rel_find_exp(rel->l, e->l) &&
rel_find_exp(rel->l, e->r)) ||
- (rel_find_exp(rel->r, e->l) &&
rel_find_exp(rel->r, e->r)))) ) {
- if (!join && !list_length(lje)) {
- stmt *l = bin_first_column(be, left);
- stmt *r = bin_first_column(be, right);
- join = stmt_join(be, l, r, 0, cmp_all,
0, false);
- }
+ /* stop search for equi joins on first non equi */
+ if (list_length(lje) && (idx || e->type != e_cmp ||
e->flag != cmp_equal))
break;
- }
- if (list_length(lje) && (idx || e->type != e_cmp ||
(e->flag != cmp_equal && e->flag != cmp_filter) ||
- (join && e->flag == cmp_filter)))
- break;
- if (e->type == e_cmp && e->flag == cmp_equal &&
- ((rel_find_exp(rel->l, e->l) &&
rel_find_exp(rel->l, e->r)) ||
- (rel_find_exp(rel->r, e->l) &&
rel_find_exp(rel->r, e->r)))) {
- break;
- }
-
- /* handle possible index lookups */
- /* expressions are in index order ! */
+
+ /* handle possible index lookups, expressions are in
index order! */
if (!join &&
(p=find_prop(e->p, PROP_HASHCOL)) != NULL) {
sql_idx *i = p->value;
@@ -2303,8 +2308,11 @@ rel2bin_join(backend *be, sql_rel *rel,
if (s->type != st_join &&
s->type != st_join2 &&
s->type != st_joinN) {
+ assert(0);
+
/* predicate */
if (!list_length(lje) && s->nrcols == 0) {
+ assert(0);
stmt *l = bin_first_column(be, left);
stmt *r = bin_first_column(be, right);
@@ -2313,15 +2321,19 @@ rel2bin_join(backend *be, sql_rel *rel,
continue;
}
if (!join) {
+ assert(0);
stmt *l = bin_first_column(be, left);
stmt *r = bin_first_column(be, right);
join = stmt_join(be, l, r, 0, cmp_all,
0, false);
+ en = rel->exps->h;
}
break;
}
if (!join)
join = s;
+ if (e->flag != cmp_equal) /* only collect equi joins */
+ break;
list_append(lje, s->op1);
list_append(rje, s->op2);
list_append(exps, e);
@@ -2341,7 +2353,7 @@ rel2bin_join(backend *be, sql_rel *rel,
}
jl = stmt_result(be, join, 0);
jr = stmt_result(be, join, 1);
- if (en) {
+ if (en || (sexps && list_length(sexps))) {
stmt *sub, *sel = NULL;
list *nl;
@@ -2370,18 +2382,24 @@ rel2bin_join(backend *be, sql_rel *rel,
sub = stmt_list(be, nl);
/* continue with non equi-joins */
- for( ; en; en = en->next ) {
- stmt *s = exp_bin(be, en->data, sub, NULL, NULL, NULL,
NULL, sel, NULL, 0, 1);
-
- if (!s) {
- assert(sql->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
- return NULL;
+ while(sexps) {
+ if (!en) {
+ en = sexps->h;
+ sexps = NULL;
}
- if (s->nrcols == 0) {
- stmt *l = bin_first_column(be, sub);
- s = stmt_uselect(be, stmt_const(be, l,
stmt_bool(be, 1)), s, cmp_equal, sel, 0, 0);
+ for( ; en; en = en->next ) {
+ stmt *s = exp_bin(be, en->data, sub, NULL,
NULL, NULL, NULL, sel, NULL, 0, 1);
+
+ if (!s) {
+ assert(sql->session->status == -10); /*
Stack overflow errors shouldn't terminate the server */
+ return NULL;
+ }
+ if (s->nrcols == 0) {
+ stmt *l = bin_first_column(be, sub);
+ s = stmt_uselect(be, stmt_const(be, l,
stmt_bool(be, 1)), s, cmp_equal, sel, 0, 0);
+ }
+ sel = s;
}
- sel = s;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list