Bug#19955: unsigned bigint used as signed with MOD function

Problem:  When we have a really large number (between 2^63 and 2^64)
as the left side of the mod operator, it gets improperly corerced
into a signed value.

Solution:  Added check to see if the "negative" number is really
positive, and if so, cast it.
parent 2b3a69eb
...@@ -341,3 +341,14 @@ select * from t1 where bigint_col='17666000000000000000'; ...@@ -341,3 +341,14 @@ select * from t1 where bigint_col='17666000000000000000';
bigint_col bigint_col
17666000000000000000 17666000000000000000
drop table t1; drop table t1;
bug 19955 -- mod is signed with bigint
select cast(10000002383263201056 as unsigned) mod 50 as result;
result
6
create table t1 (c1 bigint unsigned);
insert into t1 values (10000002383263201056);
select c1 mod 50 as result from t1;
result
6
drop table t1;
...@@ -278,4 +278,13 @@ select * from t1 where bigint_col=17666000000000000000; ...@@ -278,4 +278,13 @@ select * from t1 where bigint_col=17666000000000000000;
select * from t1 where bigint_col='17666000000000000000'; select * from t1 where bigint_col='17666000000000000000';
drop table t1; drop table t1;
--echo
--echo bug 19955 -- mod is signed with bigint
select cast(10000002383263201056 as unsigned) mod 50 as result;
create table t1 (c1 bigint unsigned);
insert into t1 values (10000002383263201056);
select c1 mod 50 as result from t1;
drop table t1;
...@@ -1326,6 +1326,10 @@ longlong Item_func_mod::int_op() ...@@ -1326,6 +1326,10 @@ longlong Item_func_mod::int_op()
signal_divide_by_null(); signal_divide_by_null();
return 0; return 0;
} }
if (args[0]->unsigned_flag)
return ((ulonglong) value) % val2;
return value % val2; return value % val2;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment