Changeset: 25a00e2e9008 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=25a00e2e9008
Added Files:
        sql/test/BugTracker-2017/Tests/one-plus-nil.Bug-6243.sql
        sql/test/BugTracker-2017/Tests/one-plus-nil.Bug-6243.stable.err
        sql/test/BugTracker-2017/Tests/one-plus-nil.Bug-6243.stable.out
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/test/BugTracker-2017/Tests/All
Branch: Dec2016
Log Message:

Use VARcalc* functions to do calculations.
This way you get nil handling and overflow checking.
This fixes bug 6243.


diffs (truncated from 495 to 300 lines):

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
@@ -2722,7 +2722,7 @@ exp_simplify_math( mvc *sql, sql_exp *e,
                                atom *ra = exp_flatten(sql, re);
 
                                if (la && ra) {
-                                       atom *a = atom_mul(sql->sa, la, ra);
+                                       atom *a = atom_mul(la, ra);
 
                                        if (a) {
                                                sql_exp *ne = exp_atom(sql->sa, 
a);
@@ -2768,10 +2768,11 @@ exp_simplify_math( mvc *sql, sql_exp *e,
                                        sql_exp *lle = l->h->data;
                                        sql_exp *lre = l->h->next->data;
                                        if (exp_equal(re, lle)==0) {
-                                               atom_inc(exp_value(sql, lre, 
sql->args, sql->argc));
-                                               (*changes)++;
-                                               exp_setname(sql->sa, le, 
exp_relname(e), exp_name(e));
-                                               return le;
+                                               if (atom_inc(exp_value(sql, 
lre, sql->args, sql->argc))) {
+                                                       (*changes)++;
+                                                       exp_setname(sql->sa, 
le, exp_relname(e), exp_name(e));
+                                                       return le;
+                                               }
                                        }
                                }
                                if (!f->func->s && !strcmp(f->func->base.name, 
"sql_mul") && list_length(l) == 2) {
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
@@ -1147,37 +1147,16 @@ atom_cast(sql_allocator *sa, atom *a, sq
 int 
 atom_neg( atom *a )
 {
-       switch( a->tpe.type->localtype) {
-       case TYPE_bte:
-               a->data.val.btval = -a->data.val.btval;
-               break;
-       case TYPE_sht:
-               a->data.val.shval = -a->data.val.shval;
-               break;
-       case TYPE_int:
-               a->data.val.ival = -a->data.val.ival;
-               break;
-       case TYPE_lng:
-               a->data.val.lval = -a->data.val.lval;
-               break;
-#ifdef HAVE_HGE
-       case TYPE_hge:
-               a->data.val.hval = -a->data.val.hval;
-               break;
-#endif
-       case TYPE_flt:
-               a->data.val.fval = -a->data.val.fval;
-               break;
-       case TYPE_dbl:
-               a->data.val.dval = -a->data.val.dval;
-               if (a->data.val.dval == dbl_nil)
-                       return -1;
-               break;
-       default:
+       ValRecord dst;
+       dst.vtype = a->data.vtype;
+       if (VARcalcnegate(&dst, &a->data) != GDK_SUCCEED)
                return -1;
-       }
-       if (a->d != dbl_nil && a->tpe.type->localtype != TYPE_dbl)
-               a->d = -a->d;
+       a->data = dst;
+       dst.vtype = TYPE_dbl;
+       dst.val.dval = a->d;
+       if (VARcalcnegate(&dst, &dst) != GDK_SUCCEED)
+               return -1;
+       a->d = dst.val.dval;
        return 0;
 }
 
@@ -1196,183 +1175,80 @@ atom_cmp(atom *a1, atom *a2)
 atom * 
 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) {
                return NULL;
        }
-       switch(a1->tpe.type->localtype) {
-       case TYPE_bte:
-                       a1->data.val.btval += a2->data.val.btval;
-                       a1->d = (dbl) a1->data.val.btval;
-                       break;
-       case TYPE_sht:
-                       a1->data.val.shval += a2->data.val.shval;
-                       a1->d = (dbl) a1->data.val.shval;
-                       break;
-       case TYPE_int:
-                       a1->data.val.ival += a2->data.val.ival;
-                       a1->d = (dbl) a1->data.val.ival;
-                       break;
-       case TYPE_lng:
-                       a1->data.val.lval += a2->data.val.lval;
-                       a1->d = (dbl) a1->data.val.lval;
-                       break;
-#ifdef HAVE_HGE
-       case TYPE_hge:
-                       a1->data.val.hval += a2->data.val.hval;
-                       a1->d = (dbl) a1->data.val.hval;
-                       break;
-#endif
-       case TYPE_flt:
-                       a1->data.val.fval += a2->data.val.fval;
-                       a1->d = (dbl) a1->data.val.fval;
-                       break;
-       case TYPE_dbl:
-                       a1->data.val.dval += a2->data.val.dval;
-                       a1->d = (dbl) a1->data.val.dval;
-       default:
-                       break;
-       }
+       dst.vtype = a1->tpe.type->localtype;
+       if (VARcalcadd(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
+               return NULL;
+       a1->data = dst;
+       dst.vtype = TYPE_dbl;
+       if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
+               a1->d = dst.val.dval;
        return a1;
 }
 
 atom * 
 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) {
                return NULL;
        }
-       switch(a1->tpe.type->localtype) {
-       case TYPE_bte:
-                       a1->data.val.btval -= a2->data.val.btval;
-                       a1->d = (dbl) a1->data.val.btval;
-                       break;
-       case TYPE_sht:
-                       a1->data.val.shval -= a2->data.val.shval;
-                       a1->d = (dbl) a1->data.val.shval;
-                       break;
-       case TYPE_int:
-                       a1->data.val.ival -= a2->data.val.ival;
-                       a1->d = (dbl) a1->data.val.ival;
-                       break;
-       case TYPE_lng:
-                       a1->data.val.lval -= a2->data.val.lval;
-                       a1->d = (dbl) a1->data.val.lval;
-                       break;
-#ifdef HAVE_HGE
-       case TYPE_hge:
-                       a1->data.val.hval -= a2->data.val.hval;
-                       a1->d = (dbl) a1->data.val.hval;
-                       break;
-#endif
-       case TYPE_flt:
-                       a1->data.val.fval -= a2->data.val.fval;
-                       a1->d = (dbl) a1->data.val.fval;
-                       break;
-       case TYPE_dbl:
-                       a1->data.val.dval -= a2->data.val.dval;
-                       a1->d = (dbl) a1->data.val.dval;
-       default:
-                       break;
-       }
+       dst.vtype = a1->tpe.type->localtype;
+       if (VARcalcsub(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
+               return NULL;
+       a1->data = dst;
+       dst.vtype = TYPE_dbl;
+       if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
+               a1->d = dst.val.dval;
        return a1;
 }
 
 atom * 
-atom_mul(sql_allocator *sa, atom *a1, atom *a2)
+atom_mul(atom *a1, atom *a2)
 {
+       ValRecord dst;
        if (!EC_COMPUTE(a1->tpe.type->eclass))
                return NULL;
-       if (a1->tpe.type->localtype != a2->tpe.type->localtype) {
-               if (a1->tpe.type->localtype == TYPE_dbl) {
-                       a1->data.val.dval *= a2->d;
-                       a1->d = (dbl) a1->data.val.dval;
-                       return a1;
-               }
-               if (a2->tpe.type->localtype == TYPE_dbl) {
-                       a2->data.val.dval *= a1->d;
-                       a2->d = (dbl) a2->data.val.dval;
-                       return a2;
-               }
-               if (a1->tpe.type->localtype > a2->tpe.type->localtype) {
-                       if (!atom_cast(sa, a2, &a1->tpe))
-                               return NULL;
-               } else if (!atom_cast(sa, a1, &a2->tpe)) {
+       if (a1->tpe.type->localtype == TYPE_dbl ||
+           a2->tpe.type->localtype == TYPE_dbl) {
+               ValRecord v1, v2;
+               v1.vtype = v2.vtype = TYPE_dbl;
+               v1.val.dval = a1->d;
+               v2.val.dval = a2->d;
+               if (VARcalcmul(&dst, &v1, &v2, 1) != GDK_SUCCEED)
                        return NULL;
-               }
+               a1->data.vtype = TYPE_dbl;
+               a1->d = a1->data.val.dval = dst.val.dval;
+               return a1;
        }
-       switch(a1->tpe.type->localtype) {
-       case TYPE_bte:
-                       a1->data.val.btval *= a2->data.val.btval;
-                       a1->d = (dbl) a1->data.val.btval;
-                       break;
-       case TYPE_sht:
-                       a1->data.val.shval *= a2->data.val.shval;
-                       a1->d = (dbl) a1->data.val.shval;
-                       break;
-       case TYPE_int:
-                       a1->data.val.ival *= a2->data.val.ival;
-                       a1->d = (dbl) a1->data.val.ival;
-                       break;
-       case TYPE_lng:
-                       a1->data.val.lval *= a2->data.val.lval;
-                       a1->d = (dbl) a1->data.val.lval;
-                       break;
-#ifdef HAVE_HGE
-       case TYPE_hge:
-                       a1->data.val.hval *= a2->data.val.hval;
-                       a1->d = (dbl) a1->data.val.hval;
-                       break;
-#endif
-       case TYPE_flt:
-                       a1->data.val.fval *= a2->data.val.fval;
-                       a1->d = (dbl) a1->data.val.fval;
-                       break;
-       case TYPE_dbl:
-                       a1->data.val.dval *= a2->data.val.dval;
-                       a1->d = (dbl) a1->data.val.dval;
-       default:
-                       break;
-       }
+       if (a1->tpe.type->localtype >= a2->tpe.type->localtype)
+               dst.vtype = a1->tpe.type->localtype;
+       else
+               dst.vtype = a2->tpe.type->localtype;
+       if (VARcalcmul(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
+               return NULL;
+       a1->data = dst;
+       dst.vtype = TYPE_dbl;
+       if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
+               a1->d = dst.val.dval;
        return a1;
 }
 
-void
+int
 atom_inc( atom *a )
 {
-       switch(a->tpe.type->localtype) {
-       case TYPE_bte:
-                       a->data.val.btval++;
-                       a->d = (dbl) a->data.val.btval;
-                       break;
-       case TYPE_sht:
-                       a->data.val.shval++;
-                       a->d = (dbl) a->data.val.shval;
-                       break;
-       case TYPE_int:
-                       a->data.val.ival++;
-                       a->d = (dbl) a->data.val.ival;
-                       break;
-       case TYPE_lng:
-                       a->data.val.lval++;
-                       a->d = (dbl) a->data.val.lval;
-                       break;
-#ifdef HAVE_HGE
-       case TYPE_hge:
-                       a->data.val.hval++;
-                       a->d = (dbl) a->data.val.hval;
-                       break;
-#endif
-       case TYPE_flt:
-                       a->data.val.fval++;
-                       a->d = (dbl) a->data.val.fval;
-                       break;
-       case TYPE_dbl:
-                       a->data.val.dval++;
-                       a->d = a->data.val.dval;
-                       break;
-       default:
-                       break;
-       }
+       ValRecord dst;
+       dst.vtype = a->data.vtype;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to