mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Manual merge.
This commit is contained in:
@ -98,7 +98,7 @@ explain extended select pi(),format(sin(pi()/2),6),format(cos(pi()/2),6),format(
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select pi() AS `pi()`,format(sin((pi() / 2)),6) AS `format(sin(pi()/2),6)`,format(cos((pi() / 2)),6) AS `format(cos(pi()/2),6)`,format(abs(tan(pi())),6) AS `format(abs(tan(pi())),6)`,format((1 / tan(1)),6) AS `format(cot(1),6)`,format(asin(1),6) AS `format(asin(1),6)`,format(acos(0),6) AS `format(acos(0),6)`,format(atan(1),6) AS `format(atan(1),6)`
|
||||
Note 1003 select pi() AS `pi()`,format(sin((pi() / 2)),6) AS `format(sin(pi()/2),6)`,format(cos((pi() / 2)),6) AS `format(cos(pi()/2),6)`,format(abs(tan(pi())),6) AS `format(abs(tan(pi())),6)`,format(cot(1),6) AS `format(cot(1),6)`,format(asin(1),6) AS `format(asin(1),6)`,format(acos(0),6) AS `format(acos(0),6)`,format(atan(1),6) AS `format(atan(1),6)`
|
||||
select degrees(pi()),radians(360);
|
||||
degrees(pi()) radians(360)
|
||||
180 6.283185307179586
|
||||
@ -451,23 +451,17 @@ SELECT 1 FROM (SELECT ROUND(f1, f1) AS a FROM t1) AS s WHERE a LIKE 'a';
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
SELECT 1e308 + 1e308;
|
||||
1e308 + 1e308
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e308 + 1e308)'
|
||||
SELECT -1e308 - 1e308;
|
||||
-1e308 - 1e308
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in '(-(1e308) - 1e308)'
|
||||
SELECT 1e300 * 1e300;
|
||||
1e300 * 1e300
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e300 * 1e300)'
|
||||
SELECT 1e300 / 1e-300;
|
||||
1e300 / 1e-300
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e300 / 1e-300)'
|
||||
SELECT EXP(750);
|
||||
EXP(750)
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in 'exp(750)'
|
||||
SELECT POW(10, 309);
|
||||
POW(10, 309)
|
||||
NULL
|
||||
ERROR 22003: DOUBLE value is out of range in 'pow(10,309)'
|
||||
#
|
||||
# Bug #44768: SIGFPE crash when selecting rand from a view
|
||||
# containing null
|
||||
@ -488,11 +482,121 @@ RAND(i)
|
||||
DROP TABLE t1;
|
||||
#
|
||||
select 123456789012345678901234567890.123456789012345678901234567890 div 1 as x;
|
||||
ERROR 22003: Out of range value for column 'x' at row 1
|
||||
ERROR 22003: BIGINT value is out of range in '(123456789012345678901234567890.123456789012345678901234567890 DIV 1)'
|
||||
select "123456789012345678901234567890.123456789012345678901234567890" div 1 as x;
|
||||
ERROR 22003: Out of range value for column 'x' at row 1
|
||||
ERROR 22003: BIGINT value is out of range in '('123456789012345678901234567890.123456789012345678901234567890' DIV 1)'
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1292 Truncated incorrect DECIMAL value: ''
|
||||
Error 1264 Out of range value for column 'x' at row 1
|
||||
Error 1690 BIGINT value is out of range in '('123456789012345678901234567890.123456789012345678901234567890' DIV 1)'
|
||||
End of 5.1 tests
|
||||
#
|
||||
# Bug #8433: Overflow must be an error
|
||||
#
|
||||
SELECT 1e308 + 1e308;
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e308 + 1e308)'
|
||||
SELECT -1e308 - 1e308;
|
||||
ERROR 22003: DOUBLE value is out of range in '(-(1e308) - 1e308)'
|
||||
SELECT 1e300 * 1e300;
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e300 * 1e300)'
|
||||
SELECT 1e300 / 1e-300;
|
||||
ERROR 22003: DOUBLE value is out of range in '(1e300 / 1e-300)'
|
||||
SELECT EXP(750);
|
||||
ERROR 22003: DOUBLE value is out of range in 'exp(750)'
|
||||
SELECT POW(10, 309);
|
||||
ERROR 22003: DOUBLE value is out of range in 'pow(10,309)'
|
||||
SELECT COT(0);
|
||||
ERROR 22003: DOUBLE value is out of range in 'cot(0)'
|
||||
SELECT DEGREES(1e307);
|
||||
ERROR 22003: DOUBLE value is out of range in 'degrees(1e307)'
|
||||
SELECT 9223372036854775808 + 9223372036854775808;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 + 9223372036854775808)'
|
||||
SELECT 18446744073709551615 + 1;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)'
|
||||
SELECT 1 + 18446744073709551615;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(1 + 18446744073709551615)'
|
||||
SELECT -2 + CAST(1 AS UNSIGNED);
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(-(2) + cast(1 as unsigned))'
|
||||
SELECT CAST(1 AS UNSIGNED) + -2;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(cast(1 as unsigned) + -(2))'
|
||||
SELECT -9223372036854775808 + -9223372036854775808;
|
||||
ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) + -(9223372036854775808))'
|
||||
SELECT 9223372036854775807 + 9223372036854775807;
|
||||
ERROR 22003: BIGINT value is out of range in '(9223372036854775807 + 9223372036854775807)'
|
||||
SELECT CAST(0 AS UNSIGNED) - 9223372036854775809;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 9223372036854775809)'
|
||||
SELECT 9223372036854775808 - 9223372036854775809;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 - 9223372036854775809)'
|
||||
SELECT CAST(1 AS UNSIGNED) - 2;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(cast(1 as unsigned) - 2)'
|
||||
SELECT 18446744073709551615 - (-1);
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 - -(1))'
|
||||
SELECT -1 - 9223372036854775808;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(-(1) - 9223372036854775808)'
|
||||
SELECT -1 - CAST(1 AS UNSIGNED);
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(-(1) - cast(1 as unsigned))'
|
||||
SELECT -9223372036854775808 - 1;
|
||||
ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) - 1)'
|
||||
SELECT 9223372036854775807 - -9223372036854775808;
|
||||
ERROR 22003: BIGINT value is out of range in '(9223372036854775807 - -(9223372036854775808))'
|
||||
set SQL_MODE='NO_UNSIGNED_SUBTRACTION';
|
||||
SELECT 18446744073709551615 - 1;
|
||||
ERROR 22003: BIGINT value is out of range in '(18446744073709551615 - 1)'
|
||||
SELECT 18446744073709551615 - CAST(1 AS UNSIGNED);
|
||||
ERROR 22003: BIGINT value is out of range in '(18446744073709551615 - cast(1 as unsigned))'
|
||||
SELECT 18446744073709551614 - (-1);
|
||||
ERROR 22003: BIGINT value is out of range in '(18446744073709551614 - -(1))'
|
||||
SELECT 9223372036854775807 - -1;
|
||||
ERROR 22003: BIGINT value is out of range in '(9223372036854775807 - -(1))'
|
||||
set SQL_MODE=default;
|
||||
SELECT 4294967296 * 4294967296;
|
||||
ERROR 22003: BIGINT value is out of range in '(4294967296 * 4294967296)'
|
||||
SELECT 9223372036854775808 * 2;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 * 2)'
|
||||
SELECT 9223372036854775808 * 2;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 * 2)'
|
||||
SELECT 7158278827 * 3221225472;
|
||||
ERROR 22003: BIGINT value is out of range in '(7158278827 * 3221225472)'
|
||||
SELECT 9223372036854775807 * (-2);
|
||||
ERROR 22003: BIGINT value is out of range in '(9223372036854775807 * -(2))'
|
||||
SELECT CAST(1 as UNSIGNED) * (-1);
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(cast(1 as unsigned) * -(1))'
|
||||
SELECT 9223372036854775807 * 2;
|
||||
ERROR 22003: BIGINT value is out of range in '(9223372036854775807 * 2)'
|
||||
SELECT ABS(-9223372036854775808);
|
||||
ERROR 22003: BIGINT value is out of range in 'abs(-(9223372036854775808))'
|
||||
SELECT -9223372036854775808 DIV -1;
|
||||
ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) DIV -(1))'
|
||||
SELECT 18446744073709551615 DIV -1;
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 DIV -(1))'
|
||||
CREATE TABLE t1(a BIGINT, b BIGINT UNSIGNED);
|
||||
INSERT INTO t1 VALUES(-9223372036854775808, 9223372036854775809);
|
||||
SELECT -a FROM t1;
|
||||
ERROR 22003: BIGINT value is out of range in '-('-9223372036854775808')'
|
||||
SELECT -b FROM t1;
|
||||
ERROR 22003: BIGINT value is out of range in '-('9223372036854775809')'
|
||||
DROP TABLE t1;
|
||||
SET @a:=999999999999999999999999999999999999999999999999999999999999999999999999999999999;
|
||||
SELECT @a + @a;
|
||||
ERROR 22003: DECIMAL value is out of range in '((@a) + (@a))'
|
||||
SELECT @a * @a;
|
||||
ERROR 22003: DECIMAL value is out of range in '((@a) * (@a))'
|
||||
SELECT -@a - @a;
|
||||
ERROR 22003: DECIMAL value is out of range in '(-((@a)) - (@a))'
|
||||
SELECT @a / 0.5;
|
||||
ERROR 22003: DECIMAL value is out of range in '((@a) / 0.5)'
|
||||
SELECT COT(1/0);
|
||||
COT(1/0)
|
||||
NULL
|
||||
SELECT -1 + 9223372036854775808;
|
||||
-1 + 9223372036854775808
|
||||
9223372036854775807
|
||||
SELECT 2 DIV -2;
|
||||
2 DIV -2
|
||||
-1
|
||||
SELECT -(1 DIV 0);
|
||||
-(1 DIV 0)
|
||||
NULL
|
||||
SELECT -9223372036854775808 MOD -1;
|
||||
-9223372036854775808 MOD -1
|
||||
0
|
||||
|
@ -25,9 +25,9 @@ length(uuid()) charset(uuid()) length(unhex(replace(uuid(),_utf8'-',_utf8'')))
|
||||
36 utf8 16
|
||||
set @a= uuid_short();
|
||||
set @b= uuid_short();
|
||||
select cast(@a - @b as signed);
|
||||
cast(@a - @b as signed)
|
||||
-1
|
||||
select @b - @a;
|
||||
@b - @a
|
||||
1
|
||||
select length(format('nan', 2)) > 0;
|
||||
length(format('nan', 2)) > 0
|
||||
1
|
||||
|
@ -63,8 +63,8 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select (10 % 7) AS `10 % 7`,(10 % 7) AS `10 mod 7`,(10 DIV 3) AS `10 div 3`
|
||||
select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
|
||||
(1 << 64)-1 ((1 << 64)-1) DIV 1 ((1 << 64)-1) DIV 2
|
||||
select 18446744073709551615, 18446744073709551615 DIV 1, 18446744073709551615 DIV 2;
|
||||
18446744073709551615 18446744073709551615 DIV 1 18446744073709551615 DIV 2
|
||||
18446744073709551615 18446744073709551615 9223372036854775807
|
||||
explain extended select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
|
@ -2426,27 +2426,28 @@ city
|
||||
London
|
||||
DROP TABLE t1;
|
||||
create table t1 (a int(11) unsigned, b int(11) unsigned);
|
||||
insert into t1 values (1,0), (1,1), (1,2);
|
||||
insert into t1 values (1,0), (1,1), (18446744073709551615,0);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'a' at row 3
|
||||
select a-b from t1 order by 1;
|
||||
a-b
|
||||
0
|
||||
1
|
||||
18446744073709551615
|
||||
4294967295
|
||||
select a-b , (a-b < 0) from t1 order by 1;
|
||||
a-b (a-b < 0)
|
||||
0 0
|
||||
1 0
|
||||
18446744073709551615 0
|
||||
4294967295 0
|
||||
select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0;
|
||||
d (a-b >= 0) b
|
||||
1 1 0
|
||||
0 1 1
|
||||
18446744073709551615 1 2
|
||||
select cast((a - b) as unsigned) from t1 order by 1;
|
||||
cast((a - b) as unsigned)
|
||||
0
|
||||
1
|
||||
18446744073709551615
|
||||
4294967295
|
||||
drop table t1;
|
||||
create table t1 (a int(11));
|
||||
select all all * from t1;
|
||||
@ -3419,6 +3420,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
|
||||
DROP TABLE t1,t2;
|
||||
SET SQL_MODE='NO_UNSIGNED_SUBTRACTION';
|
||||
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
|
||||
INSERT t1 SET i = 0;
|
||||
UPDATE t1 SET i = -1;
|
||||
@ -3438,8 +3440,9 @@ Warnings:
|
||||
Warning 1264 Out of range value for column 'i' at row 1
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
255
|
||||
0
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE=default;
|
||||
create table t1 (a int);
|
||||
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t2 (a int, b int, c int, e int, primary key(a,b,c));
|
||||
|
@ -6022,16 +6022,12 @@ select bug20777(9223372036854775810) as '9223372036854775810 2**63+2';
|
||||
9223372036854775810 2**63+2
|
||||
9223372036854775810
|
||||
select bug20777(-9223372036854775808) as 'lower bounds signed bigint';
|
||||
lower bounds signed bigint
|
||||
0
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'f1' at row 1
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(f1@0 - 10)'
|
||||
select bug20777(9223372036854775807) as 'upper bounds signed bigint';
|
||||
upper bounds signed bigint
|
||||
9223372036854775807
|
||||
select bug20777(0) as 'lower bounds unsigned bigint';
|
||||
lower bounds unsigned bigint
|
||||
0
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(f1@0 - 10)'
|
||||
select bug20777(18446744073709551615) as 'upper bounds unsigned bigint';
|
||||
upper bounds unsigned bigint
|
||||
18446744073709551615
|
||||
@ -6041,10 +6037,7 @@ upper bounds unsigned bigint + 1
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'f1' at row 1
|
||||
select bug20777(-1) as 'lower bounds unsigned bigint - 1';
|
||||
lower bounds unsigned bigint - 1
|
||||
0
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'f1' at row 1
|
||||
ERROR 22003: BIGINT UNSIGNED value is out of range in '(f1@0 - 10)'
|
||||
create table examplebug20777 as select
|
||||
0 as 'i',
|
||||
bug20777(9223372036854775806) as '2**63-2',
|
||||
@ -6053,15 +6046,10 @@ bug20777(9223372036854775808) as '2**63',
|
||||
bug20777(9223372036854775809) as '2**63+1',
|
||||
bug20777(18446744073709551614) as '2**64-2',
|
||||
bug20777(18446744073709551615) as '2**64-1',
|
||||
bug20777(18446744073709551616) as '2**64',
|
||||
bug20777(0) as '0',
|
||||
bug20777(-1) as '-1';
|
||||
bug20777(18446744073709551616) as '2**64';
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'f1' at row 1
|
||||
Warning 1264 Out of range value for column 'f1' at row 1
|
||||
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column '-1' at row 1
|
||||
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616);
|
||||
show create table examplebug20777;
|
||||
Table Create Table
|
||||
examplebug20777 CREATE TABLE `examplebug20777` (
|
||||
@ -6072,14 +6060,12 @@ examplebug20777 CREATE TABLE `examplebug20777` (
|
||||
`2**63+1` bigint(20) unsigned DEFAULT NULL,
|
||||
`2**64-2` bigint(20) unsigned DEFAULT NULL,
|
||||
`2**64-1` bigint(20) unsigned DEFAULT NULL,
|
||||
`2**64` bigint(20) unsigned DEFAULT NULL,
|
||||
`0` bigint(20) unsigned DEFAULT NULL,
|
||||
`-1` bigint(20) unsigned DEFAULT NULL
|
||||
`2**64` bigint(20) unsigned DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from examplebug20777 order by i;
|
||||
i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64 0 -1
|
||||
0 9223372036854775806 9223372036854775807 9223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 18446744073709551615 0 0
|
||||
1 9223372036854775806 9223372036854775807 223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 8446744073709551616 0 0
|
||||
i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64
|
||||
0 9223372036854775806 9223372036854775807 9223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 18446744073709551615
|
||||
1 9223372036854775806 9223372036854775807 223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 8446744073709551616
|
||||
drop table examplebug20777;
|
||||
select bug20777(18446744073709551613)+1;
|
||||
bug20777(18446744073709551613)+1
|
||||
|
@ -895,6 +895,7 @@ ERROR 22003: Out of range value for column 'col1' at row 1
|
||||
INSERT INTO t1 (col2) VALUES ('-1.2E-3');
|
||||
ERROR 22003: Out of range value for column 'col2' at row 1
|
||||
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
|
||||
ERROR 22003: DOUBLE value is out of range in '("test"."t1"."col1" * 5000)'
|
||||
UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
|
||||
ERROR 22012: Division by 0
|
||||
UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0;
|
||||
@ -922,10 +923,10 @@ SELECT * FROM t1;
|
||||
col1 col2
|
||||
-2.2e-307 0
|
||||
1e-303 0
|
||||
NULL 1.7e308
|
||||
1.7e308 1.7e308
|
||||
-2.2e-307 0
|
||||
-2e-307 0
|
||||
NULL 1.7e308
|
||||
1.7e308 1.7e308
|
||||
0 NULL
|
||||
2 NULL
|
||||
NULL NULL
|
||||
|
@ -1385,11 +1385,7 @@ Warning 1264 Out of range value for column 'c1' at row 1
|
||||
insert into t1 values(
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: ''
|
||||
Warning 1292 Truncated incorrect DECIMAL value: ''
|
||||
Warning 1292 Truncated incorrect DECIMAL value: ''
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
ERROR 22003: DECIMAL value is out of range in '(99999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999)'
|
||||
insert into t1 values(1e100);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
@ -1397,7 +1393,6 @@ select * from t1;
|
||||
c1
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
drop table t1;
|
||||
create table t1(a decimal(7,2));
|
||||
insert into t1 values(123.12);
|
||||
|
@ -14,9 +14,9 @@ SET @@global.sql_slave_skip_counter = 2147483648*2;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sql_slave_skip_counter value: '4294967296'
|
||||
SET @@global.sql_slave_skip_counter = 2147483648*2-1;
|
||||
SET @@global.sql_slave_skip_counter = 4294967295*4294967295;
|
||||
SET @@global.sql_slave_skip_counter = 18446744065119617025;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sql_slave_skip_counter value: '-8589934591'
|
||||
Warning 1292 Truncated incorrect sql_slave_skip_counter value: '18446744065119617025'
|
||||
'#--------------------FN_DYNVARS_165_03-------------------------#'
|
||||
SET @@global.sql_slave_skip_counter = '5';
|
||||
ERROR 42000: Incorrect argument type to variable 'sql_slave_skip_counter'
|
||||
|
@ -56,7 +56,7 @@ SET @@global.sql_slave_skip_counter = 1024;
|
||||
SET @@global.sql_slave_skip_counter = 2147483648;
|
||||
SET @@global.sql_slave_skip_counter = 2147483648*2;
|
||||
SET @@global.sql_slave_skip_counter = 2147483648*2-1;
|
||||
SET @@global.sql_slave_skip_counter = 4294967295*4294967295;
|
||||
SET @@global.sql_slave_skip_counter = 18446744065119617025;
|
||||
|
||||
--echo '#--------------------FN_DYNVARS_165_03-------------------------#'
|
||||
###################################################################
|
||||
|
@ -283,12 +283,20 @@ DROP TABLE t1;
|
||||
#
|
||||
# Bug #31236: Inconsistent division by zero behavior for floating point numbers
|
||||
#
|
||||
# After the fix for bug #8433 we throw an error in the below test cases
|
||||
# rather than just return a NULL value.
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e308 + 1e308;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -1e308 - 1e308;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e300 * 1e300;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e300 / 1e-300;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT EXP(750);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT POW(10, 309);
|
||||
|
||||
--echo #
|
||||
@ -314,10 +322,139 @@ DROP TABLE t1;
|
||||
# DIV returns incorrect result with large decimal value
|
||||
# Bug #46606:Casting error for large numbers in 5.4 when 'div' is used
|
||||
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
select 123456789012345678901234567890.123456789012345678901234567890 div 1 as x;
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
select "123456789012345678901234567890.123456789012345678901234567890" div 1 as x;
|
||||
SHOW WARNINGS;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
--echo #
|
||||
--echo # Bug #8433: Overflow must be an error
|
||||
--echo #
|
||||
|
||||
# Floating point overflows
|
||||
# ========================
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e308 + 1e308;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -1e308 - 1e308;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e300 * 1e300;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1e300 / 1e-300;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT EXP(750);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT POW(10, 309);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT COT(0);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT DEGREES(1e307);
|
||||
|
||||
# Integer overflows
|
||||
# =================
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775808 + 9223372036854775808;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551615 + 1;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 1 + 18446744073709551615;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -2 + CAST(1 AS UNSIGNED);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT CAST(1 AS UNSIGNED) + -2;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -9223372036854775808 + -9223372036854775808;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775807 + 9223372036854775807;
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT CAST(0 AS UNSIGNED) - 9223372036854775809;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775808 - 9223372036854775809;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT CAST(1 AS UNSIGNED) - 2;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551615 - (-1);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -1 - 9223372036854775808;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -1 - CAST(1 AS UNSIGNED);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -9223372036854775808 - 1;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775807 - -9223372036854775808;
|
||||
|
||||
# To test SIGNED overflow when subtraction arguments are both UNSIGNED
|
||||
set SQL_MODE='NO_UNSIGNED_SUBTRACTION';
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551615 - 1;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551615 - CAST(1 AS UNSIGNED);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551614 - (-1);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775807 - -1;
|
||||
set SQL_MODE=default;
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 4294967296 * 4294967296;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775808 * 2;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775808 * 2;
|
||||
# The following one triggers condition #3 from the comments in
|
||||
# Item_func_mul::int_op()
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 7158278827 * 3221225472;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775807 * (-2);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT CAST(1 as UNSIGNED) * (-1);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 9223372036854775807 * 2;
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT ABS(-9223372036854775808);
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -9223372036854775808 DIV -1;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT 18446744073709551615 DIV -1;
|
||||
|
||||
|
||||
# Have to create a table because the negation op may convert literals to DECIMAL
|
||||
CREATE TABLE t1(a BIGINT, b BIGINT UNSIGNED);
|
||||
INSERT INTO t1 VALUES(-9223372036854775808, 9223372036854775809);
|
||||
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -a FROM t1;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -b FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# Decimal overflows
|
||||
# =================
|
||||
|
||||
SET @a:=999999999999999999999999999999999999999999999999999999999999999999999999999999999;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT @a + @a;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT @a * @a;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT -@a - @a;
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
SELECT @a / 0.5;
|
||||
|
||||
# Non-overflow tests to improve code coverage
|
||||
# ===========================================
|
||||
SELECT COT(1/0);
|
||||
SELECT -1 + 9223372036854775808;
|
||||
SELECT 2 DIV -2;
|
||||
SELECT -(1 DIV 0);
|
||||
# Crashed the server with SIGFPE before the bugfix
|
||||
SELECT -9223372036854775808 MOD -1;
|
||||
|
@ -22,7 +22,7 @@ select length(uuid()), charset(uuid()), length(unhex(replace(uuid(),_utf8'-',_ut
|
||||
# between two calls should be -1
|
||||
set @a= uuid_short();
|
||||
set @b= uuid_short();
|
||||
select cast(@a - @b as signed);
|
||||
select @b - @a;
|
||||
|
||||
#
|
||||
# Test for core dump with nan
|
||||
|
@ -24,7 +24,7 @@ select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
|
||||
select 1 like 2 xor 2 like 1;
|
||||
select 10 % 7, 10 mod 7, 10 div 3;
|
||||
explain extended select 10 % 7, 10 mod 7, 10 div 3;
|
||||
select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
|
||||
select 18446744073709551615, 18446744073709551615 DIV 1, 18446744073709551615 DIV 2;
|
||||
explain extended select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
|
||||
|
||||
create table t1 (a int);
|
||||
|
@ -1989,7 +1989,7 @@ DROP TABLE t1;
|
||||
#
|
||||
|
||||
create table t1 (a int(11) unsigned, b int(11) unsigned);
|
||||
insert into t1 values (1,0), (1,1), (1,2);
|
||||
insert into t1 values (1,0), (1,1), (18446744073709551615,0);
|
||||
select a-b from t1 order by 1;
|
||||
select a-b , (a-b < 0) from t1 order by 1;
|
||||
select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0;
|
||||
@ -2910,6 +2910,7 @@ DROP TABLE t1,t2;
|
||||
# cases to prevent fixing this accidently. It is intended behaviour)
|
||||
#
|
||||
|
||||
SET SQL_MODE='NO_UNSIGNED_SUBTRACTION';
|
||||
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
|
||||
INSERT t1 SET i = 0;
|
||||
UPDATE t1 SET i = -1;
|
||||
@ -2919,6 +2920,7 @@ SELECT * FROM t1;
|
||||
UPDATE t1 SET i = i - 1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE=default;
|
||||
|
||||
# BUG#17379
|
||||
|
||||
|
@ -7076,11 +7076,14 @@ select bug20777(9223372036854775807) as '9223372036854775807 2**63-1';
|
||||
select bug20777(9223372036854775808) as '9223372036854775808 2**63+0';
|
||||
select bug20777(9223372036854775809) as '9223372036854775809 2**63+1';
|
||||
select bug20777(9223372036854775810) as '9223372036854775810 2**63+2';
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
select bug20777(-9223372036854775808) as 'lower bounds signed bigint';
|
||||
select bug20777(9223372036854775807) as 'upper bounds signed bigint';
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
select bug20777(0) as 'lower bounds unsigned bigint';
|
||||
select bug20777(18446744073709551615) as 'upper bounds unsigned bigint';
|
||||
select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1';
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
select bug20777(-1) as 'lower bounds unsigned bigint - 1';
|
||||
|
||||
create table examplebug20777 as select
|
||||
@ -7091,10 +7094,8 @@ create table examplebug20777 as select
|
||||
bug20777(9223372036854775809) as '2**63+1',
|
||||
bug20777(18446744073709551614) as '2**64-2',
|
||||
bug20777(18446744073709551615) as '2**64-1',
|
||||
bug20777(18446744073709551616) as '2**64',
|
||||
bug20777(0) as '0',
|
||||
bug20777(-1) as '-1';
|
||||
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1);
|
||||
bug20777(18446744073709551616) as '2**64';
|
||||
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616);
|
||||
show create table examplebug20777;
|
||||
select * from examplebug20777 order by i;
|
||||
|
||||
|
@ -822,6 +822,7 @@ INSERT INTO t1 (col2) VALUES (-1.1E-3);
|
||||
INSERT INTO t1 (col1) VALUES ('+1.8E+309');
|
||||
--error 1264
|
||||
INSERT INTO t1 (col2) VALUES ('-1.2E-3');
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
|
||||
--error 1365
|
||||
UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
|
||||
|
@ -1090,6 +1090,7 @@ create table t1 (c1 decimal(64));
|
||||
--disable_ps_protocol
|
||||
insert into t1 values(
|
||||
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
|
||||
--error ER_DATA_OUT_OF_RANGE
|
||||
insert into t1 values(
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
|
||||
|
@ -2946,9 +2946,7 @@ Create_func_cot Create_func_cot::s_singleton;
|
||||
Item*
|
||||
Create_func_cot::create(THD *thd, Item *arg1)
|
||||
{
|
||||
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
|
||||
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
|
||||
return new (thd->mem_root) Item_func_div(i1, i2);
|
||||
return new (thd->mem_root) Item_func_cot(arg1);
|
||||
}
|
||||
|
||||
|
||||
|
328
sql/item_func.cc
328
sql/item_func.cc
@ -65,6 +65,14 @@ eval_const_cond(COND *cond)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test if the sum of arguments overflows the ulonglong range.
|
||||
*/
|
||||
static inline bool test_if_sum_overflows_ull(ulonglong arg1, ulonglong arg2)
|
||||
{
|
||||
return ULONGLONG_MAX - arg1 < arg2;
|
||||
}
|
||||
|
||||
void Item_func::set_arguments(List<Item> &list)
|
||||
{
|
||||
allowed_arg_cols= 1;
|
||||
@ -1094,16 +1102,68 @@ double Item_func_plus::real_op()
|
||||
double value= args[0]->val_real() + args[1]->val_real();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
return 0.0;
|
||||
return fix_result(value);
|
||||
return check_float_overflow(value);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_plus::int_op()
|
||||
{
|
||||
longlong value=args[0]->val_int()+args[1]->val_int();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
longlong val0= args[0]->val_int();
|
||||
longlong val1= args[1]->val_int();
|
||||
longlong res= val0 + val1;
|
||||
bool res_unsigned= FALSE;
|
||||
|
||||
if ((null_value= args[0]->null_value || args[1]->null_value))
|
||||
return 0;
|
||||
return value;
|
||||
|
||||
/*
|
||||
First check whether the result can be represented as a
|
||||
(bool unsigned_flag, longlong value) pair, then check if it is compatible
|
||||
with this Item's unsigned_flag by calling check_integer_overflow().
|
||||
*/
|
||||
if (args[0]->unsigned_flag)
|
||||
{
|
||||
if (args[1]->unsigned_flag || val1 >= 0)
|
||||
{
|
||||
if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) val1))
|
||||
goto err;
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* val1 is negative */
|
||||
if ((ulonglong) val0 > (ulonglong) LONGLONG_MAX)
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args[1]->unsigned_flag)
|
||||
{
|
||||
if (val0 >= 0)
|
||||
{
|
||||
if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) val1))
|
||||
goto err;
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ulonglong) val1 > (ulonglong) LONGLONG_MAX)
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val0 >=0 && val1 >= 0)
|
||||
res_unsigned= TRUE;
|
||||
else if (val0 < 0 && val1 < 0 && res >= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return check_integer_overflow(res, res_unsigned);
|
||||
|
||||
err:
|
||||
return raise_integer_overflow();
|
||||
}
|
||||
|
||||
|
||||
@ -1127,8 +1187,10 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
(my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
check_decimal_overflow(my_decimal_add(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value,
|
||||
val1, val2)) > 3)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
@ -1172,16 +1234,71 @@ double Item_func_minus::real_op()
|
||||
double value= args[0]->val_real() - args[1]->val_real();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
return 0.0;
|
||||
return fix_result(value);
|
||||
return check_float_overflow(value);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_minus::int_op()
|
||||
{
|
||||
longlong value=args[0]->val_int() - args[1]->val_int();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
longlong val0= args[0]->val_int();
|
||||
longlong val1= args[1]->val_int();
|
||||
longlong res= val0 - val1;
|
||||
bool res_unsigned= FALSE;
|
||||
|
||||
if ((null_value= args[0]->null_value || args[1]->null_value))
|
||||
return 0;
|
||||
return value;
|
||||
|
||||
/*
|
||||
First check whether the result can be represented as a
|
||||
(bool unsigned_flag, longlong value) pair, then check if it is compatible
|
||||
with this Item's unsigned_flag by calling check_integer_overflow().
|
||||
*/
|
||||
if (args[0]->unsigned_flag)
|
||||
{
|
||||
if (args[1]->unsigned_flag)
|
||||
{
|
||||
if ((ulonglong) val0 < (ulonglong) val1)
|
||||
{
|
||||
if (res >= 0)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val1 >= 0)
|
||||
{
|
||||
if ((ulonglong) val0 > (ulonglong) val1)
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) -val1))
|
||||
goto err;
|
||||
res_unsigned= TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args[1]->unsigned_flag)
|
||||
{
|
||||
if ((ulonglong) (val0 - LONGLONG_MIN) < (ulonglong) val1)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val0 > 0 && val1 < 0)
|
||||
res_unsigned= TRUE;
|
||||
else if (val0 < 0 && val1 > 0 && res >= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return check_integer_overflow(res, res_unsigned);
|
||||
|
||||
err:
|
||||
return raise_integer_overflow();
|
||||
}
|
||||
|
||||
|
||||
@ -1199,8 +1316,10 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
(my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
(check_decimal_overflow(my_decimal_sub(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value, val1,
|
||||
val2)) > 3))))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
@ -1212,17 +1331,86 @@ double Item_func_mul::real_op()
|
||||
double value= args[0]->val_real() * args[1]->val_real();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
return 0.0;
|
||||
return fix_result(value);
|
||||
return check_float_overflow(value);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_mul::int_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
longlong value=args[0]->val_int()*args[1]->val_int();
|
||||
if ((null_value=args[0]->null_value || args[1]->null_value))
|
||||
longlong a= args[0]->val_int();
|
||||
longlong b= args[1]->val_int();
|
||||
longlong res;
|
||||
ulonglong res0, res1;
|
||||
ulong a0, a1, b0, b1;
|
||||
bool res_unsigned= FALSE;
|
||||
bool a_negative= FALSE, b_negative= FALSE;
|
||||
|
||||
if ((null_value= args[0]->null_value || args[1]->null_value))
|
||||
return 0;
|
||||
return value;
|
||||
|
||||
/*
|
||||
First check whether the result can be represented as a
|
||||
(bool unsigned_flag, longlong value) pair, then check if it is compatible
|
||||
with this Item's unsigned_flag by calling check_integer_overflow().
|
||||
|
||||
Let a = a1 * 2^32 + a0 and b = b1 * 2^32 + b0. Then
|
||||
a * b = (a1 * 2^32 + a0) * (b1 * 2^32 + b0) = a1 * b1 * 2^64 +
|
||||
+ (a1 * b0 + a0 * b1) * 2^32 + a0 * b0;
|
||||
We can determine if the above sum overflows the ulonglong range by
|
||||
sequentially checking the following conditions:
|
||||
1. If both a1 and b1 are non-zero.
|
||||
2. Otherwise, if (a1 * b0 + a0 * b1) is greater than ULONG_MAX.
|
||||
3. Otherwise, if (a1 * b0 + a0 * b1) * 2^32 + a0 * b0 is greater than
|
||||
ULONGLONG_MAX.
|
||||
|
||||
Since we also have to take the unsigned_flag for a and b into account,
|
||||
it is easier to first work with absolute values and set the
|
||||
correct sign later.
|
||||
*/
|
||||
if (!args[0]->unsigned_flag && a < 0)
|
||||
{
|
||||
a_negative= TRUE;
|
||||
a= -a;
|
||||
}
|
||||
if (!args[1]->unsigned_flag && b < 0)
|
||||
{
|
||||
b_negative= TRUE;
|
||||
b= -b;
|
||||
}
|
||||
|
||||
a0= 0xFFFFFFFFUL & a;
|
||||
a1= ((ulonglong) a) >> 32;
|
||||
b0= 0xFFFFFFFFUL & b;
|
||||
b1= ((ulonglong) b) >> 32;
|
||||
|
||||
if (a1 && b1)
|
||||
goto err;
|
||||
|
||||
res1= (ulonglong) a1 * b0 + (ulonglong) a0 * b1;
|
||||
if (res1 > 0xFFFFFFFFUL)
|
||||
goto err;
|
||||
|
||||
res1= res1 << 32;
|
||||
res0= (ulonglong) a0 * b0;
|
||||
|
||||
if (test_if_sum_overflows_ull(res1, res0))
|
||||
goto err;
|
||||
res= res1 + res0;
|
||||
|
||||
if (a_negative != b_negative)
|
||||
{
|
||||
if ((ulonglong) res > (ulonglong) LONGLONG_MIN + 1)
|
||||
goto err;
|
||||
res= -res;
|
||||
}
|
||||
else
|
||||
res_unsigned= TRUE;
|
||||
|
||||
return check_integer_overflow(res, res_unsigned);
|
||||
|
||||
err:
|
||||
return raise_integer_overflow();
|
||||
}
|
||||
|
||||
|
||||
@ -1237,8 +1425,10 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
(my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
(check_decimal_overflow(my_decimal_mul(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value, val1,
|
||||
val2)) > 3))))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
@ -1271,7 +1461,7 @@ double Item_func_div::real_op()
|
||||
signal_divide_by_null();
|
||||
return 0.0;
|
||||
}
|
||||
return fix_result(value/val2);
|
||||
return check_float_overflow(value/val2);
|
||||
}
|
||||
|
||||
|
||||
@ -1287,8 +1477,12 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if ((null_value= args[1]->null_value))
|
||||
return 0;
|
||||
if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
|
||||
val1, val2, prec_increment)) > 3)
|
||||
if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW &
|
||||
~E_DEC_DIV_ZERO,
|
||||
decimal_value,
|
||||
val1, val2,
|
||||
prec_increment))) > 3)
|
||||
{
|
||||
if (err == E_DEC_DIV_ZERO)
|
||||
signal_divide_by_null();
|
||||
@ -1379,22 +1573,35 @@ longlong Item_func_int_div::val_int()
|
||||
|
||||
if (my_decimal2int(E_DEC_FATAL_ERROR, &tmp, unsigned_flag, &res) &
|
||||
E_DEC_OVERFLOW)
|
||||
my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), name, 1);
|
||||
raise_integer_overflow();
|
||||
return res;
|
||||
}
|
||||
|
||||
longlong value=args[0]->val_int();
|
||||
longlong val2=args[1]->val_int();
|
||||
longlong val0=args[0]->val_int();
|
||||
longlong val1=args[1]->val_int();
|
||||
bool val0_negative, val1_negative, res_negative;
|
||||
ulonglong uval0, uval1, res;
|
||||
if ((null_value= (args[0]->null_value || args[1]->null_value)))
|
||||
return 0;
|
||||
if (val2 == 0)
|
||||
if (val1 == 0)
|
||||
{
|
||||
signal_divide_by_null();
|
||||
return 0;
|
||||
}
|
||||
return (unsigned_flag ?
|
||||
(ulonglong) value / (ulonglong) val2 :
|
||||
value / val2);
|
||||
|
||||
val0_negative= !args[0]->unsigned_flag && val0 < 0;
|
||||
val1_negative= !args[1]->unsigned_flag && val1 < 0;
|
||||
res_negative= val0_negative != val1_negative;
|
||||
uval0= (ulonglong) (val0_negative ? -val0 : val0);
|
||||
uval1= (ulonglong) (val1_negative ? -val1 : val1);
|
||||
res= uval0 / uval1;
|
||||
if (res_negative)
|
||||
{
|
||||
if (res > (ulonglong) LONGLONG_MAX)
|
||||
return raise_integer_overflow();
|
||||
res= (ulonglong) (-(longlong) res);
|
||||
}
|
||||
return check_integer_overflow(res, !res_negative);
|
||||
}
|
||||
|
||||
|
||||
@ -1413,26 +1620,32 @@ void Item_func_int_div::fix_length_and_dec()
|
||||
longlong Item_func_mod::int_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
longlong value= args[0]->val_int();
|
||||
longlong val2= args[1]->val_int();
|
||||
longlong result;
|
||||
longlong val0= args[0]->val_int();
|
||||
longlong val1= args[1]->val_int();
|
||||
bool val0_negative, val1_negative;
|
||||
ulonglong uval0, uval1;
|
||||
ulonglong res;
|
||||
|
||||
if ((null_value= args[0]->null_value || args[1]->null_value))
|
||||
return 0; /* purecov: inspected */
|
||||
if (val2 == 0)
|
||||
if (val1 == 0)
|
||||
{
|
||||
signal_divide_by_null();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args[0]->unsigned_flag)
|
||||
result= args[1]->unsigned_flag ?
|
||||
((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2;
|
||||
else
|
||||
result= args[1]->unsigned_flag ?
|
||||
value % ((ulonglong) val2) : value % val2;
|
||||
|
||||
return result;
|
||||
/*
|
||||
'%' is calculated by integer division internally. Since dividing
|
||||
LONGLONG_MIN by -1 generates SIGFPE, we calculate using unsigned values and
|
||||
then adjust the sign appropriately.
|
||||
*/
|
||||
val0_negative= !args[0]->unsigned_flag && val0 < 0;
|
||||
val1_negative= !args[1]->unsigned_flag && val1 < 0;
|
||||
uval0= (ulonglong) (val0_negative ? -val0 : val0);
|
||||
uval1= (ulonglong) (val1_negative ? -val1 : val1);
|
||||
res= uval0 % uval1;
|
||||
return check_integer_overflow(val0_negative ? -(longlong) res : res,
|
||||
!val0_negative);
|
||||
}
|
||||
|
||||
double Item_func_mod::real_op()
|
||||
@ -1502,8 +1715,12 @@ double Item_func_neg::real_op()
|
||||
longlong Item_func_neg::int_op()
|
||||
{
|
||||
longlong value= args[0]->val_int();
|
||||
null_value= args[0]->null_value;
|
||||
return -value;
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
if (args[0]->unsigned_flag &&
|
||||
(ulonglong) value > (ulonglong) LONGLONG_MAX + 1)
|
||||
return raise_integer_overflow();
|
||||
return check_integer_overflow(-value, !args[0]->unsigned_flag && value < 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1572,7 +1789,12 @@ longlong Item_func_abs::int_op()
|
||||
longlong value= args[0]->val_int();
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
return (value >= 0) || unsigned_flag ? value : -value;
|
||||
if (unsigned_flag)
|
||||
return value;
|
||||
/* -LONGLONG_MIN = LONGLONG_MAX + 1 => outside of signed longlong range */
|
||||
if (value == LONGLONG_MIN)
|
||||
return raise_integer_overflow();
|
||||
return (value >= 0) ? value : -value;
|
||||
}
|
||||
|
||||
|
||||
@ -1679,7 +1901,7 @@ double Item_func_exp::val_real()
|
||||
double value= args[0]->val_real();
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0.0; /* purecov: inspected */
|
||||
return fix_result(exp(value));
|
||||
return check_float_overflow(exp(value));
|
||||
}
|
||||
|
||||
double Item_func_sqrt::val_real()
|
||||
@ -1698,7 +1920,7 @@ double Item_func_pow::val_real()
|
||||
double val2= args[1]->val_real();
|
||||
if ((null_value=(args[0]->null_value || args[1]->null_value)))
|
||||
return 0.0; /* purecov: inspected */
|
||||
return fix_result(pow(value,val2));
|
||||
return check_float_overflow(pow(value,val2));
|
||||
}
|
||||
|
||||
// Trigonometric functions
|
||||
@ -1734,7 +1956,7 @@ double Item_func_atan::val_real()
|
||||
double val2= args[1]->val_real();
|
||||
if ((null_value=args[1]->null_value))
|
||||
return 0.0;
|
||||
return fix_result(atan2(value,val2));
|
||||
return check_float_overflow(atan2(value,val2));
|
||||
}
|
||||
return atan(value);
|
||||
}
|
||||
@ -1763,7 +1985,17 @@ double Item_func_tan::val_real()
|
||||
double value= args[0]->val_real();
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0.0;
|
||||
return fix_result(tan(value));
|
||||
return check_float_overflow(tan(value));
|
||||
}
|
||||
|
||||
|
||||
double Item_func_cot::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
double value= args[0]->val_real();
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0.0;
|
||||
return check_float_overflow(1.0 / tan(value));
|
||||
}
|
||||
|
||||
|
||||
@ -2238,7 +2470,7 @@ double Item_func_units::val_real()
|
||||
double value= args[0]->val_real();
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0;
|
||||
return value*mul+add;
|
||||
return check_float_overflow(value * mul + add);
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,13 +187,56 @@ public:
|
||||
void * arg, traverse_order order);
|
||||
bool is_expensive_processor(uchar *arg);
|
||||
virtual bool is_expensive() { return 0; }
|
||||
inline double fix_result(double value)
|
||||
inline void raise_numeric_overflow(const char *type_name)
|
||||
{
|
||||
if (isfinite(value))
|
||||
return value;
|
||||
null_value=1;
|
||||
char buf[256];
|
||||
String str(buf, sizeof(buf), system_charset_info);
|
||||
str.length(0);
|
||||
print(&str, QT_ORDINARY);
|
||||
my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe());
|
||||
}
|
||||
inline double raise_float_overflow()
|
||||
{
|
||||
raise_numeric_overflow("DOUBLE");
|
||||
return 0.0;
|
||||
}
|
||||
inline longlong raise_integer_overflow()
|
||||
{
|
||||
raise_numeric_overflow(unsigned_flag ? "BIGINT UNSIGNED": "BIGINT");
|
||||
return 0;
|
||||
}
|
||||
inline int raise_decimal_overflow()
|
||||
{
|
||||
raise_numeric_overflow("DECIMAL");
|
||||
return E_DEC_OVERFLOW;
|
||||
}
|
||||
/**
|
||||
Throw an error if the input double number is not finite, i.e. is either
|
||||
+/-INF or NAN.
|
||||
*/
|
||||
inline double check_float_overflow(double value)
|
||||
{
|
||||
return isfinite(value) ? value : raise_float_overflow();
|
||||
}
|
||||
/**
|
||||
Throw an error if the input BIGINT value represented by the
|
||||
(longlong value, bool unsigned flag) pair cannot be returned by the
|
||||
function, i.e. is not compatible with this Item's unsigned_flag.
|
||||
*/
|
||||
inline longlong check_integer_overflow(longlong value, bool val_unsigned)
|
||||
{
|
||||
if ((unsigned_flag && !val_unsigned && value < 0) ||
|
||||
(!unsigned_flag && val_unsigned && (ulonglong) value > LONGLONG_MAX))
|
||||
return raise_integer_overflow();
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
Throw an error if the error code of a DECIMAL operation is E_DEC_OVERFLOW.
|
||||
*/
|
||||
inline int check_decimal_overflow(int error)
|
||||
{
|
||||
return (error == E_DEC_OVERFLOW) ? raise_decimal_overflow() : error;
|
||||
}
|
||||
bool has_timestamp_args()
|
||||
{
|
||||
DBUG_ASSERT(fixed == TRUE);
|
||||
@ -667,6 +710,14 @@ public:
|
||||
const char *func_name() const { return "tan"; }
|
||||
};
|
||||
|
||||
class Item_func_cot :public Item_dec_func
|
||||
{
|
||||
public:
|
||||
Item_func_cot(Item *a) :Item_dec_func(a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "cot"; }
|
||||
};
|
||||
|
||||
class Item_func_integer :public Item_int_func
|
||||
{
|
||||
public:
|
||||
|
@ -6324,3 +6324,6 @@ ER_TOO_LONG_INDEX_COMMENT
|
||||
|
||||
ER_LOCK_ABORTED
|
||||
eng "Wait on a lock was aborted due to a pending exclusive lock"
|
||||
|
||||
ER_DATA_OUT_OF_RANGE 22003
|
||||
eng "%s value is out of range in '%s'"
|
||||
|
Reference in New Issue
Block a user