MDEV-28001 greatest/least with bigint unsigned maxium has unexpected results compared to 0
LEAST() and GREATEST() erroneously calcucalted the result as signed for BIGINT UNSIGNED arguments. Adding a new method for unsigned arguments: Item_func_min_max::val_uint_native()
This commit is contained in:
parent
74184074a0
commit
ae0cbfe934
@ -4338,5 +4338,14 @@ SELECT * FROM t0 WHERE LEAST(c0, NULL);
|
|||||||
c0
|
c0
|
||||||
DROP TABLE t0;
|
DROP TABLE t0;
|
||||||
#
|
#
|
||||||
|
# MDEV-28001 greatest/least with bigint unsigned maxium has unexpected results compared to 0
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT UNSIGNED);
|
||||||
|
INSERT INTO t1 VALUES (18446744073709551615,0);
|
||||||
|
SELECT a,b, LEAST(a,b), GREATEST(a,b) FROM t1;
|
||||||
|
a b LEAST(a,b) GREATEST(a,b)
|
||||||
|
18446744073709551615 0 0 18446744073709551615
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
|
@ -1137,6 +1137,14 @@ SELECT * FROM t0 WHERE GREATEST(c0, NULL);
|
|||||||
SELECT * FROM t0 WHERE LEAST(c0, NULL);
|
SELECT * FROM t0 WHERE LEAST(c0, NULL);
|
||||||
DROP TABLE t0;
|
DROP TABLE t0;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28001 greatest/least with bigint unsigned maxium has unexpected results compared to 0
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT UNSIGNED);
|
||||||
|
INSERT INTO t1 VALUES (18446744073709551615,0);
|
||||||
|
SELECT a,b, LEAST(a,b), GREATEST(a,b) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
|
@ -3051,6 +3051,27 @@ longlong Item_func_min_max::val_int_native()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item_func_min_max::val_uint_native()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed);
|
||||||
|
ulonglong value= 0;
|
||||||
|
for (uint i=0; i < arg_count ; i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
value= (ulonglong) args[i]->val_int();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulonglong tmp= (ulonglong) args[i]->val_int();
|
||||||
|
if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
|
||||||
|
value= tmp;
|
||||||
|
}
|
||||||
|
if ((null_value= args[i]->null_value))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (longlong) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
|
my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
@ -2118,6 +2118,7 @@ public:
|
|||||||
String *val_str_native(String *str);
|
String *val_str_native(String *str);
|
||||||
double val_real_native();
|
double val_real_native();
|
||||||
longlong val_int_native();
|
longlong val_int_native();
|
||||||
|
longlong val_uint_native();
|
||||||
my_decimal *val_decimal_native(my_decimal *);
|
my_decimal *val_decimal_native(my_decimal *);
|
||||||
bool get_date_native(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
|
bool get_date_native(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
|
||||||
bool get_time_native(THD *thd, MYSQL_TIME *res);
|
bool get_time_native(THD *thd, MYSQL_TIME *res);
|
||||||
|
@ -6152,7 +6152,7 @@ longlong Type_handler_timestamp_common::
|
|||||||
longlong Type_handler_numeric::
|
longlong Type_handler_numeric::
|
||||||
Item_func_min_max_val_int(Item_func_min_max *func) const
|
Item_func_min_max_val_int(Item_func_min_max *func) const
|
||||||
{
|
{
|
||||||
return func->val_int_native();
|
return is_unsigned() ? func->val_uint_native() : func->val_int_native();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user