Changeset: 2eef71653a40 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2eef71653a40 Modified Files: sql/server/rel_statistics_functions.c Branch: properties Log Message:
The multiplication function propagation was not correct. For now, propagate only if min and max from both sides have the same sign diffs (142 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 @@ -19,6 +19,55 @@ sql_hash *sql_functions_lookup = NULL; static void +VALzero_value(ValPtr input, int localtype) +{ + void *ret = NULL; + + bte bval = 0; + sht sval = 0; + int ival = 0; + lng lval = 0; +#ifdef HAVE_HGE + hge hval = 0; +#endif + flt fval = 0; + dbl dval = 0; + + if (ATOMlinear(localtype)) { + switch (ATOMstorage(localtype)) { + case TYPE_bte: + ret = &bval; + break; + case TYPE_sht: + ret = &sval; + break; + case TYPE_int: + ret = &ival; + break; + case TYPE_lng: + ret = &lval; + break; +#ifdef HAVE_HGE + case TYPE_hge: + ret = &hval; + break; +#endif + case TYPE_flt: + ret = &fval; + break; + case TYPE_dbl: + ret = &dval; + break; + default: + break; + } + } + + VALset(input, localtype, ret); +} + + +static void sql_add_propagate_statistics(mvc *sql, sql_exp *e) { list *l = e->l; @@ -27,16 +76,16 @@ sql_add_propagate_statistics(mvc *sql, s if ((lval = find_prop_and_get(first->p, PROP_MAX)) && (rval = find_prop_and_get(second->p, PROP_MAX))) { ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)); - res->vtype = lval->vtype; + res->vtype = lval->vtype > rval->vtype ? lval->vtype : rval->vtype; if (VARcalcadd(res, lval, rval, true) == GDK_SUCCEED) { copy_property(sql, e, PROP_MAX, res); } else { - GDKclrerr(); /* if the min/max pair overflows, then disable */ + GDKclrerr(); /* if the min/max pair overflows, then don't propagate */ } } if ((lval = find_prop_and_get(first->p, PROP_MIN)) && (rval = find_prop_and_get(second->p, PROP_MIN))) { ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)); - res->vtype = lval->vtype; + res->vtype = lval->vtype > rval->vtype ? lval->vtype : rval->vtype; if (VARcalcadd(res, lval, rval, true) == GDK_SUCCEED) { copy_property(sql, e, PROP_MIN, res); } else { @@ -50,31 +99,38 @@ sql_mul_propagate_statistics(mvc *sql, s { list *l = e->l; sql_exp *first = l->h->data, *second = l->h->next->data; - ValPtr lval, rval; - ValRecord zero, verify; + ValPtr 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))) { + ValPtr res1 = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)), res2 = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)); + gdk_return code1, code2; + + res1->vtype = res2->vtype = lmax->vtype > rmax->vtype ? lmax->vtype : rmax->vtype; + code1 = VARcalcmul(res1, lmax, rmax, true); + GDKclrerr(); + code2 = VARcalcmul(res2, lmin, rmin, true); + GDKclrerr(); + + if (code1 == GDK_SUCCEED && code2 == GDK_SUCCEED) { /* if the min/max pair overflows, then don't propagate */ + ValRecord zero1, zero2, zero3, zero4, verify1, verify2, verify3, verify4; - if ((lval = find_prop_and_get(first->p, PROP_MAX)) && (rval = find_prop_and_get(second->p, PROP_MAX))) { - ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)); - res->vtype = lval->vtype; - if (VARcalcmul(res, lval, rval, true) == GDK_SUCCEED) { /* only propagate '*' min/max when both sides have the same sign ie a * b >= 0 */ - VALinit(&zero, res->vtype, &(int){0}); - VARcalcge(&verify, res, &zero); - if (verify.val.btval == 1) - copy_property(sql, e, PROP_MAX, res); - } else { - GDKclrerr(); /* if the min/max pair overflows, then disable */ - } - } - if ((lval = find_prop_and_get(first->p, PROP_MIN)) && (rval = find_prop_and_get(second->p, PROP_MIN))) { - ValPtr res = (ValPtr) sa_zalloc(sql->sa, sizeof(ValRecord)); - res->vtype = lval->vtype; - if (VARcalcmul(res, lval, rval, true) == GDK_SUCCEED) { - VALinit(&zero, res->vtype, &(int){0}); - VARcalcge(&verify, res, &zero); - if (verify.val.btval == 1) - copy_property(sql, e, PROP_MIN, res); - } else { - GDKclrerr(); + VALzero_value(&zero1, lmax->vtype); + VARcalcge(&verify1, lmax, &zero1); + VALzero_value(&zero2, rmax->vtype); + VARcalcge(&verify2, rmax, &zero2); + VALzero_value(&zero3, lmin->vtype); + VARcalcge(&verify3, lmin, &zero3); + VALzero_value(&zero4, rmin->vtype); + VARcalcge(&verify4, rmin, &zero4); + + if (verify1.val.btval == 1 && verify2.val.btval == 1 && verify3.val.btval == 1 && verify4.val.btval == 1) { /* if all positive then propagate */ + copy_property(sql, e, PROP_MAX, res1); + copy_property(sql, e, PROP_MIN, res2); + } else if (verify1.val.btval == 0 && verify2.val.btval == 0 && verify3.val.btval == 0 && verify4.val.btval == 0) { /* if all negative propagate by swapping min and max */ + copy_property(sql, e, PROP_MIN, res1); + copy_property(sql, e, PROP_MAX, res2); + } } } } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list