summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_newdecimal.result32
-rw-r--r--mysql-test/t/type_newdecimal.test22
-rw-r--r--strings/decimal.c16
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;
}