diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-09-30 10:05:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-09-30 10:05:16 +0400 |
commit | 09b87d6293b4b41321ba98366d5d7ade9ad681d3 (patch) | |
tree | 70e1d9d1eb8e20f68c43b6041e396ad64e47cd27 /sql | |
parent | c13f4091f57ebe89281f11affac49d191db77e4f (diff) | |
download | mariadb-git-09b87d6293b4b41321ba98366d5d7ade9ad681d3.tar.gz |
MDEV-8871 Wrong result for CREATE TABLE .. SELECT LEAST(unsigned_column,unsigned_column)
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_func.cc | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index ea1710ecc24..711d23d9b15 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2823,11 +2823,13 @@ double Item_func_units::val_real() void Item_func_min_max::fix_length_and_dec() { + uint unsigned_count= 0; int max_int_part=0; decimals=0; max_length=0; maybe_null=0; thd= current_thd; + compare_as_dates= find_date_time_item(args, arg_count, 0); cmp_type=args[0]->result_type(); for (uint i=0 ; i < arg_count ; i++) @@ -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(decimals, args[i]->decimals); set_if_bigger(max_int_part, args[i]->decimal_int_part()); + unsigned_count+= args[i]->unsigned_flag; if (args[i]->maybe_null) maybe_null= 1; 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) agg_arg_charsets_for_string_result_with_comparison(collation, 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(); 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() else if (cmp_type == REAL_RESULT) fix_char_length(float_length(decimals)); - compare_as_dates= find_date_time_item(args, arg_count, 0); if (compare_as_dates) { cached_field_type= compare_as_dates->field_type(); |