fixed ALL/ANY optimisation with union (BUG#1668)
code cleanup
This commit is contained in:
parent
b9156c1871
commit
2efab5b67d
@ -1489,3 +1489,17 @@ set sort_buffer_size = (select s1 from t1);
|
|||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
do (select * from t1);
|
do (select * from t1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (s1 char);
|
||||||
|
insert into t1 values ('e');
|
||||||
|
select * from t1 where 'f' > any (select s1 from t1);
|
||||||
|
s1
|
||||||
|
e
|
||||||
|
select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
|
||||||
|
s1
|
||||||
|
e
|
||||||
|
explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||||
|
2 SUBQUERY t1 system NULL NULL NULL NULL 1
|
||||||
|
3 UNION t1 system NULL NULL NULL NULL 1
|
||||||
|
drop table t1;
|
||||||
|
@ -1010,3 +1010,13 @@ insert into t1 values (2);
|
|||||||
set sort_buffer_size = (select s1 from t1);
|
set sort_buffer_size = (select s1 from t1);
|
||||||
do (select * from t1);
|
do (select * from t1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# optimized ALL/ANY with union
|
||||||
|
#
|
||||||
|
create table t1 (s1 char);
|
||||||
|
insert into t1 values ('e');
|
||||||
|
select * from t1 where 'f' > any (select s1 from t1);
|
||||||
|
select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
|
||||||
|
explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
|
||||||
|
drop table t1;
|
||||||
|
@ -35,7 +35,7 @@ inline Item * and_items(Item* cond, Item *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::Item_subselect():
|
Item_subselect::Item_subselect():
|
||||||
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0),
|
Item_result_field(), value_assigned(0), substitution(0),
|
||||||
engine(0), used_tables_cache(0), have_to_be_excluded(0),
|
engine(0), used_tables_cache(0), have_to_be_excluded(0),
|
||||||
const_item_cache(1), engine_changed(0)
|
const_item_cache(1), engine_changed(0)
|
||||||
{
|
{
|
||||||
@ -66,8 +66,7 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||||||
|
|
||||||
Item_subselect::~Item_subselect()
|
Item_subselect::~Item_subselect()
|
||||||
{
|
{
|
||||||
if (engine_owner)
|
delete engine;
|
||||||
delete engine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
@ -183,7 +182,8 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_maxmin_subselect::Item_maxmin_subselect(st_select_lex *select_lex,
|
Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent,
|
||||||
|
st_select_lex *select_lex,
|
||||||
bool max)
|
bool max)
|
||||||
:Item_singlerow_subselect()
|
:Item_singlerow_subselect()
|
||||||
{
|
{
|
||||||
@ -192,6 +192,14 @@ Item_maxmin_subselect::Item_maxmin_subselect(st_select_lex *select_lex,
|
|||||||
max_columns= 1;
|
max_columns= 1;
|
||||||
maybe_null= 1;
|
maybe_null= 1;
|
||||||
max_columns= 1;
|
max_columns= 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Following information was collected during performing fix_fields()
|
||||||
|
of Items belonged to subquery, which will be not repeated
|
||||||
|
*/
|
||||||
|
used_tables_cache= parent->get_used_tables_cache();
|
||||||
|
const_item_cache= parent->get_const_item_cache();
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,9 +535,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
func == &Item_bool_func2::ge_creator ||
|
func == &Item_bool_func2::ge_creator ||
|
||||||
func == &Item_bool_func2::le_creator))
|
func == &Item_bool_func2::le_creator))
|
||||||
{
|
{
|
||||||
|
if (substitution)
|
||||||
|
{
|
||||||
|
// It is second (third, ...) SELECT of UNION => All is done
|
||||||
|
DBUG_RETURN(RES_OK);
|
||||||
|
}
|
||||||
|
|
||||||
Item *subs;
|
Item *subs;
|
||||||
if (!select_lex->group_list.elements &&
|
if (!select_lex->group_list.elements &&
|
||||||
!select_lex->with_sum_func)
|
!select_lex->with_sum_func &&
|
||||||
|
!(select_lex->next_select()))
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
subs_type type= substype();
|
subs_type type= substype();
|
||||||
@ -565,7 +580,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
// remove LIMIT placed by ALL/ANY subquery
|
// remove LIMIT placed by ALL/ANY subquery
|
||||||
select_lex->master_unit()->global_parameters->select_limit=
|
select_lex->master_unit()->global_parameters->select_limit=
|
||||||
HA_POS_ERROR;
|
HA_POS_ERROR;
|
||||||
subs= new Item_maxmin_subselect(select_lex,
|
subs= new Item_maxmin_subselect(this, select_lex,
|
||||||
(func == &Item_bool_func2::le_creator ||
|
(func == &Item_bool_func2::le_creator ||
|
||||||
func == &Item_bool_func2::lt_creator));
|
func == &Item_bool_func2::lt_creator));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ typedef Item_bool_func2* (*compare_func_creator)(Item*, Item*);
|
|||||||
|
|
||||||
class Item_subselect :public Item_result_field
|
class Item_subselect :public Item_result_field
|
||||||
{
|
{
|
||||||
my_bool engine_owner; /* Is this item owner of engine */
|
|
||||||
my_bool value_assigned; /* value already assigned to subselect */
|
my_bool value_assigned; /* value already assigned to subselect */
|
||||||
protected:
|
protected:
|
||||||
/* thread handler, will be assigned in fix_fields only */
|
/* thread handler, will be assigned in fix_fields only */
|
||||||
@ -90,6 +89,8 @@ public:
|
|||||||
virtual void fix_length_and_dec();
|
virtual void fix_length_and_dec();
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
bool const_item() const;
|
bool const_item() const;
|
||||||
|
inline table_map get_used_tables_cache() { return used_tables_cache; }
|
||||||
|
inline bool get_const_item_cache() { return const_item_cache; }
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
void print(String *str)
|
void print(String *str)
|
||||||
{
|
{
|
||||||
@ -144,10 +145,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* used in static ALL/ANY optimisation */
|
/* used in static ALL/ANY optimisation */
|
||||||
class Item_maxmin_subselect: public Item_singlerow_subselect
|
class Item_maxmin_subselect :public Item_singlerow_subselect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_maxmin_subselect(st_select_lex *select_lex, bool max);
|
Item_maxmin_subselect(Item_subselect *parent,
|
||||||
|
st_select_lex *select_lex, bool max);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* exists subselect */
|
/* exists subselect */
|
||||||
|
@ -119,13 +119,18 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
|
|||||||
SELECT_LEX *select_cursor,*sl;
|
SELECT_LEX *select_cursor,*sl;
|
||||||
DBUG_ENTER("st_select_lex_unit::prepare");
|
DBUG_ENTER("st_select_lex_unit::prepare");
|
||||||
|
|
||||||
|
/*
|
||||||
|
result object should be reassigned even if preparing already done for
|
||||||
|
max/min subquery (ALL/ANY optimization)
|
||||||
|
*/
|
||||||
|
result= sel_result;
|
||||||
|
|
||||||
if (prepared)
|
if (prepared)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
prepared= 1;
|
prepared= 1;
|
||||||
res= 0;
|
res= 0;
|
||||||
found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS;
|
found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS;
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
result= sel_result;
|
|
||||||
t_and_f= tables_and_fields_initied;
|
t_and_f= tables_and_fields_initied;
|
||||||
|
|
||||||
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
|
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user