mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge mysql.com:/home/timka/mysql/src/5.0-virgin
into mysql.com:/home/timka/mysql/src/5.0-bug-16710 mysql-test/r/group_min_max.result: Auto merged mysql-test/t/group_min_max.test: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/opt_range.cc: Auto merged
This commit is contained in:
@ -1954,6 +1954,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 163 NULL 128 Using where; Using index
|
||||
explain select distinct(a1) from t1 where ord(a2) = 98;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
|
||||
select distinct(a1) from t1 where ord(a2) = 98;
|
||||
a1
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
explain select a1 from t1 where a2 = 'b' group by a1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 5 Using where; Using index for group-by
|
||||
|
@ -641,6 +641,14 @@ explain select a1,a2,count(a2) from t1 group by a1,a2,b;
|
||||
explain select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b;
|
||||
explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;
|
||||
|
||||
|
||||
#
|
||||
# Bug #16710: select distinct doesn't return all it should
|
||||
#
|
||||
|
||||
explain select distinct(a1) from t1 where ord(a2) = 98;
|
||||
select distinct(a1) from t1 where ord(a2) = 98;
|
||||
|
||||
#
|
||||
# BUG#11044: DISTINCT or GROUP BY queries with equality predicates instead of MIN/MAX.
|
||||
#
|
||||
|
34
sql/item.cc
34
sql/item.cc
@ -496,7 +496,7 @@ bool Item_ident::remove_dependence_processor(byte * arg)
|
||||
arguments in a condition the method must return false.
|
||||
|
||||
RETURN
|
||||
false to force the evaluation of collect_item_field_processor
|
||||
FALSE to force the evaluation of collect_item_field_processor
|
||||
for the subsequent items.
|
||||
*/
|
||||
|
||||
@ -517,6 +517,38 @@ bool Item_field::collect_item_field_processor(byte *arg)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if an Item_field references some field from a list of fields.
|
||||
|
||||
SYNOPSIS
|
||||
Item_field::find_item_in_field_list_processor
|
||||
arg Field being compared, arg must be of type Field
|
||||
|
||||
DESCRIPTION
|
||||
Check whether the Item_field represented by 'this' references any
|
||||
of the fields in the keyparts passed via 'arg'. Used with the
|
||||
method Item::walk() to test whether any keypart in a sequence of
|
||||
keyparts is referenced in an expression.
|
||||
|
||||
RETURN
|
||||
TRUE if 'this' references the field 'arg'
|
||||
FALE otherwise
|
||||
*/
|
||||
bool Item_field::find_item_in_field_list_processor(byte *arg)
|
||||
{
|
||||
KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg);
|
||||
KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1);
|
||||
KEY_PART_INFO *cur_part;
|
||||
|
||||
for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
|
||||
{
|
||||
if (field->eq(cur_part->field))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool Item::check_cols(uint c)
|
||||
{
|
||||
if (c != 1)
|
||||
|
@ -701,6 +701,7 @@ public:
|
||||
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
|
||||
virtual bool cleanup_processor(byte *arg);
|
||||
virtual bool collect_item_field_processor(byte * arg) { return 0; }
|
||||
virtual bool find_item_in_field_list_processor(byte *arg) { return 0; }
|
||||
virtual bool change_context_processor(byte *context) { return 0; }
|
||||
virtual bool reset_query_id_processor(byte *query_id) { return 0; }
|
||||
|
||||
@ -1149,6 +1150,7 @@ public:
|
||||
bool is_null() { return field->is_null(); }
|
||||
Item *get_tmp_table_item(THD *thd);
|
||||
bool collect_item_field_processor(byte * arg);
|
||||
bool find_item_in_field_list_processor(byte *arg);
|
||||
bool reset_query_id_processor(byte *arg)
|
||||
{
|
||||
field->query_id= *((query_id_t *) arg);
|
||||
|
@ -6895,6 +6895,7 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
|
||||
bool have_min, bool have_max,
|
||||
double *read_cost, ha_rows *records);
|
||||
|
||||
|
||||
/*
|
||||
Test if this access method is applicable to a GROUP query with MIN/MAX
|
||||
functions, and if so, construct a new TRP object.
|
||||
@ -7301,11 +7302,36 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
||||
}
|
||||
else if (min_max_arg_part &&
|
||||
(min_max_arg_part - first_non_group_part > 0))
|
||||
{
|
||||
/*
|
||||
There is a gap but no range tree, thus no predicates at all for the
|
||||
non-group keyparts.
|
||||
*/
|
||||
goto next_index;
|
||||
}
|
||||
else if (first_non_group_part && join->conds)
|
||||
{
|
||||
/*
|
||||
If there is no MIN/MAX function in the query, but some index
|
||||
key part is referenced in the WHERE clause, then this index
|
||||
cannot be used because the WHERE condition over the keypart's
|
||||
field cannot be 'pushed' to the index (because there is no
|
||||
range 'tree'), and the WHERE clause must be evaluated before
|
||||
GROUP BY/DISTINCT.
|
||||
*/
|
||||
/*
|
||||
Store the first and last keyparts that need to be analyzed
|
||||
into one array that can be passed as parameter.
|
||||
*/
|
||||
KEY_PART_INFO *key_part_range[2];
|
||||
key_part_range[0]= first_non_group_part;
|
||||
key_part_range[1]= last_part;
|
||||
|
||||
/* Check if cur_part is referenced in the WHERE clause. */
|
||||
if (join->conds->walk(&Item::find_item_in_field_list_processor,
|
||||
(byte*) key_part_range))
|
||||
goto next_index;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user