mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	 79cdd7e76b
			
		
	
	
	79cdd7e76b
	
	
	
		
			
			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.
		
			
				
	
	
		
			97 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| --echo #
 | |
| --echo # Start of 10.5 tests
 | |
| --echo #
 | |
| 
 | |
| --echo #
 | |
| --echo # MDEV-20305 Data loss on DOUBLE and DECIMAL conversion to INT
 | |
| --echo #
 | |
| 
 | |
| DELIMITER $$;
 | |
| CREATE PROCEDURE p1(type VARCHAR(64), val VARCHAR(64))
 | |
| BEGIN
 | |
|   EXECUTE IMMEDIATE CONCAT('CREATE TABLE t1 (a ', type, ')');
 | |
|   SHOW CREATE TABLE t1;
 | |
|   EXECUTE IMMEDIATE CONCAT('INSERT INTO t1 VALUES (', val, ')');
 | |
|   SELECT
 | |
|     a,
 | |
|     ~a,
 | |
|     a & 18446744073709551615,
 | |
|     18446744073709551615 & a,
 | |
|     0 | a,
 | |
|     a | 0,
 | |
|     a << 0,
 | |
|     a >> 0,
 | |
|     a ^ 1,
 | |
|     1 ^ a,
 | |
|     BIT_COUNT(a)
 | |
|   FROM t1;
 | |
|   SHOW WARNINGS;
 | |
|   DROP TABLE t1;
 | |
| END;
 | |
| $$
 | |
| DELIMITER ;$$
 | |
| 
 | |
| --vertical_results
 | |
| CALL p1('BIGINT UNSIGNED', 18446744073709551615);
 | |
| CALL p1('DOUBLE',          18446744073709551615);
 | |
| CALL p1('DECIMAL(30,0)',   18446744073709551615);
 | |
| 
 | |
| CALL p1('BIGINT',          -1);
 | |
| CALL p1('DOUBLE',          -1);
 | |
| CALL p1('DECIMAL(30,0)',   -1);
 | |
| 
 | |
| CALL p1('BIGINT',          -9223372036854775808);
 | |
| CALL p1('DOUBLE',          -9223372036854775808);
 | |
| CALL p1('DECIMAL(30,0)',   -9223372036854775808);
 | |
| --horizontal_results
 | |
| 
 | |
| DROP PROCEDURE p1;
 | |
| 
 | |
| 
 | |
| SELECT CAST(CAST(18446744073709551615 AS UNSIGNED) AS DECIMAL(32))<<0 AS c1;
 | |
| SELECT CAST(CAST(18446744073709551615 AS UNSIGNED) AS DOUBLE)<<0 AS c1;
 | |
| 
 | |
| SELECT COALESCE(CAST(CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED) AS DECIMAL(32))) << 0 AS c1;
 | |
| SELECT COALESCE(CAST(CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED) AS DOUBLE)) << 0 AS c1;
 | |
| 
 | |
| SELECT 18446744073709551615 ^ 1 AS c1;
 | |
| SELECT 18446744073709551615.0 ^ 1 AS c1;
 | |
| SELECT 18446744073709551615e0 ^ 1 AS c1;
 | |
| 
 | |
| SELECT LAST_VALUE(18446744073709551615) ^ 1 AS c1;
 | |
| SELECT LAST_VALUE(18446744073709551615.0) ^ 1 AS c1;
 | |
| SELECT LAST_VALUE(18446744073709551615e0) ^ 1 AS c1;
 | |
| 
 | |
| SELECT 18446744073709551615 & 18446744073709551615 AS c1;
 | |
| SELECT 18446744073709551615 & 18446744073709551615.0 AS c1;
 | |
| SELECT 18446744073709551615 & 18446744073709551615e0 AS c1;
 | |
| SELECT 18446744073709551615.0 & 18446744073709551615 AS c1;
 | |
| SELECT 18446744073709551615.0 & 18446744073709551615.0 AS c1;
 | |
| SELECT 18446744073709551615.0 & 18446744073709551615e0 AS c1;
 | |
| SELECT 18446744073709551615e0 & 18446744073709551615 AS c1;
 | |
| SELECT 18446744073709551615e0 & 18446744073709551615.0 AS c1;
 | |
| SELECT 18446744073709551615e0 & 18446744073709551615e0 AS c1;
 | |
| 
 | |
| 
 | |
| SELECT 0 | 18446744073709551615 AS c1;
 | |
| SELECT 0 | 18446744073709551615.0 AS c1;
 | |
| SELECT 0 | 18446744073709551615e0 AS c1;
 | |
| SELECT 18446744073709551615 | 0 AS c1;
 | |
| SELECT 18446744073709551615.0 | 0 AS c1;
 | |
| SELECT 18446744073709551615e0 | 0 AS c1;
 | |
| 
 | |
| SELECT ~18446744073709551615 AS c1;
 | |
| SELECT ~18446744073709551615.0 AS c1;
 | |
| SELECT ~18446744073709551615e0 AS c1;
 | |
| 
 | |
| SELECT BIT_COUNT(18446744073709551615) AS c1;
 | |
| SELECT BIT_COUNT(18446744073709551615.0) AS c1;
 | |
| SELECT BIT_COUNT(18446744073709551615e0) AS c1;
 | |
| 
 | |
| SELECT BIT_COUNT(-9223372036854775808) AS c1;
 | |
| SELECT BIT_COUNT(-9223372036854775808.0) AS c1;
 | |
| SELECT BIT_COUNT(-9223372036854775808e0) AS c1;
 | |
| 
 | |
| --echo #
 | |
| --echo # End of 10.5 tests
 | |
| --echo #
 |