From 781b05fbadbf51259ad1385ef79c3a7a30a62eba Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Wed, 11 Jul 2012 08:19:17 +0530 Subject: [PATCH] Bug #13444084:PRIMARY KEY OR UNIQUE KEY >453 BYTES FAILS FOR COUNT DISTINCT GROUP BY PROBLEM: To calculate the final result of the count(distinct(select 1)) we call 'end_send' function instead of 'end_send_group'. 'end_send' cannot be called if we have aggregate functions that need to be evaluated. ANALYSIS: While evaluating for a possible loose_index_scan option for the query, the variable 'is_agg_distinct' is set to 'false' as the item in the distinct clause is not a field. But, we choose loose_index_scan by not taking this into consideration. So, while setting the final 'select_function' to evaluate the result, 'precomputed_group_by' is set to TRUE as in this case loose_index_scan is chosen and we do not have agg_distinct in the query (which is clearly wrong as we have one). As a result, 'end_send' function is chosen as the final select_function instead of 'end_send_group'. The difference between the two being, 'end_send_group' evaluates the aggregates while 'end_send' does not. Hence the wrong result. FIX: The variable 'is_agg_distinct' always represents if 'loose_idnex_scan' can be chosen for aggregate_distinct functions present in the select. So, we check for this variable to continue with loose_index_scan option. --- sql/opt_range.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8a6607cf343..03f444c22b5 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9463,9 +9463,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) have_min= TRUE; else if (min_max_item->sum_func() == Item_sum::MAX_FUNC) have_max= TRUE; - else if (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC) + else if (is_agg_distinct && + (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC)) continue; else DBUG_RETURN(NULL);