mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-20305 Data loss on DOUBLE and DECIMAL conversion to INT
Bit operators (~ ^ | & << >>) and the function BIT_COUNT() always called val_int() for their arguments. It worked correctly only for INT type arguments. In case of DECIMAL and DOUBLE arguments it did not work well: the argument values were truncated to the maximum SIGNED BIGINT value of 9223372036854775807. Fixing the code as follows: - If the argument if of an integer data type, it works using val_int() as before. - If the argument if of some other data type, it gets the argument value using val_decimal(), to avoid truncation, and then converts the result to ulonglong. Using Item_handled_func to switch between the two approaches easier. As an additional advantage, with Item_handled_func it will be easier to implement overloading in the future, so data type plugings will be able to define their own behavioir of bit operators and BIT_COUNT(). Moving the code from the former val_int() implementations as methods to Longlong_null, to avoid code duplication in the INT and DECIMAL branches.
This commit is contained in:
@ -3071,7 +3071,7 @@ SELECT ((rpad(1.0,2048,1)) = ('4(') ^ (0.1));
|
||||
((rpad(1.0,2048,1)) = ('4(') ^ (0.1))
|
||||
0
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: '4('
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '4('
|
||||
SELECT
|
||||
pow((rpad(10.0,2048,1)),(b'1111111111111111111111111111111111111111111'));
|
||||
ERROR 22003: DOUBLE value is out of range in 'pow(rpad(10.0,2048,1),0x07ffffffffff)'
|
||||
@ -3079,7 +3079,7 @@ SELECT ((rpad(1.0,2048,1)) + (0) ^ ('../'));
|
||||
((rpad(1.0,2048,1)) + (0) ^ ('../'))
|
||||
1.011111111111111
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: '../'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '../'
|
||||
SELECT stddev_samp(rpad(1.0,2048,1));
|
||||
stddev_samp(rpad(1.0,2048,1))
|
||||
NULL
|
||||
|
Reference in New Issue
Block a user