diff options
author | Evgeny Potemkin <epotemkin@mysql.com> | 2010-07-19 21:11:47 +0400 |
---|---|---|
committer | Evgeny Potemkin <epotemkin@mysql.com> | 2010-07-19 21:11:47 +0400 |
commit | 589027b2f585690b57a21edeb24b89c3e7302724 (patch) | |
tree | 43325bce21852a2c0b13eaedf562480d09437bb1 /sql/item_sum.cc | |
parent | 40856e830ded489100bc7832bf4e2b5d11175f26 (diff) | |
download | mariadb-git-589027b2f585690b57a21edeb24b89c3e7302724.tar.gz |
Bug#49771: Incorrect MIN/MAX for date/time values.
This bug is a design flaw of the fix for the bug#33546. It assumed that an
item can be used only in one comparison context, but actually it isn't the
case. Item_cache_datetime is used to store result for MIX/MAX aggregate
functions. Because Arg_comparator always compares datetime values as INTs when
possible the Item_cache_datetime most time caches only INT value. But
since all datetime values has STRING result type MIN/MAX functions are asked
for a STRING value when the result is being sent to a client. The
Item_cache_datetime was designed to avoid conversions and get INT/STRING
values from an underlying item, but at the moment the values is asked
underlying item doesn't hold it anymore thus wrong result is returned.
Beside that MIN/MAX aggregate functions was wrongly initializing cached result
and this led to a wrong result.
The Item::has_compatible_context helper function is added. It checks whether
this and given items has the same comparison context or can be compared as
DATETIME values by Arg_comparator. The equality propagation optimization is
adjusted to take into account that items which being compared as DATETIME
can have different comparison contexts.
The Item_cache_datetime now converts cached INT value to a correct STRING
DATETIME value by means of number_to_datetime & my_TIME_to_str functions.
The Arg_comparator::set_cmp_context_for_datetime helper function is added.
It sets comparison context of items being compared as DATETIMEs to INT if
items will be compared as longlong.
The Item_sum_hybrid::setup function now correctly initializes its result
value.
In order to avoid unnecessary conversions Item_sum_hybrid now states that it
can provide correct longlong value if the item being aggregated can do it
too.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 77c45ea85f7..b05d845dead 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1214,8 +1214,7 @@ void Item_sum_hybrid::setup_hybrid(Item *item, Item *value_arg) { value= Item_cache::get_cache(item); value->setup(item); - if (value_arg) - value->store(value_arg); + value->store(value_arg); cmp= new Arg_comparator(); cmp->set_cmp_func(this, args, (Item**)&value, FALSE); collation.set(item->collation); @@ -1903,7 +1902,7 @@ void Item_sum_variance::update_field() void Item_sum_hybrid::clear() { - value->null_value= 1; + value->clear(); null_value= 1; } |