Changeset: f7570df27aae for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f7570df27aae Modified Files: sql/server/rel_statistics_functions.c sql/server/sql_atom.c Branch: properties Log Message:
Allow add/sub/mul/div on decimals, and preparing to propagate statistics on time types diffs (139 lines): diff --git a/sql/server/rel_statistics_functions.c b/sql/server/rel_statistics_functions.c --- a/sql/server/rel_statistics_functions.c +++ b/sql/server/rel_statistics_functions.c @@ -37,36 +37,59 @@ sql_add_propagate_statistics(mvc *sql, s } } -#define mul_and_sub_propagate(FUNC) \ -static void \ -sql_##FUNC##_propagate_statistics(mvc *sql, sql_exp *e) \ -{ \ - list *l = e->l; \ - sql_exp *first = l->h->data, *second = l->h->next->data; \ - atom *lmax, *rmax, *lmin, *rmin; \ - \ - if ((lmax = find_prop_and_get(first->p, PROP_MAX)) && (rmax = find_prop_and_get(second->p, PROP_MAX)) && \ - (lmin = find_prop_and_get(first->p, PROP_MIN)) && (rmin = find_prop_and_get(second->p, PROP_MIN))) { \ - atom *res1 = atom_##FUNC(atom_dup(sql->sa, lmax), rmax); \ - atom *res2 = atom_##FUNC(atom_dup(sql->sa, lmin), rmin); \ - \ - if (res1 && res2) { /* if the min/max pair overflows, then don't propagate */ \ - atom *zero1 = atom_zero_value(sql->sa, &(lmax->tpe)), *zero2 = atom_zero_value(sql->sa, &(rmax->tpe)); \ - int cmp1 = atom_cmp(lmax, zero1), cmp2 = atom_cmp(lmin, zero1), cmp3 = atom_cmp(rmin, zero2), cmp4 = atom_cmp(rmax, zero2); \ - \ - if (cmp1 >= 0 && cmp2 >= 0 && cmp3 >= 0 && cmp4 >= 0) { /* if all positive then propagate */ \ - set_property(sql, e, PROP_MAX, res1); \ - set_property(sql, e, PROP_MIN, res2); \ - } else if (cmp1 < 0 && cmp2 < 0 && cmp3 < 0 && cmp4 < 0) { /* if all negative propagate by swapping min and max */ \ - set_property(sql, e, PROP_MAX, res2); \ - set_property(sql, e, PROP_MIN, res1); \ - } \ - } \ - } \ +static void +sql_sub_propagate_statistics(mvc *sql, sql_exp *e) +{ + list *l = e->l; + sql_exp *first = l->h->data, *second = l->h->next->data; + atom *lmax, *rmax, *lmin, *rmin; + + if ((lmax = find_prop_and_get(first->p, PROP_MAX)) && (rmax = find_prop_and_get(second->p, PROP_MAX)) && + (lmin = find_prop_and_get(first->p, PROP_MIN)) && (rmin = find_prop_and_get(second->p, PROP_MIN))) { + atom *res1 = atom_sub(atom_dup(sql->sa, lmax), rmax); + atom *res2 = atom_sub(atom_dup(sql->sa, lmin), rmin); + + if (res1 && res2) { /* if the min/max pair overflows, then don't propagate */ + atom *zero1 = atom_zero_value(sql->sa, &(lmax->tpe)), *zero2 = atom_zero_value(sql->sa, &(rmax->tpe)); + int cmp1 = atom_cmp(lmax, zero1), cmp2 = atom_cmp(lmin, zero1), cmp3 = atom_cmp(rmin, zero2), cmp4 = atom_cmp(rmax, zero2); + + if (cmp1 >= 0 && cmp2 >= 0 && cmp3 >= 0 && cmp4 >= 0) { /* if all positive then propagate */ + set_property(sql, e, PROP_MAX, res1); + set_property(sql, e, PROP_MIN, res2); + } else if (cmp1 < 0 && cmp2 < 0 && cmp3 < 0 && cmp4 < 0) { /* if all negative propagate by swapping min and max */ + set_property(sql, e, PROP_MAX, res2); + set_property(sql, e, PROP_MIN, res1); + } + } + } } -mul_and_sub_propagate(sub) -mul_and_sub_propagate(mul) +static void +sql_mul_propagate_statistics(mvc *sql, sql_exp *e) +{ + list *l = e->l; + sql_exp *first = l->h->data, *second = l->h->next->data; + atom *lmax, *rmax, *lmin, *rmin; + + if ((lmax = find_prop_and_get(first->p, PROP_MAX)) && (rmax = find_prop_and_get(second->p, PROP_MAX)) && + (lmin = find_prop_and_get(first->p, PROP_MIN)) && (rmin = find_prop_and_get(second->p, PROP_MIN))) { + atom *res1 = atom_mul(atom_dup(sql->sa, lmax), rmax); + atom *res2 = atom_mul(atom_dup(sql->sa, lmin), rmin); + + if (res1 && res2) { /* if the min/max pair overflows, then don't propagate */ + atom *zero1 = atom_zero_value(sql->sa, &(lmax->tpe)), *zero2 = atom_zero_value(sql->sa, &(rmax->tpe)); + int cmp1 = atom_cmp(lmax, zero1), cmp2 = atom_cmp(lmin, zero1), cmp3 = atom_cmp(rmin, zero2), cmp4 = atom_cmp(rmax, zero2); + + if (cmp1 >= 0 && cmp2 >= 0 && cmp3 >= 0 && cmp4 >= 0) { /* if all positive then propagate */ + set_property(sql, e, PROP_MAX, res1); + set_property(sql, e, PROP_MIN, res2); + } else if (cmp1 < 0 && cmp2 < 0 && cmp3 < 0 && cmp4 < 0) { /* if all negative propagate by swapping min and max */ + set_property(sql, e, PROP_MAX, res2); + set_property(sql, e, PROP_MIN, res1); + } + } + } +} static void sql_div_propagate_statistics(mvc *sql, sql_exp *e) @@ -80,7 +103,7 @@ sql_div_propagate_statistics(mvc *sql, s atom *res1 = atom_div(atom_dup(sql->sa, lmax), rmin); atom *res2 = atom_div(atom_dup(sql->sa, lmin), rmax); - if (res1 && res2) { /* if the min/max pair overflows, then don't propagate */ + if (res1 && res2) { /* on div by zero don't propagate */ atom *zero1 = atom_zero_value(sql->sa, &(lmax->tpe)), *zero2 = atom_zero_value(sql->sa, &(rmax->tpe)); int cmp1 = atom_cmp(lmax, zero1), cmp2 = atom_cmp(lmin, zero1), cmp3 = atom_cmp(rmin, zero2), cmp4 = atom_cmp(rmax, zero2); 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 @@ -1321,7 +1321,7 @@ atom_add(atom *a1, atom *a2) { ValRecord dst; - if ((!EC_COMPUTE(a1->tpe.type->eclass) && (a1->tpe.type->eclass != EC_DEC || a1->tpe.digits != a2->tpe.digits || a1->tpe.scale != a2->tpe.scale)) || a1->tpe.digits < a2->tpe.digits || a1->tpe.type->localtype != a2->tpe.type->localtype) + if (!EC_NUMBER(a1->tpe.type->eclass)) return NULL; if (a1->tpe.type->localtype < a2->tpe.type->localtype || (a1->tpe.type->localtype == a2->tpe.type->localtype && @@ -1346,7 +1346,7 @@ atom_sub(atom *a1, atom *a2) { ValRecord dst; - if ((!EC_COMPUTE(a1->tpe.type->eclass) && (a1->tpe.type->eclass != EC_DEC || a1->tpe.digits != a2->tpe.digits || a1->tpe.scale != a2->tpe.scale)) || a1->tpe.digits < a2->tpe.digits || a1->tpe.type->localtype != a2->tpe.type->localtype) + if (!EC_NUMBER(a1->tpe.type->eclass)) return NULL; if (a1->tpe.type->localtype < a2->tpe.type->localtype || (a1->tpe.type->localtype == a2->tpe.type->localtype && @@ -1373,7 +1373,7 @@ atom_mul(atom *a1, atom *a2) { ValRecord dst; - if (!EC_COMPUTE(a1->tpe.type->eclass)) + if (!EC_NUMBER(a1->tpe.type->eclass)) return NULL; if (a1->tpe.type->localtype < a2->tpe.type->localtype || (a1->tpe.type->localtype == a2->tpe.type->localtype && @@ -1401,7 +1401,7 @@ atom_div(atom *a1, atom *a2) { ValRecord dst; - if (!EC_COMPUTE(a1->tpe.type->eclass)) + if (!EC_NUMBER(a1->tpe.type->eclass)) return NULL; if (a1->tpe.type->localtype < a2->tpe.type->localtype || (a1->tpe.type->localtype == a2->tpe.type->localtype && _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list