Commit 339a290d authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

Merge remote-tracking branch 'origin/5.5' into 10.0

parents b87873b2 934b8312
......@@ -2591,5 +2591,43 @@ Handler_read_rnd_deleted 0
Handler_read_rnd_next 27
deallocate prepare stmt1;
drop table t1,t2;
#
# Bug mdev-12670: mergeable derived / view with subqueries
# subject to semi-join optimizations
# (actually this is a 5.3 bug.)
#
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain select a from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
explain select * from (select a from t1 where a in (select b from t2)) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
create view v1 as select a from t1 where a in (select b from t2);
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
drop view v1;
drop table t1,t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
......@@ -426,7 +426,7 @@ c1
bb
cc
Warnings:
Warning 1931 Query execution was interrupted. The query examined at least 18 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete.
Warning 1931 Query execution was interrupted. The query examined at least 17 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete.
select * from v1 LIMIT ROWS EXAMINED 11;
c1
bb
......@@ -439,7 +439,8 @@ from (select * from t1
where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp
LIMIT ROWS EXAMINED 11;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 2 func 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
select *
from (select * from t1
......
......@@ -379,6 +379,7 @@ drop table t3, t4, t5;
#
# LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
#
set @optimizer_switch_save= @@optimizer_switch;
create table t1 (c1 char(2) not null, c2 char(2));
create table t2 (c3 char(2), c4 char(2));
insert into t1 values ('a1', 'b1');
......@@ -400,6 +401,7 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
c1 c2
drop table t1, t2;
set optimizer_switch= @optimizer_switch_save;
#
# MDEV-12673: cost-based choice between materialization and in-to-exists
#
......@@ -442,3 +444,44 @@ id select_type table type possible_keys key key_len ref rows Extra
2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1
2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
DROP TABLE t1,t2,t3;
#
# MDEV-7599: in-to-exists chosen after min/max optimization
#
set @optimizer_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
b c
EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 MATERIALIZED t1 index NULL a 5 NULL 2 100.00 Using index
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,`test`.`t2`.`b` in ( <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) ), <primary_index_lookup>(`test`.`t2`.`b` in <temporary table> on distinct_key where ((`test`.`t2`.`b` = `<subquery2>`.`MIN(a)`))))))))
set optimizer_switch= 'materialization=off';
SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
b c
EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY t1 index NULL a 5 NULL 2 100.00 Using index
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) having trigcond((<cache>(`test`.`t2`.`b`) = <ref_null_helper>(min(`test`.`t1`.`a`)))))))))
set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1,t2;
CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('baz'),('qux');
CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
INSERT INTO t3 VALUES ('abc'),('def');
SELECT * FROM t1
WHERE f1 = ALL( SELECT MAX(t2a.f2)
FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
ON (f3 = t2b.f2) );
f1
DROP TABLE t1,t2,t3;
......@@ -1652,9 +1652,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
......@@ -3062,4 +3062,43 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
#
# MDEV-12675: subquery subject to semi-join optimizations
# in ON expression of INNER JOIN
#
set @tmp_mdev12675=@@optimizer_switch;
set optimizer_switch=default;
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain
select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
explain
select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
drop table t1,t2;
set optimizer_switch= @tmp_mdev12675;
set optimizer_switch=@subselect_sj_tmp;
......@@ -1589,3 +1589,26 @@ i1
DROP TABLE t1,t2,t3;
set join_cache_level= @save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
#
# mdev-7791: materialization of a semi-join subquery +
# RAND() in WHERE
# (materialized table is accessed last)
#
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='materialization=on';
create table t1(i int);
insert into t1 values (1), (2), (3), (7), (9), (10);
create table t2(i int);
insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
select * from t1 where (rand() < 0) and i in (select i from t2);
i
explain extended
select * from t1 where (rand() < 0) and i in (select i from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 100.00
Warnings:
Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where ((rand() < 0))
drop table t1,t2;
set optimizer_switch=@save_optimizer_switch;
......@@ -1665,9 +1665,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
......@@ -3076,6 +3076,45 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
#
# MDEV-12675: subquery subject to semi-join optimizations
# in ON expression of INNER JOIN
#
set @tmp_mdev12675=@@optimizer_switch;
set optimizer_switch=default;
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain
select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
explain
select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
drop table t1,t2;
set optimizer_switch= @tmp_mdev12675;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
......
......@@ -1881,6 +1881,36 @@ deallocate prepare stmt1;
drop table t1,t2;
--echo #
--echo # Bug mdev-12670: mergeable derived / view with subqueries
--echo # subject to semi-join optimizations
--echo # (actually this is a 5.3 bug.)
--echo #
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
explain select a from t1 where a in (select b from t2);
explain select * from (select a from t1 where a in (select b from t2)) t;
create view v1 as select a from t1 where a in (select b from t2);
explain select * from v1;
drop view v1;
drop table t1,t2;
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
......@@ -406,6 +406,8 @@ drop table t3, t4, t5;
--echo # LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
--echo #
set @optimizer_switch_save= @@optimizer_switch;
create table t1 (c1 char(2) not null, c2 char(2));
create table t2 (c3 char(2), c4 char(2));
......@@ -425,6 +427,8 @@ select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
drop table t1, t2;
set optimizer_switch= @optimizer_switch_save;
--echo #
--echo # MDEV-12673: cost-based choice between materialization and in-to-exists
--echo #
......@@ -463,3 +467,43 @@ SELECT * FROM t1 WHERE i1 NOT IN (
);
DROP TABLE t1,t2,t3;
--echo #
--echo # MDEV-7599: in-to-exists chosen after min/max optimization
--echo #
set @optimizer_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
let $q=
SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
eval $q;
eval EXPLAIN EXTENDED $q;
set optimizer_switch= 'materialization=off';
eval $q;
eval EXPLAIN EXTENDED $q;
set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1,t2;
CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('baz'),('qux');
CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
INSERT INTO t3 VALUES ('abc'),('def');
SELECT * FROM t1
WHERE f1 = ALL( SELECT MAX(t2a.f2)
FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
ON (f3 = t2b.f2) );
DROP TABLE t1,t2,t3;
......@@ -2773,5 +2773,37 @@ WHERE ( SELECT z.country
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
--echo #
--echo # MDEV-12675: subquery subject to semi-join optimizations
--echo # in ON expression of INNER JOIN
--echo #
set @tmp_mdev12675=@@optimizer_switch;
set optimizer_switch=default;
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
explain
select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
explain
select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
drop table t1,t2;
set optimizer_switch= @tmp_mdev12675;
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
......@@ -263,3 +263,23 @@ DROP TABLE t1,t2,t3;
set join_cache_level= @save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
--echo #
--echo # mdev-7791: materialization of a semi-join subquery +
--echo # RAND() in WHERE
--echo # (materialized table is accessed last)
--echo #
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='materialization=on';
create table t1(i int);
insert into t1 values (1), (2), (3), (7), (9), (10);
create table t2(i int);
insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
select * from t1 where (rand() < 0) and i in (select i from t2);
explain extended
select * from t1 where (rand() < 0) and i in (select i from t2);
drop table t1,t2;
set optimizer_switch=@save_optimizer_switch;
......@@ -1381,8 +1381,9 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
st_select_lex *select_lex):
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
pushed_cond_guards(NULL), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
is_flattenable_semijoin(FALSE), is_registered_semijoin(FALSE),
pushed_cond_guards(NULL), do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE),
is_jtbm_const_tab(FALSE), is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE),
upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
......@@ -2512,6 +2513,27 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond");
DBUG_ASSERT(thd == join_arg->thd);
if (select_lex->min_max_opt_list.elements)
{
/*
MIN/MAX optimizations have been applied to Item_sum objects
of the subquery this subquery predicate in opt_sum_query().
Injection of new condition invalidates this optimizations.
Thus those optimizations must be rolled back.
*/
List_iterator_fast<Item_sum> it(select_lex->min_max_opt_list);
Item_sum *item;
while ((item= it++))
{
item->clear();
item->reset_forced_const();
}
if (where_item)
where_item->update_used_tables();
if (having_item)
having_item->update_used_tables();
}
if (where_item)
{
List<Item> *and_args= NULL;
......
......@@ -490,6 +490,8 @@ class Item_in_subselect :public Item_exists_subselect
Item *left_expr_orig;
/* Priority of this predicate in the convert-to-semi-join-nest process. */
int sj_convert_priority;
/* May be TRUE only for the candidates to semi-join conversion */
bool do_not_convert_to_sj;
/*
Types of left_expr and subquery's select list allow to perform subquery
materialization. Currently, we set this to FALSE when it as well could
......@@ -580,8 +582,8 @@ class Item_in_subselect :public Item_exists_subselect
Item_in_subselect()
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
pushed_cond_guards(NULL), func(NULL), is_jtbm_merged(FALSE),
is_jtbm_const_tab(FALSE), upper_item(0) {}
pushed_cond_guards(NULL), func(NULL), do_not_convert_to_sj(FALSE),
is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE), upper_item(0) {}
void cleanup();
subs_type substype() { return IN_SUBS; }
void reset()
......@@ -635,6 +637,8 @@ class Item_in_subselect :public Item_exists_subselect
*/
int get_identifier();
void block_conversion_to_sj () { do_not_convert_to_sj= TRUE; }
bool test_strategy(uchar strategy)
{ return MY_TEST(in_strategy & strategy); }
......
......@@ -454,6 +454,7 @@ class Item_sum :public Item_result_field
used_tables_cache= 0;
forced_const= TRUE;
}
void reset_forced_const() { forced_const= FALSE; }
virtual bool const_item() const { return forced_const; }
virtual bool const_during_execution() const { return false; }
virtual void print(String *str, enum_query_type query_type);
......
......@@ -1001,6 +1001,25 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
}
void find_and_block_conversion_to_sj(Item *to_find,
List_iterator_fast<Item_in_subselect> &li)
{
if (to_find->type() != Item::SUBSELECT_ITEM ||
((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
return;
Item_in_subselect *in_subq;
li.rewind();
while ((in_subq= li++))
{
if (in_subq == to_find)
{
in_subq->block_conversion_to_sj();
return;
}
}
}
/*
Convert semi-join subquery predicates into semi-join join nests
......@@ -1053,7 +1072,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
Query_arena *arena, backup;
Item_in_subselect *in_subq;
THD *thd= join->thd;
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
DBUG_ENTER("convert_join_subqueries_to_semijoins");
if (join->select_lex->sj_subselects.is_empty())
......@@ -1071,6 +1089,60 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
subq_sel->update_used_tables();
}
/*
Check all candidates to semi-join conversion that occur
in ON expressions of outer join. Set the flag blocking
this conversion for them.
*/
TABLE_LIST *tbl;
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
while ((tbl= ti++))
{
TABLE_LIST *embedded;
TABLE_LIST *embedding= tbl;
do
{
embedded= embedding;
if (MY_TEST(embedded->outer_join))
{
Item *cond= embedded->on_expr;
if (!cond)
;
else if (cond->type() != Item::COND_ITEM)
find_and_block_conversion_to_sj(cond, li);
else if (((Item_cond*) cond)->functype() ==
Item_func::COND_AND_FUNC)
{
Item *item;
List_iterator<Item> it(*(((Item_cond*) cond)->argument_list()));
while ((item= it++))
{
find_and_block_conversion_to_sj(item, li);
}
}
}
embedding= embedded->embedding;
}
while (embedding &&
embedding->nested_join->join_list.head() == embedded);
}
/*
Block conversion to semi-joins for those candidates that
are encountered in the WHERE condition of the multi-table view
with CHECK OPTION if this view is used in UPDATE/DELETE.
(This limitation can be, probably, easily lifted.)
*/
li.rewind();
while ((in_subq= li++))
{
if (in_subq->emb_on_expr_nest != NO_JOIN_NEST &&
in_subq->emb_on_expr_nest->effective_with_check)
{
in_subq->block_conversion_to_sj();
}
}
li.rewind();
/* First, convert child join's subqueries. We proceed bottom-up here */
while ((in_subq= li++))
......@@ -1089,8 +1161,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (convert_join_subqueries_to_semijoins(child_join))
DBUG_RETURN(TRUE);
in_subq->sj_convert_priority=
MY_TEST(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
MY_TEST(in_subq->do_not_convert_to_sj) * MAX_TABLES * 2 +
in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
}
......@@ -1123,7 +1197,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool remove_item= TRUE;
/* Stop processing if we've reached a subquery that's attached to the ON clause */
if (in_subq->emb_on_expr_nest != NO_JOIN_NEST)
if (in_subq->do_not_convert_to_sj)
break;
if (in_subq->is_flattenable_semijoin)
......
......@@ -254,6 +254,8 @@ int opt_sum_query(THD *thd,
int error= 0;
DBUG_ENTER("opt_sum_query");
thd->lex->current_select->min_max_opt_list.empty();
if (conds)
where_tables= conds->used_tables();
......@@ -447,7 +449,14 @@ int opt_sum_query(THD *thd,
item_sum->aggregator_clear();
}
else
{
item_sum->reset_and_add();
/*
Save a reference to the item for possible rollback
of the min/max optimizations for this select
*/
thd->lex->current_select->min_max_opt_list.push_back(item_sum);
}
item_sum->make_const();
recalc_const_item= 1;
break;
......
......@@ -558,7 +558,7 @@ file '%s')", fname);
mi->connect_retry= (uint) connect_retry;
mi->ssl= (my_bool) ssl;
mi->ssl_verify_server_cert= ssl_verify_server_cert;
mi->heartbeat_period= master_heartbeat_period;
mi->heartbeat_period= MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, master_heartbeat_period);
}
DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
mi->master_log_name,
......@@ -675,8 +675,8 @@ int flush_master_info(Master_info* mi,
contents of file). But because of number of lines in the first line
of file we don't care about this garbage.
*/
char heartbeat_buf[sizeof(mi->heartbeat_period) * 4]; // buffer to suffice always
sprintf(heartbeat_buf, "%.3f", mi->heartbeat_period);
char heartbeat_buf[FLOATING_POINT_BUFFER];
my_fcvt(mi->heartbeat_period, 3, heartbeat_buf, NULL);
my_b_seek(file, 0L);
my_b_printf(file,
"%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n"
......
......@@ -1865,6 +1865,7 @@ void st_select_lex::init_query()
leaf_tables_prep.empty();
leaf_tables.empty();
item_list.empty();
min_max_opt_list.empty();
join= 0;
having= prep_having= where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE;
......
......@@ -704,6 +704,11 @@ class st_select_lex: public st_select_lex_node
*/
List<Item_func_match> *ftfunc_list;
List<Item_func_match> ftfunc_list_alloc;
/*
The list of items to which MIN/MAX optimizations of opt_sum_query()
have been applied. Used to rollback those optimizations if it's needed.
*/
List<Item_sum> min_max_opt_list;
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
List<TABLE_LIST> top_join_list; /* join list of the top level */
List<TABLE_LIST> *join_list; /* list for the currently parsed join */
......
......@@ -9487,12 +9487,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
/*
Step #2: Extract WHERE/ON parts
*/
uint i;
for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--)
{
if (!join->join_tab[i].bush_children)
break;
}
uint last_top_base_tab_idx= i;
table_map save_used_tables= 0;
used_tables=((select->const_tables=join->const_table_map) |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
JOIN_TAB *tab;
table_map current_map;
uint i= join->const_tables;
i= join->const_tables;
for (tab= first_depth_first_tab(join); tab;
tab= next_depth_first_tab(join, tab), i++)
{
......@@ -9530,7 +9538,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
Following force including random expression in last table condition.
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
*/
if (tab == join->join_tab + join->top_join_tab_count - 1)
if (tab == join->join_tab + last_top_base_tab_idx)
current_map|= RAND_TABLE_BIT;
used_tables|=current_map;
......@@ -9569,10 +9577,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
save_used_tables= 0;
}
else
{
tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
{
tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
FALSE, FALSE);
}
}
/* Add conditions added by add_not_null_conds(). */
if (tab->select_cond)
add_cond_and_fix(thd, &tmp, tab->select_cond);
......
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