mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Some simple optimisation
= ANY and <> ALL converted to (NOT) IN to get advantage of IN optimisation mysql-test/r/subselect.result: test of new optimisation mysql-test/t/subselect.test: test of new optimisation sql/mysql_priv.h: new function for subquery creation sql/sql_parse.cc: layout fix new function for subquery creation (convert some ALL/ANY to IN) sql/sql_yacc.yy: same code blocks replaced with function
This commit is contained in:
parent
0f81ecf501
commit
1db2b4e60e
5 changed files with 69 additions and 18 deletions
|
@ -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); }
|
||||
|
|
Loading…
Add table
Reference in a new issue