mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Bug #45360: wrong results
Propagation of a large unsigned numeric constant in the WHERE expression led to wrong result. For example, "WHERE a = CAST(0xFFFFFFFFFFFFFFFF AS USIGNED) AND FOO(a)", where a is an UNSIGNED BIGINT, and FOO() accepts strings, was transformed to "... AND FOO('-1')". That has been fixed. Also EXPLAIN EXTENDED printed incorrect numeric constants in transformed WHERE expressions like above. That has been fixed too. mysql-test/r/bigint.result: Added test case for bug #45360. mysql-test/t/bigint.test: Added test case for bug #45360. sql/item.cc: Bug #45360: wrong results As far as Item_int_with_ref (and underlaying Item_int) class accepts both signed and unsigned 64bit values, Item_int::val_str and Item_int::print methods have been modified to take into account unsigned_flag.
This commit is contained in:
parent
1935327e74
commit
936ed6ca86
3 changed files with 71 additions and 2 deletions
|
@ -404,3 +404,37 @@ describe t1;
|
|||
Field Type Null Key Default Extra
|
||||
bi decimal(19,0) NO 0
|
||||
drop table t1;
|
||||
#
|
||||
# Bug #45360: wrong results
|
||||
#
|
||||
CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
a BIGINT(20) UNSIGNED,
|
||||
b VARCHAR(20));
|
||||
INSERT INTO t1 (a) VALUES
|
||||
(0),
|
||||
(CAST(0x7FFFFFFFFFFFFFFF AS UNSIGNED)),
|
||||
(CAST(0x8000000000000000 AS UNSIGNED)),
|
||||
(CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
|
||||
UPDATE t1 SET b = a;
|
||||
# FFFFFFFFFFFFFFFF
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 18446744073709551615 AND TRIM(a) = b;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 18446744073709551615) and ('18446744073709551615' = `test`.`t1`.`b`))
|
||||
# 8000000000000000
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 9223372036854775808 AND TRIM(a) = b;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 9223372036854775808) and ('9223372036854775808' = `test`.`t1`.`b`))
|
||||
# 7FFFFFFFFFFFFFFF
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 9223372036854775807 AND TRIM(a) = b;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 9223372036854775807) and ('9223372036854775807' = `test`.`t1`.`b`))
|
||||
# 0
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 0 AND TRIM(a) = b;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 0) and ('0' = `test`.`t1`.`b`))
|
||||
DROP TABLE t1;
|
||||
# End of 5.1 tests
|
||||
|
|
|
@ -327,3 +327,38 @@ drop table t1;
|
|||
create table t1 select -9223372036854775809 bi;
|
||||
describe t1;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug #45360: wrong results
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
a BIGINT(20) UNSIGNED,
|
||||
b VARCHAR(20));
|
||||
|
||||
INSERT INTO t1 (a) VALUES
|
||||
(0),
|
||||
(CAST(0x7FFFFFFFFFFFFFFF AS UNSIGNED)),
|
||||
(CAST(0x8000000000000000 AS UNSIGNED)),
|
||||
(CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
|
||||
|
||||
UPDATE t1 SET b = a;
|
||||
|
||||
let $n = `SELECT MAX(id) FROM t1`;
|
||||
while($n) {
|
||||
let $x = `SELECT a FROM t1 WHERE id = $n`;
|
||||
dec $n;
|
||||
let $hex = `SELECT HEX($x)`;
|
||||
echo # $hex;
|
||||
|
||||
--disable_result_log
|
||||
eval EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = $x AND TRIM(a) = b;
|
||||
--enable_result_log
|
||||
SHOW WARNINGS;
|
||||
}
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 5.1 tests
|
||||
|
||||
|
||||
|
|
|
@ -2209,14 +2209,14 @@ String *Item_int::val_str(String *str)
|
|||
{
|
||||
// following assert is redundant, because fixed=1 assigned in constructor
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
str->set(value, &my_charset_bin);
|
||||
str->set_int(value, unsigned_flag, &my_charset_bin);
|
||||
return str;
|
||||
}
|
||||
|
||||
void Item_int::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
// my_charset_bin is good enough for numbers
|
||||
str_value.set(value, &my_charset_bin);
|
||||
str_value.set_int(value, unsigned_flag, &my_charset_bin);
|
||||
str->append(str_value);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue