Some simple optimisation

= ANY and <> ALL converted to (NOT) IN to get advantage of IN optimisation
parent 381b6808
......@@ -1403,6 +1403,16 @@ s1 s1 NOT IN (SELECT s1 FROM t2)
a1 0
a2 0
a3 1
select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
s1 s1 = ANY (SELECT s1 FROM t2)
a1 1
a2 1
a3 0
select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
s1 s1 <> ALL (SELECT s1 FROM t2)
a1 0
a2 0
a3 1
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
a1 0
......@@ -1412,6 +1422,14 @@ explain select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
explain select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
explain select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
......
......@@ -947,8 +947,12 @@ create table t2 (s1 char(5), index s1(s1));
insert into t1 values ('a1'),('a2'),('a3');
insert into t2 values ('a1'),('a2');
select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
explain select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
explain select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
explain select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
drop table t1,t2;
......
......@@ -1015,6 +1015,11 @@ compare_func_creator comp_le_creator(bool invert);
compare_func_creator comp_lt_creator(bool invert);
compare_func_creator comp_ne_creator(bool invert);
Item * all_any_subquery_creator(Item *left_expr,
chooser_compare_func_creator cmp,
bool all,
SELECT_LEX *select_lex);
/*
clean/setup table fields and map
......
......@@ -4610,32 +4610,71 @@ bool check_simple_select()
return 0;
}
compare_func_creator comp_eq_creator(bool invert)
{
return invert?&Item_bool_func2::ne_creator:&Item_bool_func2::eq_creator;
}
compare_func_creator comp_ge_creator(bool invert)
{
return invert?&Item_bool_func2::lt_creator:&Item_bool_func2::ge_creator;
}
compare_func_creator comp_gt_creator(bool invert)
{
return invert?&Item_bool_func2::le_creator:&Item_bool_func2::gt_creator;
}
compare_func_creator comp_le_creator(bool invert)
{
return invert?&Item_bool_func2::gt_creator:&Item_bool_func2::le_creator;
}
compare_func_creator comp_lt_creator(bool invert)
{
return invert?&Item_bool_func2::ge_creator:&Item_bool_func2::lt_creator;
}
compare_func_creator comp_ne_creator(bool invert)
{
return invert?&Item_bool_func2::eq_creator:&Item_bool_func2::ne_creator;
}
/*
Construct ALL/ANY/SOME subquery Item
SYNOPSIS
all_any_subquery_creator()
left_expr - pointer to left expression
cmp - compare function creator
all - true if we create ALL subquery
select_lex - pointer on parsed subquery structure
RETURN VALUE
constructed Item (or 0 if out of memory)
*/
Item * all_any_subquery_creator(Item *left_expr,
chooser_compare_func_creator cmp,
bool all,
SELECT_LEX *select_lex)
{
if ((cmp == &comp_eq_creator) and !all) // = ANY <=> IN
return new Item_in_subselect(left_expr, select_lex);
if ((cmp == &comp_ne_creator) and all) // <> ALL <=> NOT IN
return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
Item_allany_subselect *it=
new Item_allany_subselect(left_expr, (*cmp)(all), select_lex);
if (all)
return it->upper_not= new Item_func_not_all(it); /* ALL */
return it; /* ANY/SOME */
}
......@@ -2262,12 +2262,7 @@ expr_expr:
| expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
| expr comp_op all_or_any in_subselect %prec EQ
{
Item_allany_subselect *it=
new Item_allany_subselect($1, (*$2)($3), $4);
if ($3)
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
else
$$ = it; /* ANY/SOME */
$$= all_any_subquery_creator($1, $2, $3, $4);
}
| expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
......@@ -2308,12 +2303,7 @@ no_in_expr:
| no_in_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
| no_in_expr comp_op all_or_any in_subselect %prec EQ
{
Item_allany_subselect *it=
new Item_allany_subselect($1, (*$2)($3), $4);
if ($3)
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
else
$$ = it; /* ANY/SOME */
all_any_subquery_creator($1, $2, $3, $4);
}
| no_in_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| no_in_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
......@@ -2363,12 +2353,7 @@ no_and_expr:
| no_and_expr comp_op expr %prec EQ { $$= (*((*$2)(0)))($1,$3); }
| no_and_expr comp_op all_or_any in_subselect %prec EQ
{
Item_allany_subselect *it=
new Item_allany_subselect($1, (*$2)($3), $4);
if ($3)
$$ = it->upper_not= new Item_func_not_all(it); /* ALL */
else
$$ = it; /* ANY/SOME */
all_any_subquery_creator($1, $2, $3, $4);
}
| no_and_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| no_and_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment