Changeset: d0667b92bede for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d0667b92bede
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
Branch: Jul2017
Log Message:

fixed problem in dead code optimizer, ie handle the referenced sub queries
in the proper order.


diffs (280 lines):

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
@@ -6078,43 +6078,20 @@ rel_remove_unused(mvc *sql, sql_rel *rel
        return rel;
 }
 
-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 NULL;
+static void
+rel_dep_graph( char *deps, list *refs, sql_rel *parent, sql_rel *rel) 
+{
+       if (!parent)
+               return ;
+
+       if (rel_is_ref(rel) && parent != rel) {
+               int n = list_length(refs);
+               int pnr = list_position(refs, parent);
+               int cnr = list_position(refs, rel);
+
+               deps[pnr*n + cnr] = 1;
+               parent = rel;
+       }
 
        switch(rel->op) {
        case op_table:
@@ -6125,7 +6102,7 @@ rel_dce_refs(mvc *sql, sql_rel *rel)
        case op_select: 
 
                if (rel->l && (rel->op != op_table || rel->flag != 2))
-                       l = rel_dce_refs(sql, rel->l);
+                       rel_dep_graph(deps, refs, parent, rel->l);
 
        case op_basetable:
        case op_insert:
@@ -6136,7 +6113,7 @@ rel_dce_refs(mvc *sql, sql_rel *rel)
        case op_delete:
 
                if (rel->r)
-                       r = rel_dce_refs(sql, rel->r);
+                       rel_dep_graph(deps, refs, parent, rel->r);
                break;
 
 
@@ -6151,25 +6128,152 @@ rel_dce_refs(mvc *sql, sql_rel *rel)
        case op_anti: 
 
                if (rel->l)
-                       l = rel_dce_refs(sql, rel->l);
+                       rel_dep_graph(deps, refs, parent, rel->l);
                if (rel->r)
-                       r = rel_dce_refs(sql, rel->r);
+                       rel_dep_graph(deps, refs, parent, 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;
+}
+
+/*
+extern void _rel_print(mvc *sql, sql_rel *rel);
+
+static void 
+print_deps(mvc *sql, char *deps, list *refs) 
+{
+       int i, j;
+       int n = list_length(refs);
+
+       for (i=0; i<n; i++) {
+               sql_rel *r = list_fetch(refs, i);
+               printf("dep %d\n", i);
+               _rel_print(sql,r);
+       }
+       for (i=0; i<n; i++) {
+               for (j=0; j<n; j++) {
+                       printf("%c ", i==j?'x' : deps[i*n + j]?'1':'0');
+               }
+               printf("\n");
+       }
+
+}      
+*/
+
+static int 
+depends_on(int nr, char *deps, int n, int dnr) 
+{
+       for(;dnr < n; dnr++) {
+               if (dnr == nr)
+                       dnr++;
+               if (deps[nr*n + dnr])
+                       return dnr;
+       }
+       return -1;
+}
+
+static void
+flatten_dep(list *nrefs, list *refs, int nr, char *deps, int n) 
+{
+       int dnr = 0;
+
+       if (deps[nr*n + nr])
+               return;
+       for (;(dnr = depends_on(nr, deps, n, dnr)) >= 0 && dnr < n; dnr++) 
+               flatten_dep(nrefs, refs, dnr, deps, n);
+       if (!deps[nr*n + nr]) {
+               list_prepend(nrefs, list_fetch(refs,nr));
+               deps[nr*n+nr] = 1; /* mark done */
+       }
+}
+
+static list *
+flatten_dep_graph(mvc *sql, char *deps, list *refs)
+{
+       list *nrefs = sa_list(sql->sa);
+       int n = list_length(refs), nr = 0;
+
+       for (nr = 0; nr < n; nr++) {
+               if (deps[nr*n + nr])
+                       continue;
+               flatten_dep(nrefs, refs, nr, deps, n);
+       }
+       return nrefs;
+}
+
+static list *
+rel_dependencies(mvc *sql, list *refs)
+{
+       int n = list_length(refs);
+
+       if (n > 1) {
+               char *deps = SA_NEW_ARRAY(sql->sa, char, n*n);
+               node *m;
+
+               memset(deps, 0, n*n);
+               for (m = refs->h; m; m = m->next) {
+                       rel_dep_graph(deps, refs, m->data, m->data);
+               }
+               refs = flatten_dep_graph(sql, deps, refs);
+               //print_deps(sql, deps, refs);
+       }
+       return refs;
+}
+
+static void
+rel_dce_refs(mvc *sql, sql_rel *rel, list *refs) 
+{
+       if (!rel)
+               return ;
+
+       switch(rel->op) {
+       case op_table:
+       case op_topn: 
+       case op_sample: 
+       case op_project:
+       case op_groupby: 
+       case op_select: 
+
+               if (rel->l && (rel->op != op_table || rel->flag != 2))
+                       rel_dce_refs(sql, rel->l, refs);
+
+       case op_basetable:
+       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_union: 
+       case op_inter: 
+       case op_except: 
+       case op_join: 
+       case op_left: 
+       case op_right: 
+       case op_full: 
+       case op_semi: 
+       case op_anti: 
+
+               if (rel->l)
+                       rel_dce_refs(sql, rel->l, refs);
+               if (rel->r)
+                       rel_dce_refs(sql, rel->r, refs);
+               break;
+
+       case op_apply: 
+               assert(0);
+       }
+
+       if (rel_is_ref(rel) && !list_find(refs, rel, NULL)) 
+               list_prepend(refs, rel);
 }
 
 static sql_rel *
@@ -6348,17 +6452,19 @@ rel_add_projects(mvc *sql, sql_rel *rel)
 sql_rel *
 rel_dce(mvc *sql, sql_rel *rel)
 {
-       list *refs;
+       list *refs = sa_list(sql->sa);
        node *n;
 
-       refs = rel_dce_refs(sql, rel);
+       rel_dce_refs(sql, rel, refs);
        rel = rel_add_projects(sql, rel);
        rel_used(rel);
        rel_dce_sub(sql, rel, refs);
 
-       if (refs)
+       if (refs) {
+               refs = rel_dependencies(sql, refs);
                for (n = refs->h; n; n = n->next)
                        rel_dce_sub(sql, n->data, refs);
+       }
        return rel;
 }
 
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
@@ -210,6 +210,8 @@ rel_table_optname(mvc *sql, sql_rel *sq,
                list *l = sa_list(sql->sa);
 
                columnrefs = optname->data.lval->h->next->data.lval;
+               if (!is_project(sq->op) && !is_base(sq->op)) 
+                       sq = rel_project(sql->sa, sq, rel_projections(sql, sq, 
NULL, 1, 1));
                if (columnrefs && sq->exps) {
                        dnode *d = columnrefs->h;
                        node *ne = sq->exps->h;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to