summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.h
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_cmpfunc.h
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_cmpfunc.h')
-rw-r--r--sql/item_cmpfunc.h12
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;
};