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]