summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-08-19 15:11:14 +0400
committerAlexander Barkov <bar@mariadb.com>2019-08-19 15:11:14 +0400
commit52e276247d4573de0a01fa1500485fbd980d423a (patch)
treefd252f6411b56b87c85cfe3f8861faf087519fce /sql/item_sum.cc
parent850bf3313740598d3148139e9add7ea95a71cb03 (diff)
downloadmariadb-git-52e276247d4573de0a01fa1500485fbd980d423a.tar.gz
MDEV-19961 MIN(timestamp_column) returns a wrong result in a GROUP BY query
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc72
1 files changed, 60 insertions, 12 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 287a17aad3a..13a823fb10d 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3086,18 +3086,32 @@ void Item_sum_min_max::update_field()
tmp_item= args[0];
args[0]= direct_item;
}
- switch (result_type()) {
- case STRING_RESULT:
- min_max_update_str_field();
- break;
- case INT_RESULT:
- min_max_update_int_field();
- break;
- case DECIMAL_RESULT:
- min_max_update_decimal_field();
- break;
- default:
- min_max_update_real_field();
+ if (Item_sum_min_max::type_handler()->is_val_native_ready())
+ {
+ /*
+ TODO-10.5: change Item_sum_min_max to use val_native() for all data types
+ - make all type handlers val_native() ready
+ - use min_max_update_native_field() for all data types
+ - remove Item_sum_min_max::min_max_update_{str|real|int|decimal}_field()
+ */
+ min_max_update_native_field();
+ }
+ else
+ {
+ switch (Item_sum_min_max::type_handler()->cmp_type()) {
+ case STRING_RESULT:
+ case TIME_RESULT:
+ min_max_update_str_field();
+ break;
+ case INT_RESULT:
+ min_max_update_int_field();
+ break;
+ case DECIMAL_RESULT:
+ min_max_update_decimal_field();
+ break;
+ default:
+ min_max_update_real_field();
+ }
}
if (unlikely(direct_added))
{
@@ -3108,6 +3122,40 @@ void Item_sum_min_max::update_field()
}
+void Arg_comparator::min_max_update_field_native(THD *thd,
+ Field *field,
+ Item *item,
+ int cmp_sign)
+{
+ DBUG_ENTER("Arg_comparator::min_max_update_field_native");
+ if (!item->val_native(current_thd, &m_native2))
+ {
+ if (field->is_null())
+ field->store_native(m_native2); // The first non-null value
+ else
+ {
+ field->val_native(&m_native1);
+ if ((cmp_sign * m_compare_handler->cmp_native(m_native2, m_native1)) < 0)
+ field->store_native(m_native2);
+ }
+ field->set_notnull();
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void
+Item_sum_min_max::min_max_update_native_field()
+{
+ DBUG_ENTER("Item_sum_min_max::min_max_update_native_field");
+ DBUG_ASSERT(cmp);
+ DBUG_ASSERT(type_handler_for_comparison() == cmp->compare_type_handler());
+ THD *thd= current_thd;
+ cmp->min_max_update_field_native(thd, result_field, args[0], cmp_sign);
+ DBUG_VOID_RETURN;
+}
+
+
void
Item_sum_min_max::min_max_update_str_field()
{