Commit 09b87d62 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8871 Wrong result for CREATE TABLE .. SELECT LEAST(unsigned_column,unsigned_column)

parent c13f4091
...@@ -377,5 +377,44 @@ id k c pad ...@@ -377,5 +377,44 @@ id k c pad
7 16 a xxx 7 16 a xxx
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-8871 Wrong result for CREATE TABLE .. SELECT LEAST(unsigned_column,unsigned_column)
#
CREATE TABLE t1 (a INT,b INT UNSIGNED);
INSERT INTO t1 VALUES (-2147483648,4294967295);
SELECT a, b, LEAST(a,a), LEAST(b,b), LEAST(a,b), LEAST(b,a), GREATEST(a,b), GREATEST(b,a) FROM t1;
a -2147483648
b 4294967295
LEAST(a,a) -2147483648
LEAST(b,b) 4294967295
LEAST(a,b) -2147483648
LEAST(b,a) -2147483648
GREATEST(a,b) 4294967295
GREATEST(b,a) 4294967295
CREATE TABLE t2 AS
SELECT a, b, LEAST(a,a), LEAST(b,b), LEAST(a,b), LEAST(b,a), GREATEST(a,b), GREATEST(b,a) FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL,
`b` int(10) unsigned DEFAULT NULL,
`LEAST(a,a)` int(11) DEFAULT NULL,
`LEAST(b,b)` int(10) unsigned DEFAULT NULL,
`LEAST(a,b)` decimal(10,0) DEFAULT NULL,
`LEAST(b,a)` decimal(10,0) DEFAULT NULL,
`GREATEST(a,b)` decimal(10,0) DEFAULT NULL,
`GREATEST(b,a)` decimal(10,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t2;
a -2147483648
b 4294967295
LEAST(a,a) -2147483648
LEAST(b,b) 4294967295
LEAST(a,b) -2147483648
LEAST(b,a) -2147483648
GREATEST(a,b) 4294967295
GREATEST(b,a) 4294967295
DROP TABLE t2;
DROP TABLE t1;
#
# End of 10.1 tests # End of 10.1 tests
# #
...@@ -220,6 +220,24 @@ SELECT * FROM t1 WHERE id XOR 0; ...@@ -220,6 +220,24 @@ SELECT * FROM t1 WHERE id XOR 0;
SELECT * FROM t1 IGNORE KEY(PRIMARY) WHERE id XOR 0; SELECT * FROM t1 IGNORE KEY(PRIMARY) WHERE id XOR 0;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-8871 Wrong result for CREATE TABLE .. SELECT LEAST(unsigned_column,unsigned_column)
--echo #
CREATE TABLE t1 (a INT,b INT UNSIGNED);
INSERT INTO t1 VALUES (-2147483648,4294967295);
--vertical_results
SELECT a, b, LEAST(a,a), LEAST(b,b), LEAST(a,b), LEAST(b,a), GREATEST(a,b), GREATEST(b,a) FROM t1;
--horizontal_results
CREATE TABLE t2 AS
SELECT a, b, LEAST(a,a), LEAST(b,b), LEAST(a,b), LEAST(b,a), GREATEST(a,b), GREATEST(b,a) FROM t1;
SHOW CREATE TABLE t2;
--vertical_results
SELECT * FROM t2;
--horizontal_results
DROP TABLE t2;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
...@@ -2823,11 +2823,13 @@ double Item_func_units::val_real() ...@@ -2823,11 +2823,13 @@ double Item_func_units::val_real()
void Item_func_min_max::fix_length_and_dec() void Item_func_min_max::fix_length_and_dec()
{ {
uint unsigned_count= 0;
int max_int_part=0; int max_int_part=0;
decimals=0; decimals=0;
max_length=0; max_length=0;
maybe_null=0; maybe_null=0;
thd= current_thd; thd= current_thd;
compare_as_dates= find_date_time_item(args, arg_count, 0);
cmp_type=args[0]->result_type(); cmp_type=args[0]->result_type();
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
...@@ -2835,14 +2837,34 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -2835,14 +2837,34 @@ void Item_func_min_max::fix_length_and_dec()
set_if_bigger(max_length, args[i]->max_length); set_if_bigger(max_length, args[i]->max_length);
set_if_bigger(decimals, args[i]->decimals); set_if_bigger(decimals, args[i]->decimals);
set_if_bigger(max_int_part, args[i]->decimal_int_part()); set_if_bigger(max_int_part, args[i]->decimal_int_part());
unsigned_count+= args[i]->unsigned_flag;
if (args[i]->maybe_null) if (args[i]->maybe_null)
maybe_null= 1; maybe_null= 1;
cmp_type= item_cmp_type(cmp_type,args[i]->result_type()); cmp_type= item_cmp_type(cmp_type,args[i]->result_type());
} }
unsigned_flag= unsigned_count == arg_count; // if all args are unsigned
if (cmp_type == STRING_RESULT) if (cmp_type == STRING_RESULT)
agg_arg_charsets_for_string_result_with_comparison(collation, agg_arg_charsets_for_string_result_with_comparison(collation,
args, arg_count); args, arg_count);
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) else if (cmp_type == INT_RESULT)
{
collation.set_numeric();
fix_char_length(my_decimal_precision_to_length_no_truncation(max_int_part +
decimals,
decimals,
unsigned_flag));
if (unsigned_count != 0 && unsigned_count != arg_count)
{
/*
If all args are of INT-alike type, but have different unsigned_flag,
then change type to DECIMAL.
*/
cmp_type= DECIMAL_RESULT;
cached_field_type= MYSQL_TYPE_NEWDECIMAL;
return;
}
}
else if (cmp_type == DECIMAL_RESULT)
{ {
collation.set_numeric(); collation.set_numeric();
fix_char_length(my_decimal_precision_to_length_no_truncation(max_int_part + fix_char_length(my_decimal_precision_to_length_no_truncation(max_int_part +
...@@ -2853,7 +2875,6 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -2853,7 +2875,6 @@ void Item_func_min_max::fix_length_and_dec()
else if (cmp_type == REAL_RESULT) else if (cmp_type == REAL_RESULT)
fix_char_length(float_length(decimals)); fix_char_length(float_length(decimals));
compare_as_dates= find_date_time_item(args, arg_count, 0);
if (compare_as_dates) if (compare_as_dates)
{ {
cached_field_type= compare_as_dates->field_type(); cached_field_type= compare_as_dates->field_type();
......
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