summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorEvgeny Potemkin <epotemkin@mysql.com>2010-07-19 21:11:47 +0400
committerEvgeny Potemkin <epotemkin@mysql.com>2010-07-19 21:11:47 +0400
commit589027b2f585690b57a21edeb24b89c3e7302724 (patch)
tree43325bce21852a2c0b13eaedf562480d09437bb1 /sql/item_sum.cc
parent40856e830ded489100bc7832bf4e2b5d11175f26 (diff)
downloadmariadb-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.cc5
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;
}