diff options
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 57 |
1 files changed, 20 insertions, 37 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1d33e369af0..fcd9ebdc938 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -891,7 +891,6 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, Item **a1, Item **a2, Item_result type) { - enum enum_date_cmp_type cmp_type; ulonglong const_value= (ulonglong)-1; thd= current_thd; owner= owner_arg; @@ -900,7 +899,7 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, b= a2; thd= current_thd; - if ((cmp_type= can_compare_as_dates(*a, *b, &const_value))) + if (can_compare_as_dates(*a, *b, &const_value)) { a_type= (*a)->field_type(); b_type= (*b)->field_type(); @@ -2936,6 +2935,16 @@ void Item_func_case::fix_length_and_dec() nagg++; if (!(found_types= collect_cmp_types(agg, nagg))) return; + if (with_sum_func || current_thd->lex->current_select->group_list.elements) + { + /* + See TODO commentary in the setup_copy_fields function: + item in a group may be wrapped with an Item_copy_string item. + That item has a STRING_RESULT result type, so we need + to take this type into account. + */ + found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT)); + } for (i= 0; i <= (uint)DECIMAL_RESULT; i++) { @@ -2972,9 +2981,8 @@ void Item_func_case::fix_length_and_dec() agg_num_lengths(args[i + 1]); if (else_expr_num != -1) agg_num_lengths(args[else_expr_num]); - max_length= my_decimal_precision_to_length_no_truncation(max_length + - decimals, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length(max_length + decimals, decimals, + unsigned_flag); } } @@ -3209,19 +3217,19 @@ int cmp_longlong(void *cmp_arg, One of the args is unsigned and is too big to fit into the positive signed range. Report no match. */ - if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) || + if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) + || (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX)) return a->unsigned_flag ? 1 : -1; /* Although the signedness differs both args can fit into the signed positive range. Make them signed and compare as usual. */ - return cmp_longs (a->val, b->val); + return cmp_longs(a->val, b->val); } if (a->unsigned_flag) - return cmp_ulongs ((ulonglong) a->val, (ulonglong) b->val); - else - return cmp_longs (a->val, b->val); + return cmp_ulongs((ulonglong) a->val, (ulonglong) b->val); + return cmp_longs(a->val, b->val); } static int cmp_double(void *cmp_arg, double *a,double *b) @@ -5408,33 +5416,7 @@ void Item_equal::merge(Item_equal *item) void Item_equal::sort(Item_field_cmpfunc cmp, void *arg) { - bool swap; - List_iterator<Item_field> it(fields); - do - { - Item_field *item1= it++; - Item_field **ref1= it.ref(); - Item_field *item2; - - swap= FALSE; - while ((item2= it++)) - { - Item_field **ref2= it.ref(); - if (cmp(item1, item2, arg) < 0) - { - Item_field *item= *ref1; - *ref1= *ref2; - *ref2= item; - swap= TRUE; - } - else - { - item1= item2; - ref1= ref2; - } - } - it.rewind(); - } while (swap); + exchange_sort<Item_field>(&fields, cmp, arg); } @@ -5489,6 +5471,7 @@ void Item_equal::update_used_tables() not_null_tables_cache= used_tables_cache= 0; if ((const_item_cache= cond_false)) return; + const_item_cache= 1; while ((item=li++)) { item->update_used_tables(); |