diff options
-rw-r--r-- | mysql-test/r/type_newdecimal.result | 32 | ||||
-rw-r--r-- | mysql-test/t/type_newdecimal.test | 22 | ||||
-rw-r--r-- | strings/decimal.c | 16 |
3 files changed, 69 insertions, 1 deletions
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 4980e2a73d2..f06e290a49b 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -984,3 +984,35 @@ t1 CREATE TABLE `t1` ( `f1` decimal(10,0) unsigned zerofill NOT NULL default '0000000000' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +drop procedure if exists wg2; +Warnings: +Note 1305 PROCEDURE wg2 does not exist +create procedure wg2() +begin +declare v int default 1; +declare tdec decimal(5) default 0; +while v <= 9 do set tdec =tdec * 10; +select v, tdec; +set v = v + 1; +end while; +end// +call wg2()// +v tdec +1 0 +v tdec +2 0 +v tdec +3 0 +v tdec +4 0 +v tdec +5 0 +v tdec +6 0 +v tdec +7 0 +v tdec +8 0 +v tdec +9 0 +drop procedure wg2; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index f3be64506c7..55e0618a3e5 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1015,3 +1015,25 @@ create table t1 ( f1 decimal (0,0) zerofill not null default 0); show create table t1; drop table t1; + +# +# Bug 12938 (arithmetic loop's zero) +# +--disable-warnings +drop procedure if exists wg2; +--enable-warnings +delimiter //; +create procedure wg2() +begin + declare v int default 1; + declare tdec decimal(5) default 0; + while v <= 9 do set tdec =tdec * 10; + select v, tdec; + set v = v + 1; + end while; +end// + +call wg2()// + +delimiter ;// +drop procedure wg2; diff --git a/strings/decimal.c b/strings/decimal.c index 4dc5fa91e0a..7816f340eef 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1933,7 +1933,7 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac), intg0=ROUND_UP(from1->intg+from2->intg), - frac0=frac1+frac2, error, i, j; + frac0=frac1+frac2, error, i, j, d_to_move; dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0, *start2, *stop2, *stop1, *start0, carry; @@ -2007,6 +2007,20 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) } } } + buf1= to->buf; + d_to_move= intg0 + ROUND_UP(to->frac); + while (!*buf1 && (to->intg > DIG_PER_DEC1)) + { + buf1++; + to->intg-= DIG_PER_DEC1; + d_to_move--; + } + if (to->buf < buf1) + { + dec1 *cur_d= to->buf; + for (; d_to_move; d_to_move--, cur_d++, buf1++) + *cur_d= *buf1; + } return error; } |