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

Reply via email to