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_cmpfunc.h | |
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_cmpfunc.h')
-rw-r--r-- | sql/item_cmpfunc.h | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 8813324262c..b20a6892ce2 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -123,7 +123,17 @@ public: delete [] comparators; comparators= 0; } - + /* + Set correct cmp_context if items would be compared as INTs. + */ + inline void set_cmp_context_for_datetime() + { + DBUG_ASSERT(func == &Arg_comparator::compare_datetime); + if ((*a)->result_as_longlong()) + (*a)->cmp_context= INT_RESULT; + if ((*b)->result_as_longlong()) + (*b)->cmp_context= INT_RESULT; + } friend class Item_func; }; |