Commit 9c9cf556 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in

Roll back to most general duplicate removing strategi in case of different stratagies for one position.
parent a9c55c00
......@@ -7146,3 +7146,29 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
(SELECT MAX(sq.f2) FROM t1)
NULL
drop table t1, t2;
#
# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
# (5.5 test)
#
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
End of 5.5 tests
......@@ -7143,6 +7143,32 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
(SELECT MAX(sq.f2) FROM t1)
NULL
drop table t1, t2;
#
# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
# (5.5 test)
#
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
End of 5.5 tests
set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
......
......@@ -7141,4 +7141,30 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
(SELECT MAX(sq.f2) FROM t1)
NULL
drop table t1, t2;
#
# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
# (5.5 test)
#
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
End of 5.5 tests
set @optimizer_switch_for_subselect_test=null;
......@@ -7152,6 +7152,32 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
(SELECT MAX(sq.f2) FROM t1)
NULL
drop table t1, t2;
#
# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
# (5.5 test)
#
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
End of 5.5 tests
set optimizer_switch=default;
select @@optimizer_switch like '%subquery_cache=on%';
@@optimizer_switch like '%subquery_cache=on%'
......
......@@ -7141,5 +7141,31 @@ SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
(SELECT MAX(sq.f2) FROM t1)
NULL
drop table t1, t2;
#
# MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
# (5.5 test)
#
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
a
5
5
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
End of 5.5 tests
set @optimizer_switch_for_subselect_test=null;
set @join_cache_level_for_subselect_test=NULL;
......@@ -6033,3 +6033,31 @@ CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
INSERT t2 VALUES (6),(9);
SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
drop table t1, t2;
--echo #
--echo # MDEV-13933: Wrong results in COUNT() query with EXISTS and exists_to_in
--echo # (5.5 test)
--echo #
SET @optimiser_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (1),(1),(1),(5),(5);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (5),(1);
CREATE TABLE t3 (c INT, KEY(c));
INSERT INTO t3 VALUES (5),(5);
SET optimizer_switch='semijoin=on';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
SET optimizer_switch='semijoin=off';
select t1.a from t1 where t1.a in (select `test`.`t2`.`b` from `test`.`t2`)
and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
SET @@optimizer_switch= @optimiser_switch_save;
DROP TABLE t1, t2, t3;
--echo End of 5.5 tests
......@@ -2687,7 +2687,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
LooseScan detector in best_access_path)
*/
remaining_tables &= ~new_join_tab->table->map;
table_map dups_producing_tables;
table_map dups_producing_tables, prev_dups_producing_tables,
prev_sjm_lookup_tables;
if (idx == join->const_tables)
dups_producing_tables= 0;
......@@ -2698,7 +2699,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
dups_producing_tables |= emb_sj_nest->sj_inner_tables;
Semi_join_strategy_picker **strategy;
Semi_join_strategy_picker **strategy, **prev_strategy;
if (idx == join->const_tables)
{
/* First table, initialize pickers */
......@@ -2750,23 +2751,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
3. We have no clue what to do about fanount of semi-join Y.
*/
if ((dups_producing_tables & handled_fanout) ||
(read_time < *current_read_time &&
(read_time < *current_read_time &&
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{
/* Mark strategy as used */
(*strategy)->mark_used();
pos->sj_strategy= sj_strategy;
if (sj_strategy == SJ_OPT_MATERIALIZE)
join->sjm_lookup_tables |= handled_fanout;
DBUG_ASSERT(pos->sj_strategy != sj_strategy);
/*
If the strategy choosen first time or
the strategy replace strategy which was used to exectly the same
tables
*/
if (pos->sj_strategy == SJ_OPT_NONE ||
handled_fanout ==
(prev_dups_producing_tables ^ dups_producing_tables))
{
prev_strategy= strategy;
if (pos->sj_strategy == SJ_OPT_NONE)
{
prev_dups_producing_tables= dups_producing_tables;
prev_sjm_lookup_tables= join->sjm_lookup_tables;
}
/* Mark strategy as used */
(*strategy)->mark_used();
pos->sj_strategy= sj_strategy;
if (sj_strategy == SJ_OPT_MATERIALIZE)
join->sjm_lookup_tables |= handled_fanout;
else
join->sjm_lookup_tables &= ~handled_fanout;
*current_read_time= read_time;
*current_record_count= rec_count;
dups_producing_tables &= ~handled_fanout;
//TODO: update bitmap of semi-joins that were handled together with
// others.
if (is_multiple_semi_joins(join, join->positions, idx,
handled_fanout))
pos->inner_tables_handled_with_other_sjs |= handled_fanout;
}
else
join->sjm_lookup_tables &= ~handled_fanout;
*current_read_time= read_time;
*current_record_count= rec_count;
dups_producing_tables &= ~handled_fanout;
//TODO: update bitmap of semi-joins that were handled together with
// others.
if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
pos->inner_tables_handled_with_other_sjs |= handled_fanout;
{
/* Conflict fall to most general variant */
(*prev_strategy)->set_empty();
dups_producing_tables= prev_dups_producing_tables;
join->sjm_lookup_tables= prev_sjm_lookup_tables;
// mark it 'none' to avpoid loops
pos->sj_strategy= SJ_OPT_NONE;
// next skip to last;
strategy= pickers +
(sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
continue;
}
}
else
{
......
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