Changeset: 33d0aebde14c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=33d0aebde14c
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_optimizer.c
        sql/test/SQLancer/Tests/sqlancer01.stable.out
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 589 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
@@ -2183,6 +2183,89 @@ releqjoin( backend *be, list *l1, list *
        return res;
 }
 
+static void
+split_join_exps(sql_rel *rel, list *joinable, list *not_joinable)
+{
+       if (!list_empty(rel->exps)) {
+               for (node *n = rel->exps->h; n; n = n->next) {
+                       sql_exp *e = n->data;
+                       int left_reference = 0, right_reference = 0;
+
+                       /* we can handle thetajoins, rangejoins and filter 
joins (like) */
+                       /* ToDo how about in/notin, mark_in/notin, 
mark_exists/not_exists and atom expressions? */
+                       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) { /* theta and range 
joins */
+                                       /* join or select ? */
+                                       sql_exp *l = e->l, *r = e->r, *f = e->f;
+
+                                       if (l->card != CARD_ATOM) {
+                                               left_reference += 
rel_find_exp(rel->l, l) != NULL;
+                                               right_reference += 
rel_find_exp(rel->r, l) != NULL;
+                                       }
+                                       if (r->card != CARD_ATOM) {
+                                               left_reference += 
rel_find_exp(rel->l, r) != NULL;
+                                               right_reference += 
rel_find_exp(rel->r, r) != NULL;
+                                       }
+                                       if (f && f->card != CARD_ATOM) {
+                                               left_reference += 
rel_find_exp(rel->l, f) != NULL;
+                                               right_reference += 
rel_find_exp(rel->r, f) != NULL;
+                                       }
+                               } else if (flag == cmp_filter) {
+                                       list *l = e->l, *r = e->r;
+
+                                       for (node *n = l->h ; n ; n = n->next) {
+                                               sql_exp *ee = n->data;
+
+                                               if (ee->card != CARD_ATOM) {
+                                                       left_reference += 
rel_find_exp(rel->l, ee) != NULL;
+                                                       right_reference += 
rel_find_exp(rel->r, ee) != NULL;
+                                               }
+                                       }
+                                       for (node *n = r->h ; n ; n = n->next) {
+                                               sql_exp *ee = n->data;
+
+                                               if (ee->card != CARD_ATOM) {
+                                                       left_reference += 
rel_find_exp(rel->l, ee) != NULL;
+                                                       right_reference += 
rel_find_exp(rel->r, ee) != NULL;
+                                               }
+                                       }
+                               }
+                       }
+                       if (left_reference && right_reference) {
+                               append(joinable, e);
+                       } else {
+                               append(not_joinable, e);
+                       }
+               }
+       }
+}
+
+#define is_priority_exp(e) ((e)->type == e_cmp && (e)->flag == cmp_equal)
+
+static list *
+get_equi_joins_first(mvc *sql, list *exps, int *equality_only)
+{
+       list *new_exps = sa_list(sql->sa);
+
+       for( node *n = exps->h; n; n = n->next ) {
+               sql_exp *e = n->data;
+               if (is_priority_exp(e)) {
+                       list_append(new_exps, e);
+                       *equality_only &= (e->flag == cmp_equal);
+               }
+       }
+       for( node *n = exps->h; n; n = n->next ) {
+               sql_exp *e = n->data;
+               if (!is_priority_exp(e)) {
+                       list_append(new_exps, e);
+                       *equality_only &= (e->flag == mark_in || e->flag == 
mark_notin);
+               }
+       }
+       return new_exps;
+}
+
 static stmt *
 rel2bin_join(backend *be, sql_rel *rel, list *refs)
 {
@@ -2209,129 +2292,75 @@ rel2bin_join(backend *be, sql_rel *rel, 
         *      second selects/filters 
         */
        if (!list_empty(rel->exps)) {
-               int used_hash = 0;
-               int idx = 0, i;
                list *jexps = sa_list(sql->sa);
-               list *lje = sa_list(sql->sa);
-               list *rje = sa_list(sql->sa);
-               list *exps = sa_list(sql->sa);
                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;
-                               int left_reference = 0, right_reference = 0;
-
-                               /* we can handle thetajoins, rangejoins and 
filter joins (like) */
-                               /* ToDo how about in/notin, mark_in/notin, 
mark_exists/not_exists and atom expressions? */
-                               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) { /* theta and 
range joins */
-                                               /* join or select ? */
-                                               sql_exp *l = e->l, *r = e->r, 
*f = e->f;
-
-                                               if (l->card != CARD_ATOM) {
-                                                       left_reference += 
rel_find_exp(rel->l, l) != NULL;
-                                                       right_reference += 
rel_find_exp(rel->r, l) != NULL;
-                                               }
-                                               if (r->card != CARD_ATOM) {
-                                                       left_reference += 
rel_find_exp(rel->l, r) != NULL;
-                                                       right_reference += 
rel_find_exp(rel->r, r) != NULL;
-                                               }
-                                               if (f && f->card != CARD_ATOM) {
-                                                       left_reference += 
rel_find_exp(rel->l, f) != NULL;
-                                                       right_reference += 
rel_find_exp(rel->r, f) != NULL;
-                                               }
-                                       } else if (flag == cmp_filter) {
-                                               list *l = e->l, *r = e->r;
-
-                                               for (node *n = l->h ; n ; n = 
n->next) {
-                                                       sql_exp *ee = n->data;
-
-                                                       if (ee->card != 
CARD_ATOM) {
-                                                               left_reference 
+= rel_find_exp(rel->l, ee) != NULL;
-                                                               right_reference 
+= rel_find_exp(rel->r, ee) != NULL;
-                                                       }
-                                               }
-                                               for (node *n = r->h ; n ; n = 
n->next) {
-                                                       sql_exp *ee = n->data;
-
-                                                       if (ee->card != 
CARD_ATOM) {
-                                                               left_reference 
+= rel_find_exp(rel->l, ee) != NULL;
-                                                               right_reference 
+= rel_find_exp(rel->r, ee) != NULL;
-                                                       }
-                                               }
-                                       }
-                               }
-                               if (left_reference && right_reference) {
-                                       append(jexps, e);
-                               } else {
-                                       append(sexps, e);
-                               }
-                       }
-               }
-
+               split_join_exps(rel, jexps, sexps);
                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)
+               if (join) {
                        en = rel->exps->h;
-               else
+               } else {
+                       list *lje = sa_list(sql->sa), *rje = sa_list(sql->sa), 
*exps = sa_list(sql->sa);
+                       int used_hash = 0, idx = 0, equality_only = 1;
+
+                       (void) equality_only;
+                       jexps = get_equi_joins_first(sql, jexps, 
&equality_only);
                        /* 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;
-
-                       /* stop search for equi joins on first non equi */
-                       if (list_length(lje) && (idx || e->type != e_cmp || 
e->flag != cmp_equal))
-                               break;
-
-                       /* handle possible index lookups, expressions are in 
index order! */
-                       if (!join &&
-                           (p=find_prop(e->p, PROP_HASHCOL)) != NULL) {
-                               sql_idx *i = p->value;
-
-                               join = s = rel2bin_hash_lookup(be, rel, left, 
right, i, en);
-                               if (s) {
-                                       list_append(lje, s->op1);
-                                       list_append(rje, s->op2);
-                                       list_append(exps, NULL);
-                                       used_hash = 1;
+                       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;
+
+                               /* stop search for equi joins on first non equi 
*/
+                               if (list_length(lje) && (idx || e->type != 
e_cmp || e->flag != cmp_equal))
+                                       break;
+
+                               /* handle possible index lookups, expressions 
are in index order! */
+                               if (!join &&
+                                       (p=find_prop(e->p, PROP_HASHCOL)) != 
NULL) {
+                                       sql_idx *i = p->value;
+
+                                       join = s = rel2bin_hash_lookup(be, rel, 
left, right, i, en);
+                                       if (s) {
+                                               list_append(lje, s->op1);
+                                               list_append(rje, s->op2);
+                                               list_append(exps, NULL);
+                                               used_hash = 1;
+                                       }
                                }
+
+                               s = exp_bin(be, e, left, right, NULL, NULL, 
NULL, NULL, NULL, 0, 1);
+                               if (!s) {
+                                       assert(sql->session->status == -10); /* 
Stack overflow errors shouldn't terminate the server */
+                                       return NULL;
+                               }
+                               if (join_idx != sql->opt_stats[0])
+                                       idx = 1;
+                               assert(s->type == st_join || s->type == 
st_join2 || s->type == st_joinN);
+                               if (!join) 
+                                       join = s;
+                               if (e->flag != cmp_equal) { /* only collect 
equi joins */
+                                       en = en->next;
+                                       break;
+                               }
+                               list_append(lje, s->op1);
+                               list_append(rje, s->op2);
+                               list_append(exps, e);
                        }
-
-                       s = exp_bin(be, e, left, right, NULL, NULL, NULL, NULL, 
NULL, 0, 1);
-                       if (!s) {
-                               assert(sql->session->status == -10); /* Stack 
overflow errors shouldn't terminate the server */
-                               return NULL;
+                       if (list_length(lje) > 1) {
+                               join = releqjoin(be, lje, rje, exps, used_hash, 
cmp_equal, need_left, 0);
+                       } else if (!join) {
+                               sql_exp *e = exps->h->data;
+                               join = stmt_join(be, lje->h->data, 
rje->h->data, 0, cmp_equal, is_semantics(e), false);
+                               if (need_left)
+                                       join->flag = cmp_left;
                        }
-                       if (join_idx != sql->opt_stats[0])
-                               idx = 1;
-                       assert(s->type == st_join || s->type == st_join2 || 
s->type == st_joinN);
-                       if (!join) 
-                               join = s;
-                       if (e->flag != cmp_equal) { /* only collect equi joins 
*/
-                               en = en->next;
-                               break;
-                       }
-                       list_append(lje, s->op1);
-                       list_append(rje, s->op2);
-                       list_append(exps, e);
-               }
-               if (list_length(lje) > 1) {
-                       join = releqjoin(be, lje, rje, exps, used_hash, 
cmp_equal, need_left, 0);
-               } else if (!join) {
-                       sql_exp *e = exps->h->data;
-                       join = stmt_join(be, lje->h->data, rje->h->data, 0, 
cmp_equal, is_semantics(e), false);
-                       if (need_left)
-                               join->flag = cmp_left;
                }
        } else {
                stmt *l = bin_first_column(be, left);
@@ -2538,7 +2567,7 @@ static stmt *
 rel2bin_semijoin(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, *c, *lcand = 
NULL;
 
@@ -2559,117 +2588,108 @@ rel2bin_semijoin(backend *be, sql_rel *r
         *      second selects/filters 
         */
        if (!list_empty(rel->exps)) {
-               int idx = 0;
                list *jexps = sa_list(sql->sa);
-               list *lje = sa_list(sql->sa);
-               list *rje = sa_list(sql->sa);
-               list *exps = sa_list(sql->sa);
-               int equality_only = 1;
-
-               /* get equi-joins/filters first */
-               if (list_length(rel->exps) > 1) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to