mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-17256 Decimal field multiplication bug.
We should clear trailing zeroes in frac part. Otherwise that tail is growing quickly and forces unnecessary truncating of arguments.
This commit is contained in:
parent
65cfc5873e
commit
57898316b6
3 changed files with 105 additions and 16 deletions
|
@ -1997,3 +1997,45 @@ select 0.0000000001 mod 1;
|
|||
select 0.01 mod 1;
|
||||
0.01 mod 1
|
||||
0.01
|
||||
CREATE TABLE t1 (
|
||||
`FLD1` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD2` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD3` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD4` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD5` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD6` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD7` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD8` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD9` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD10` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD11` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD12` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD13` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD14` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD15` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD16` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD17` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD18` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD19` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD20` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD21` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD22` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD23` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000
|
||||
);
|
||||
INSERT INTO t1 VALUES (001.0760,000.9500,001.0000,001.0000,001.0000,
|
||||
001.0000,001.0000,001.0000,001.0000,001.0000,001.0000,000.5949,001.0194,
|
||||
001.0000,001.0000,001.0000,001.0000,001.0000,001.0000,000.9220,001.1890,001.2130,327.2690);
|
||||
select FLD1*FLD2*FLD3*FLD4*FLD5*FLD6*FLD7*FLD8*FLD9*FLD10*FLD11*FLD12*FLD13*FLD14*FLD15*FLD16*FLD17*FLD18*FLD19*FLD20*FLD21*FLD22*FLD23 as calc1 from t1;
|
||||
calc1
|
||||
269.775757576440530322187032000000
|
||||
select FLD23*FLD2*FLD1*FLD4*FLD5*FLD11*FLD12*FLD13*FLD3*FLD15*FLD16*FLD17*FLD18*FLD19*FLD20*FLD21*FLD22*FLD14*FLD6*FLD7*FLD8*FLD9*FLD10 as calc2 from t1;
|
||||
calc2
|
||||
269.775757576440530322187032000000
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 AS SELECT 1.0 * 2.000;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`1.0 * 2.000` decimal(6,4) NOT NULL DEFAULT '0.0000'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1581,3 +1581,47 @@ select 0.000000000000000000000000000000000000000000000000001 mod 1;
|
|||
select 0.0000000001 mod 1;
|
||||
select 0.01 mod 1;
|
||||
|
||||
#
|
||||
# MDEV-17256 Decimal field multiplication bug
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
`FLD1` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD2` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD3` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD4` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD5` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD6` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD7` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD8` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD9` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD10` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD11` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD12` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD13` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD14` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD15` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD16` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD17` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD18` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD19` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD20` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD21` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD22` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000,
|
||||
`FLD23` decimal(7,4) unsigned zerofill NOT NULL DEFAULT 001.0000
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (001.0760,000.9500,001.0000,001.0000,001.0000,
|
||||
001.0000,001.0000,001.0000,001.0000,001.0000,001.0000,000.5949,001.0194,
|
||||
001.0000,001.0000,001.0000,001.0000,001.0000,001.0000,000.9220,001.1890,001.2130,327.2690);
|
||||
|
||||
select FLD1*FLD2*FLD3*FLD4*FLD5*FLD6*FLD7*FLD8*FLD9*FLD10*FLD11*FLD12*FLD13*FLD14*FLD15*FLD16*FLD17*FLD18*FLD19*FLD20*FLD21*FLD22*FLD23 as calc1 from t1;
|
||||
select FLD23*FLD2*FLD1*FLD4*FLD5*FLD11*FLD12*FLD13*FLD3*FLD15*FLD16*FLD17*FLD18*FLD19*FLD20*FLD21*FLD22*FLD14*FLD6*FLD7*FLD8*FLD9*FLD10 as calc2 from t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 AS SELECT 1.0 * 2.000;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
|
|
|
@ -2077,26 +2077,21 @@ int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
|
|||
}
|
||||
}
|
||||
|
||||
/* Now we have to check for -0.000 case */
|
||||
if (to->sign)
|
||||
/* Remove trailing zero words in frac part */
|
||||
frac0= ROUND_UP(to->frac);
|
||||
|
||||
if (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0)
|
||||
{
|
||||
dec1 *buf= to->buf;
|
||||
dec1 *end= to->buf + intg0 + frac0;
|
||||
DBUG_ASSERT(buf != end);
|
||||
for (;;)
|
||||
do
|
||||
{
|
||||
if (*buf)
|
||||
break;
|
||||
if (++buf == end)
|
||||
{
|
||||
/* We got decimal zero */
|
||||
decimal_make_zero(to);
|
||||
break;
|
||||
}
|
||||
}
|
||||
frac0--;
|
||||
} while (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0);
|
||||
to->frac= DIG_PER_DEC1 * frac0;
|
||||
}
|
||||
|
||||
/* Remove heading zero words in intg part */
|
||||
buf1= to->buf;
|
||||
d_to_move= intg0 + ROUND_UP(to->frac);
|
||||
d_to_move= intg0 + frac0;
|
||||
while (!*buf1 && (to->intg > DIG_PER_DEC1))
|
||||
{
|
||||
buf1++;
|
||||
|
@ -2109,6 +2104,14 @@ int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
|
|||
for (; d_to_move--; cur_d++, buf1++)
|
||||
*cur_d= *buf1;
|
||||
}
|
||||
|
||||
/* Now we have to check for -0.000 case */
|
||||
if (to->sign && to->frac == 0 && to->buf[0] == 0)
|
||||
{
|
||||
DBUG_ASSERT(to->intg <= DIG_PER_DEC1);
|
||||
/* We got decimal zero */
|
||||
decimal_make_zero(to);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue