Changeset: 833dba869087 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/833dba869087
Modified Files:
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/vaults/csv/csv.c
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_file_loader.h
        sql/server/rel_optimize_others.c
        sql/server/rel_optimize_proj.c
        sql/server/rel_optimize_sel.c
        sql/server/rel_rewriter.c
        sql/server/rel_select.c
        sql/server/rel_statistics.c
        sql/server/rel_unnest.c
        
sql/test/BugTracker-2010/Tests/ORDER_BY_over_UNION_EXCEPT_INTERSECT.Bug-2606.test
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.test
        sql/test/miscellaneous/Tests/simple_plans.test
        sql/test/rel-optimizers/Tests/const-aggr-elim.test
Branch: default
Log Message:

backported optimizer changes


diffs (truncated from 900 to 300 lines):

diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -1109,6 +1109,7 @@ stmt_const(backend *be, stmt *s, stmt *v
                ns->nr = getDestVar(q);
                ns->tname = val->tname;
                ns->cname = val->cname;
+               ns->label = val->label;
                return ns;
        }
   bailout:
diff --git a/sql/backends/monet5/vaults/csv/csv.c 
b/sql/backends/monet5/vaults/csv/csv.c
--- a/sql/backends/monet5/vaults/csv/csv.c
+++ b/sql/backends/monet5/vaults/csv/csv.c
@@ -418,7 +418,7 @@ typedef struct csv_t {
  * Fill the list res_exps, with one result expressions per resulting column.
  */
 static str
-csv_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname)
+csv_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname, lng *est)
 {
        stream *file = csv_open_file(filename);
        if (file == NULL)
@@ -430,6 +430,8 @@ csv_relation(mvc *sql, sql_subfunc *f, c
         * detect header
         */
        char buf[8196+1];
+       *est = 0;
+       size_t fs = getFileSize(file);
        ssize_t l = mnstr_read(file, buf, 1, 8196);
        mnstr_close(file);
        mnstr_destroy(file);
@@ -478,6 +480,8 @@ csv_relation(mvc *sql, sql_subfunc *f, c
                        return sa_message(sql->sa, "csv" "type unknown\n");
                }
        }
+       if (p)
+               *est = fs * (p-buf)/2;
        GDKfree(types);
        f->res = typelist;
        f->coltypes = typelist;
@@ -490,7 +494,7 @@ csv_relation(mvc *sql, sql_subfunc *f, c
        r->extra_tsep = extra_tsep;
        r->has_header = has_header;
        f->sname = (char*)r; /* pass schema++ */
-       return NULL;
+       return MAL_SUCCEED;
 }
 
 static void *
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -148,7 +148,6 @@ exp_or_print(mvc *sql, stream *fout, nod
 void
 exp_print(mvc *sql, stream *fout, sql_exp *e, int depth, list *refs, int 
comma, int alias, int decorate)
 {
-       (void)sql;
        if (!e)
                return;
        /*mnstr_printf(fout, "%p ", e);*/
@@ -674,7 +673,7 @@ rel_print_rel(mvc *sql, stream  *fout, s
                if (rel->op == op_groupby)
                        r = "group by";
                if (rel->op == op_topn)
-                       r = "top N";
+                       r = rel->grouped?"grouped top N":"top N";
                if (rel->op == op_sample)
                        r = "sample";
 
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
@@ -1641,15 +1641,67 @@ rel_has_exps(sql_rel *rel, list *exps, b
        return -1;
 }
 
-int
-rel_has_all_exps(sql_rel *rel, list *exps)
+static bool
+rel_has_complete_exp(sql_rel *rel, sql_exp *e, bool subexp)
+{
+       sql_exp *ne = NULL;
+
+       if (!rel)
+               return NULL;
+       switch(e->type) {
+       case e_column:
+               if (is_basetable(rel->op) && !rel->exps) {
+                       assert(e->nid);
+                       return (rel_base_has_nid(rel, e->nid));
+               } else if ((!list_empty(rel->exps) && (is_project(rel->op) || 
is_base(rel->op))) ||
+                                       (!list_empty(rel->attr) && 
is_join(rel->op))) {
+                       list *l = rel->attr ? rel->attr : rel->exps;
+                       assert(e->nid);
+                       ne = exps_bind_nid(l, e->nid);
+               }
+               return ne;
+       case e_convert:
+               return rel_has_complete_exp(rel, e->l, subexp);
+       case e_aggr:
+       case e_func:
+               return (rel_has_all_exps(rel, e->l, subexp));
+       case e_cmp:
+               if (!subexp)
+                       return false;
+
+               if (e->flag == cmp_filter) {
+                       if (rel_has_all_exps(rel, e->l, subexp))
+                           return rel_has_all_exps(rel, e->r, subexp);
+               } else if (e->flag == cmp_con || e->flag == cmp_dis) {
+                       return rel_has_all_exps(rel, e->l, subexp);
+               } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+                       if (rel_has_complete_exp(rel, e->l, subexp))
+                           return rel_has_all_exps(rel, e->r, subexp);
+               } else if (rel_has_complete_exp(rel, e->l, subexp) &&
+                                  rel_has_complete_exp(rel, e->r, subexp) &&
+                              (!e->f || rel_has_complete_exp(rel, e->f, 
subexp))) {
+                       return true;
+               }
+               return false;
+       case e_psm:
+               return false;
+       case e_atom:
+               if (e->f) /* values */
+                       return rel_has_all_exps(rel, e->f, subexp);
+               return true;
+       }
+       return true;
+}
+
+bool
+rel_has_all_exps(sql_rel *rel, list *exps, bool subexp)
 {
        if (list_empty(exps))
-               return 1;
+               return true;
        for (node *n = exps->h; n; n = n->next)
-               if (rel_has_exp(rel, n->data, false) < 0)
-                       return 0;
-       return 1;
+               if (!rel_has_complete_exp(rel, n->data, subexp))
+                       return false;
+       return true;
 }
 
 static int
@@ -1920,7 +1972,6 @@ rel_find_nid(sql_rel *rel, int nid)
                case op_ddl:
                case op_truncate:
                        return false;
-
                }
        }
        return false;
@@ -2378,7 +2429,7 @@ exps_rel_get_rel(allocator *sa, list *ex
                        if (!(r = exp_rel_get_rel(sa, e)))
                                return NULL;
                        if (xp) {
-                               xp = rel_crossproduct(sa, xp, r, op_full);
+                               xp = rel_crossproduct(sa, xp, r, op_join);
                                set_processed(xp);
                        } else {
                                xp = r;
@@ -2920,7 +2971,7 @@ exps_uses_nid(list *exps, int nid)
 }
 
 sql_exp *
-exps_bind_nid(list *exps, int nid)
+exps_bind_nid(const list *exps, int nid)
 {
        if (exps) {
                for (node *en = exps->h; en; en = en->next ) {
@@ -3981,13 +4032,25 @@ rel_find_parameter(mvc *sql, sql_subtype
 }
 
 sql_exp *
-list_find_exp( list *exps, sql_exp *e)
+list_find_exp(const list *exps, sql_exp *e)
 {
        if (e->type != e_column)
                return NULL;
        return exps_bind_nid(exps, e->nid);
 }
 
+int
+exp_is_rename(sql_exp *e)
+{
+       return (e->type == e_column);
+}
+
+int
+exp_is_useless_rename(sql_exp *e)
+{
+       return (e->type == e_column && e->alias.label == e->nid);
+}
+
 void
 free_exps(allocator *sa, list *exps)
 {
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
@@ -197,16 +197,16 @@ extern int rel_has_exp(sql_rel *rel, sql
 /* return 0 when the relation contain at least one of the passed expressions 
(or sub expressions if subexp is set) else < 0 */
 extern int rel_has_exps(sql_rel *rel, list *e, bool subexp);
 /* return 1 when the relation contains all of the passed expressions else 0 */
-extern int rel_has_all_exps(sql_rel *rel, list *e);
+extern bool rel_has_all_exps(sql_rel *rel, list *e, bool subexp);
 
 extern sql_rel *find_rel(list *rels, sql_exp *e);
 extern sql_rel *find_one_rel(list *rels, sql_exp *e);
 
-extern sql_exp *exps_bind_nid(list *exps, int nid); /* get first expression to 
which this nid points */
+extern sql_exp *exps_bind_nid(const list *exps, int nid); /* get first 
expression to which this nid points */
 extern sql_exp *exps_uses_nid(list *exps, int nid); /* get first expression 
which references back to nid */
 extern sql_exp *exps_bind_column(list *exps, const char *cname, int 
*ambiguous, int *multiple, int no_tname /* set if expressions should be without 
a tname */);
 extern sql_exp *exps_bind_column2(list *exps, const char *rname, const char 
*cname, int *multiple);
-extern sql_exp * list_find_exp( list *exps, sql_exp *e);
+extern sql_exp * list_find_exp(const list *exps, sql_exp *e);
 
 extern unsigned int exps_card( list *l );
 extern void exps_fix_card( list *exps, unsigned int card);
@@ -236,4 +236,7 @@ extern sql_exp *exp_values_set_supertype
 extern void free_exp(allocator *sa, sql_exp *e);
 extern void free_exps(allocator *sa, list *exps);
 
+extern int exp_is_rename(sql_exp *e);
+extern int exp_is_useless_rename(sql_exp *e);
+
 #endif /* _REL_EXP_H_ */
diff --git a/sql/server/rel_file_loader.h b/sql/server/rel_file_loader.h
--- a/sql/server/rel_file_loader.h
+++ b/sql/server/rel_file_loader.h
@@ -16,7 +16,7 @@
 #include "sql_types.h"
 #include "sql_mvc.h"
 
-typedef str (*fl_add_types_fptr)(mvc *sql, sql_subfunc *f, char *filename, 
list *res_exps, char *name);
+typedef str (*fl_add_types_fptr)(mvc *sql, sql_subfunc *f, char *filename, 
list *res_exps, char *name, lng *est);
 typedef void *(*fl_load_fptr)(void *be, sql_subfunc *f, char *filename, 
sql_exp *topn); /* use void * as both return type and be argument are unknown 
types at this layer */
 
 typedef struct file_loader_t {
diff --git a/sql/server/rel_optimize_others.c b/sql/server/rel_optimize_others.c
--- a/sql/server/rel_optimize_others.c
+++ b/sql/server/rel_optimize_others.c
@@ -160,9 +160,20 @@ exp_push_down_prj(mvc *sql, sql_exp *e, 
                        return NULL;
                return exp_propagate(sql->sa, ne, e);
        case e_convert:
-               if (!(l = exp_push_down_prj(sql, e->l, f, t)))
-                       return NULL;
-               ne = exp_convert(sql, l, exp_fromtype(e), exp_totype(e));
+               {
+                       sql_exp *l = e->l;
+                       if (l->type == e_column) {
+                               sql_exp *ne = exps_bind_nid(f->exps, l->nid);
+                               if (!ne || !ne->nid)
+                                       return NULL;
+                               sql_exp *nne = exps_bind_nid(t->exps, ne->nid);
+                               if (!nne)
+                                       return NULL;
+                               l = exp_ref(sql, nne);
+                       } else if (!(l = exp_push_down_prj(sql, e->l, f, t)))
+                               return NULL;
+                       ne = exp_convert(sql, l, exp_fromtype(e), 
exp_totype(e));
+               }
                return exp_propagate(sql->sa, ne, e);
        case e_aggr:
        case e_func: {
diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -17,18 +17,6 @@
 #include "rel_select.h"
 #include "rel_rewriter.h"
 
-static int
-exp_is_rename(sql_exp *e)
-{
-       return (e->type == e_column);
-}
-
-static int
-exp_is_useless_rename(sql_exp *e)
-{
-       return (e->type == e_column && e->alias.label == e->nid);
-}
-
 static list *
 rel_used_projections(mvc *sql, list *exps, list *users)
 {
@@ -42,11 +30,13 @@ rel_used_projections(mvc *sql, list *exp
                assert(e->nid && exps_bind_nid(exps, e->nid));
                if (e->nid && (ne = exps_bind_nid(exps, e->nid))) {
                        used[list_position(exps, ne)] = 1;
+                       append(nexps, ne);
                }
        }
+       /* add intern expressions */
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to