summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc57
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();