Changeset: c3c45e82840d for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c3c45e82840d Modified Files: sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/sql_atom.c sql/server/sql_atom.h Branch: default Log Message:
flatten atom expression when eliminating partitions diffs (218 lines): 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 @@ -1604,3 +1604,38 @@ exp_copy( sql_allocator *sa, sql_exp * e return ne; } +atom * +exp_flatten(mvc *sql, sql_exp *e) +{ + if (e->type == e_atom) { + atom *v = exp_value(e, sql->args, sql->argc); + + if (v) + return atom_dup(sql->sa, v); + } else if (e->type == e_convert) { + atom *v = exp_flatten(sql, e->l); + + if (v && atom_cast(v, &e->tpe)) + return v; + return NULL; + } else if (e->type == e_func) { + sql_subfunc *f = e->f; + list *l = e->l; + sql_arg *res = (f->func->res)?(f->func->res->h->data):NULL; + + /* TODO handle date + x months */ + if (strcmp(f->func->base.name, "sql_add") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) { + atom *l1 = exp_flatten(sql, l->h->data); + atom *l2 = exp_flatten(sql, l->h->next->data); + if (l1 && l2) + return atom_add(l1,l2); + } else if (strcmp(f->func->base.name, "sql_sub") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) { + atom *l1 = exp_flatten(sql, l->h->data); + atom *l2 = exp_flatten(sql, l->h->next->data); + if (l1 && l2) + return atom_sub(l1,l2); + } + } + return NULL; +} + 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 @@ -127,5 +127,6 @@ extern int exps_intern(list *exps); extern char *compare_func( comp_type t ); extern int is_identity( sql_exp *e, sql_rel *r); +extern atom *exp_flatten(mvc *sql, sql_exp *e); #endif /* _REL_EXP_H_ */ 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 @@ -213,31 +213,6 @@ kc_column_cmp(sql_kc *kc, sql_column *c) return !(c == kc->c); } -static int -join_properties(mvc *sql, sql_rel *rel) -{ - if (rel->exps) { - list *join_cols = new_col_list(sql->sa); - node *en; - - /* simply using the expressions should also work ! */ - for ( en = rel->exps->h; en; en = en->next ) { - sql_exp *e = en->data; - - if (e->type == e_cmp && e->flag == cmp_equal) { - sql_column *lc = exp_find_column(rel, e->l, -2); - sql_column *rc = exp_find_column(rel, e->r, -2); - - if (lc && rc) { - append(join_cols, lc); - append(join_cols, rc); - } - } - } - } - return 0; -} - static void rel_properties(mvc *sql, global_props *gp, sql_rel *rel) { @@ -285,8 +260,6 @@ rel_properties(mvc *sql, global_props *g rel->p = prop_create(sql->sa, PROP_COUNT, rel->p); break; case op_join: - join_properties(sql, rel); - break; case op_left: case op_right: case op_full: @@ -6597,16 +6570,11 @@ rel_merge_table_rewrite(int *changes, mv sql_exp *c = e->l; c = rel_find_exp(rel, c); - if (l->type == e_atom && !l->l) - lval = sql->args[l->flag]; - else if (l->type == e_atom && l->l) - lval = l->l; + lval = exp_flatten(sql, l); if (!h) hval = lval; - else if (h && h->type == e_atom && !h->l) - hval = sql->args[h->flag]; - else if (h && h->type == e_atom && h->l) - hval = h->l; + else if (h) + hval = exp_flatten(sql, h); if (c && lval && hval) { append(cols, c); append(low, lval); diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c --- a/sql/server/sql_atom.c +++ b/sql/server/sql_atom.c @@ -1178,3 +1178,85 @@ atom_cmp(atom *a1, atom *a2) return 0; return VALcmp(&a1->data, &a2->data); } + +atom * +atom_add(atom *a1, atom *a2) +{ + if (a1->tpe.type->localtype != a2->tpe.type->localtype) + return NULL; + switch(a1->tpe.type->localtype) { + case TYPE_bte: + a1->data.val.btval += a2->data.val.btval; + a1->d = a1->data.val.btval; + break; + case TYPE_sht: + a1->data.val.shval += a2->data.val.shval; + a1->d = a1->data.val.shval; + break; + case TYPE_int: + a1->data.val.ival += a2->data.val.ival; + a1->d = a1->data.val.ival; + break; + case TYPE_lng: + a1->data.val.lval += a2->data.val.lval; + a1->d = a1->data.val.lval; + break; +#ifdef HAVE_HGE + case TYPE_hge: + a1->data.val.hval += a2->data.val.hval; + a1->d = a1->data.val.hval; + break; +#endif + case TYPE_flt: + a1->data.val.fval += a2->data.val.fval; + a1->d = a1->data.val.fval; + break; + case TYPE_dbl: + a1->data.val.dval += a2->data.val.dval; + a1->d = a1->data.val.dval; + default: + break; + } + return a1; +} + +atom * +atom_sub(atom *a1, atom *a2) +{ + if (a1->tpe.type->localtype != a2->tpe.type->localtype) + return NULL; + switch(a1->tpe.type->localtype) { + case TYPE_bte: + a1->data.val.btval -= a2->data.val.btval; + a1->d = a1->data.val.btval; + break; + case TYPE_sht: + a1->data.val.shval -= a2->data.val.shval; + a1->d = a1->data.val.shval; + break; + case TYPE_int: + a1->data.val.ival -= a2->data.val.ival; + a1->d = a1->data.val.ival; + break; + case TYPE_lng: + a1->data.val.lval -= a2->data.val.lval; + a1->d = a1->data.val.lval; + break; +#ifdef HAVE_HGE + case TYPE_hge: + a1->data.val.hval -= a2->data.val.hval; + a1->d = a1->data.val.hval; + break; +#endif + case TYPE_flt: + a1->data.val.fval -= a2->data.val.fval; + a1->d = a1->data.val.fval; + break; + case TYPE_dbl: + a1->data.val.dval -= a2->data.val.dval; + a1->d = a1->data.val.dval; + default: + break; + } + return a1; +} diff --git a/sql/server/sql_atom.h b/sql/server/sql_atom.h --- a/sql/server/sql_atom.h +++ b/sql/server/sql_atom.h @@ -61,6 +61,9 @@ extern lng atom_get_int(atom *a); extern int atom_cmp(atom *a1, atom *a2); +extern atom *atom_add(atom *a1, atom *a2); +extern atom *atom_sub(atom *a1, atom *a2); + #ifdef HAVE_HGE extern hge scales[39]; #else _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list