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
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
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
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -1821,6 +1821,28 @@ CREATE TABLE t1 (a DECIMAL(2,1) DEFAULT 0.10001e0);
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP 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 #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--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))
|
while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
|
||||||
s++;
|
s++;
|
||||||
intg= (int) (s-s1);
|
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=='.')
|
if (s < end_of_string && *s=='.')
|
||||||
{
|
{
|
||||||
endp= s+1;
|
endp= s+1;
|
||||||
|
Reference in New Issue
Block a user