Changeset: b72b05357cdd for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b72b05357cdd
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
        sql/test/BugTracker-2016/Tests/case-column-when-null-Bug-6124.stable.out
        
sql/test/BugTracker-2016/Tests/nested-subquery-in-select.Bug-6125.stable.out
        sql/test/BugTracker-2016/Tests/select-in-from.Bug-6121.stable.out
Branch: Dec2016
Log Message:

fixes for bugs 6124, 6125 and 6121
The apply rename optimizer step has been rewriten.
Apply optimizer now create new relational operators (doesn't steal
the structures, ie safe against referenced subqueries).


diffs (truncated from 1543 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
@@ -1898,8 +1898,10 @@ rel2bin_semijoin( mvc *sql, sql_rel *rel
                                break;
 
                        s = exp_bin(sql, en->data, left, right, NULL, NULL, 
NULL, NULL);
-                       if (!s) 
+                       if (!s) {
+                               assert(0);
                                return NULL;
+                       }
                        if (join_idx != sql->opt_stats[0])
                                idx = 1;
                        /* stop on first non equality join */
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
@@ -631,6 +631,13 @@ exp_label(sql_allocator *sa, sql_exp *e,
        return e;
 }
 
+sql_exp*
+exp_label_table(sql_allocator *sa, sql_exp *e, int nr)
+{
+       e->rname = make_label(sa, nr);
+       return e;
+}
+
 void
 exp_swap( sql_exp *e ) 
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -86,6 +86,7 @@ extern void exp_setrelname(sql_allocator
 extern void noninternexp_setname(sql_allocator *sa, sql_exp *e, const char 
*rname, const char *name );
 extern char* make_label(sql_allocator *sa, int nr);
 extern sql_exp* exp_label(sql_allocator *sa, sql_exp *e, int nr);
+extern sql_exp* exp_label_table(sql_allocator *sa, sql_exp *e, int nr);
 
 extern sql_exp * exp_copy( sql_allocator *sa, sql_exp *e);
 extern list * exps_copy( sql_allocator *sa, list *exps);
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
@@ -4237,18 +4237,20 @@ rel_push_semijoin_down(int *changes, mvc
                        if (!right && !left)
                                return rel;
                } 
-               nsexps = rel->exps;
-               njexps = l->exps;
+               nsexps = exps_copy(sql->sa, rel->exps);
+               njexps = exps_copy(sql->sa, l->exps);
                if (right)
-                       l = rel_crossproduct(sql->sa, ll, r, op);
+                       l = rel_crossproduct(sql->sa, rel_dup(ll), rel_dup(r), 
op);
                else
-                       l = rel_crossproduct(sql->sa, lr, r, op);
+                       l = rel_crossproduct(sql->sa, rel_dup(lr), rel_dup(r), 
op);
                l->exps = nsexps;
                if (right)
-                       rel = rel_crossproduct(sql->sa, l, lr, lop);
+                       l = rel_crossproduct(sql->sa, l, rel_dup(lr), lop);
                else
-                       rel = rel_crossproduct(sql->sa, l, ll, lop);
-               rel->exps = njexps;
+                       l = rel_crossproduct(sql->sa, l, rel_dup(ll), lop);
+               l->exps = njexps;
+               rel_destroy(rel);
+               rel = l;
        }
        return rel;
 }
@@ -5908,34 +5910,46 @@ rel_remove_unused(mvc *sql, sql_rel *rel
        return rel;
 }
 
-static void
-rel_dce_refs(mvc *sql, sql_rel *rel, list *refs) 
-{
+static list *
+merge_refs(list *l, list *r)
+{
+       node *n, *m, *np = l->h, *mp = r->h;
+       list *nl = sa_list(l->sa);
+
+       for( n = np; n; n = n->next) {
+               sql_rel *lr = n->data;
+               for (m = mp; m; m = m->next) {
+                       sql_rel *rr = m->data;
+
+                       if (lr == rr) {
+                               for( ; np != n; np = np->next) 
+                                       append(nl, np->data);
+                               np = np->next;
+                               for( ; mp != m; mp = mp->next) 
+                                       append(nl, mp->data);
+                               append(nl, mp->data); 
+                               mp = mp->next;
+                               break;
+                       }
+               }
+       }
+       for( ; np; np = np->next) 
+               append(nl, np->data);
+       for( ; mp; mp = mp->next) 
+               append(nl, mp->data);
+       return nl;
+}
+
+static list *
+rel_dce_refs(mvc *sql, sql_rel *rel) 
+{
+       list *l = NULL, *r = NULL;
+
        if (!rel)
-               return ;
-
-       if (rel_is_ref(rel)) {
-               if (!list_find(refs, rel, NULL))
-                       list_append(refs, rel);
-       }
+               return NULL;
 
        switch(rel->op) {
-       case op_basetable:
        case op_table:
-
-               if (rel->l && rel->op == op_table)
-                       rel_dce_refs(sql, rel->l, refs);
-       case op_insert:
-       case op_ddl:
-               break;
-
-       case op_update:
-       case op_delete:
-
-               if (rel->r)
-                       rel_dce_refs(sql, rel->r, refs);
-               break;
-
        case op_topn: 
        case op_sample: 
        case op_project:
@@ -5943,9 +5957,21 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis
        case op_select: 
 
                if (rel->l)
-                       rel_dce_refs(sql, rel->l, refs);
+                       l = rel_dce_refs(sql, rel->l);
+
+       case op_basetable:
+       case op_insert:
+       case op_ddl:
                break;
 
+       case op_update:
+       case op_delete:
+
+               if (rel->r)
+                       r = rel_dce_refs(sql, rel->r);
+               break;
+
+
        case op_union: 
        case op_inter: 
        case op_except: 
@@ -5957,14 +5983,25 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis
        case op_anti: 
 
                if (rel->l)
-                       rel_dce_refs(sql, rel->l, refs);
+                       l = rel_dce_refs(sql, rel->l);
                if (rel->r)
-                       rel_dce_refs(sql, rel->r, refs);
+                       r = rel_dce_refs(sql, rel->r);
                break;
 
        case op_apply: 
                assert(0);
        }
+
+       if (l && r)
+               l = merge_refs(l, r);
+       if (!l) 
+               l = r;
+       if (rel_is_ref(rel)) {
+               if (!l)
+                       l = sa_list(sql->sa);
+               list_prepend(l, rel);
+       }
+       return l;
 }
 
 static sql_rel *
@@ -6142,16 +6179,17 @@ rel_add_projects(mvc *sql, sql_rel *rel)
 sql_rel *
 rel_dce(mvc *sql, sql_rel *rel)
 {
-       list *refs = sa_list(sql->sa);
+       list *refs;
        node *n;
 
-       rel_dce_refs(sql, rel, refs);
+       refs = rel_dce_refs(sql, rel);
        rel = rel_add_projects(sql, rel);
        rel_used(rel);
        rel_dce_sub(sql, rel, refs);
 
-       for (n = refs->h; n; n = n->next)
-               rel_dce_sub(sql, n->data, refs);
+       if (refs)
+               for (n = refs->h; n; n = n->next)
+                       rel_dce_sub(sql, n->data, refs);
        return rel;
 }
 
@@ -7736,9 +7774,9 @@ exps_uses_exps(list *users, list *exps)
 static int
 rel_uses_exps(sql_rel *rel, list *exps )
 {
-       if (!exps || !rel || !rel->l)
+       if (!exps || !rel)
                return 0;
-       if (rel->exps && exps_uses_exps(rel->exps, exps)) 
+       if (rel->op == op_project && !rel->l && rel->exps && 
exps_uses_exps(rel->exps, exps)) 
                return 1;
        switch(rel->op) {
        case op_basetable:
@@ -7777,11 +7815,10 @@ rel_uses_exps(sql_rel *rel, list *exps )
        return 0;
 }
 
-/* exp_rename_up */
-static sql_exp * exp_rename_up(mvc *sql, sql_exp *e, list *aliases);
+static sql_exp * exp_apply_rename(mvc *sql, sql_exp *e, list *aliases, int 
always);
 
 static list *
-exps_rename_up(mvc *sql, list *l, list *aliases) 
+exps_apply_rename(mvc *sql, list *l, list *aliases, int always) 
 {
        node *n;
        list *nl = new_exp_list(sql->sa);
@@ -7791,33 +7828,34 @@ exps_rename_up(mvc *sql, list *l, list *
        for(n=l->h; n; n=n->next) {
                sql_exp *arg = n->data, *narg;
 
-               narg = exp_rename_up(sql, arg, aliases);
+               narg = exp_apply_rename(sql, arg, aliases, always);
                if (!narg) 
-                       return NULL;
+                       narg = arg;
                narg->flag = arg->flag;
                append(nl, narg);
        }
        return nl;
 }
 
-/* exp_rename_up, rename an expression to use an alias */
 static sql_exp *
-exp_rename_up(mvc *sql, sql_exp *e, list *aliases) 
-{
-       sql_exp *ne = NULL, *l, *r, *r2;
+exp_apply_rename(mvc *sql, sql_exp *e, list *aliases, int setname) 
+{
+       sql_exp *ne = NULL, *l;
 
        switch(e->type) {
        case e_column:
                ne = exps_bind_alias(aliases, e->l, e->r);
-               if (ne)
-                       ne = exp_column(sql->sa, exp_relname(ne), exp_name(ne), 
exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne));
-               else
-                       return e;
+               if (ne && ne->used && !setname) {
+                       ne = exp_column(sql->sa, exp_relname(ne), exp_name(ne), 
exp_subtype(e), e->card, has_nil(e), is_intern(e));
+                       if (e && e->rname && e->rname[0] == 'L')
+                               exp_setname(sql->sa, ne, e->rname, e->name);
+               } else if (ne && !ne->used)
+                       ne = NULL;
                break;
        case e_cmp: 
                if (e->flag == cmp_or || get_cmp(e) == cmp_filter) {
-                       list *l = exps_rename_up(sql, e->l, aliases);
-                       list *r = exps_rename_up(sql, e->r, aliases);
+                       list *l = exps_apply_rename(sql, e->l, aliases, 
setname);
+                       list *r = exps_apply_rename(sql, e->r, aliases, 
setname);
                        if (l && r) {
                                if (get_cmp(e) == cmp_filter) 
                                        ne = exp_filter(sql->sa, l, r, e->f, 
is_anti(e));
@@ -7825,15 +7863,25 @@ exp_rename_up(mvc *sql, sql_exp *e, list
                                        ne = exp_or(sql->sa, l,r);
                        }
                } else if (e->flag == cmp_in || e->flag == cmp_notin) {
-                       sql_exp *l = exp_rename_up(sql, e->l, aliases);
-                       list *r = exps_rename_up(sql, e->r, aliases);
+                       sql_exp *l = exp_apply_rename(sql, e->l, aliases, 
setname);
+                       list *r = exps_apply_rename(sql, e->r, aliases, 
setname);
+
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to