mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
Skip leading zeros when converting a string to decimal_t.
This commit is contained in:
@ -2342,6 +2342,50 @@ t1 CREATE TABLE `t1` (
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
|
||||
#
|
||||
SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
|
||||
val
|
||||
20.01
|
||||
SET sql_mode='';
|
||||
CREATE TABLE t1 (a TEXT);
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
|
||||
CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
|
||||
INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'd' at row 5
|
||||
Note 1265 Data truncated for column 'd' at row 6
|
||||
Note 1265 Data truncated for column 'd' at row 7
|
||||
INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'd' at row 5
|
||||
Note 1265 Data truncated for column 'd' at row 6
|
||||
Note 1265 Data truncated for column 'd' at row 7
|
||||
SELECT d, a FROM t2 ORDER BY d,a;
|
||||
d a
|
||||
-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
|
||||
-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
|
||||
-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
|
||||
-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
|
||||
-1.90 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
|
||||
-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
|
||||
1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
|
||||
1.90 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
|
||||
1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
|
||||
1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
|
||||
2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
|
||||
2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
|
||||
DROP TABLE t1, t2;
|
||||
SET sql_mode=DEFAULT;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
||||
#
|
||||
|
@ -1821,6 +1821,28 @@ CREATE TABLE t1 (a DECIMAL(2,1) DEFAULT 0.10001e0);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
|
||||
--echo #
|
||||
|
||||
SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
|
||||
|
||||
SET sql_mode='';
|
||||
CREATE TABLE t1 (a TEXT);
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
|
||||
INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
|
||||
CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
|
||||
INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
|
||||
INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
|
||||
SELECT d, a FROM t2 ORDER BY d,a;
|
||||
DROP TABLE t1, t2;
|
||||
SET sql_mode=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.1 tests
|
||||
--echo #
|
||||
|
@ -812,6 +812,24 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
|
||||
while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
|
||||
s++;
|
||||
intg= (int) (s-s1);
|
||||
/*
|
||||
If the integer part is long enough and it has multiple leading zeros,
|
||||
let's trim them, so this expression can return 1 without overflowing:
|
||||
CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10))
|
||||
*/
|
||||
if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0')
|
||||
{
|
||||
/*
|
||||
Keep at least one digit, to avoid an empty string.
|
||||
So we trim '0000' to '0' rather than to ''.
|
||||
Otherwise the below code (converting digits to to->buf)
|
||||
would fail on a fatal error.
|
||||
*/
|
||||
const char *iend= s - 1;
|
||||
for ( ; s1 < iend && *s1 == '0'; s1++)
|
||||
{ }
|
||||
intg= (int) (s-s1);
|
||||
}
|
||||
if (s < end_of_string && *s=='.')
|
||||
{
|
||||
endp= s+1;
|
||||
|
Reference in New Issue
Block a user