Skip to content

Commit 8d7462e

Browse files
committed
MDEV-21614 Wrong query results with optimizer_switch="split_materialized=on"
Do not materialize a semi-join nest if it contains a materialized derived table /view that potentially can be subject to the split optimization. Splitting of materialization of such nest would help, but currently there is no code to support this technique.
1 parent fafb35e commit 8d7462e

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

mysql-test/main/derived_cond_pushdown.result

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16829,4 +16829,93 @@ id username id userid logindate
1682916829
2 user2 3 2 2017-06-19 12:17:02
1683016830
set join_cache_level=default;
1683116831
DROP TABLE t1,t2;
16832+
#
16833+
# MDEV-21614: potentially splittable materialized derived/view
16834+
# within materialized semi-join
16835+
#
16836+
create table t1 (
16837+
id int not null auto_increment primary key,
16838+
a int not null
16839+
) engine=myisam;
16840+
create table t2 (
16841+
id int not null auto_increment primary key,
16842+
ro_id int not null,
16843+
flag int not null, key (ro_id)
16844+
) engine=myisam;
16845+
insert into t1(a) select seq+100 from seq_1_to_20;
16846+
insert into t2(ro_id,flag) select seq, 1 from seq_1_to_20;
16847+
insert into t2(ro_id,flag) select seq, 0 from seq_1_to_20;
16848+
create view v1 as
16849+
select t1.* from t1 left join t2 on (t1.id = t2.ro_id AND t2.flag = 1)
16850+
group by t1.id;
16851+
select id, a from t1 where id in (select id from v1);
16852+
id a
16853+
1 101
16854+
2 102
16855+
3 103
16856+
4 104
16857+
5 105
16858+
6 106
16859+
7 107
16860+
8 108
16861+
9 109
16862+
10 110
16863+
11 111
16864+
12 112
16865+
13 113
16866+
14 114
16867+
15 115
16868+
16 116
16869+
17 117
16870+
18 118
16871+
19 119
16872+
20 120
16873+
explain extended select id, a from t1 where id in (select id from v1);
16874+
id select_type table type possible_keys key key_len ref rows filtered Extra
16875+
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00
16876+
1 PRIMARY <derived3> ref key0 key0 4 test.t1.id 2 100.00 FirstMatch(t1)
16877+
3 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00
16878+
3 LATERAL DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where
16879+
Warnings:
16880+
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`v1`) where `v1`.`id` = `test`.`t1`.`id`
16881+
select id, a from t1
16882+
where id in (select id
16883+
from (select t1.* from t1 left join t2
16884+
on (t1.id = t2.ro_id AND t2.flag = 1)
16885+
group by t1.id) dt);
16886+
id a
16887+
1 101
16888+
2 102
16889+
3 103
16890+
4 104
16891+
5 105
16892+
6 106
16893+
7 107
16894+
8 108
16895+
9 109
16896+
10 110
16897+
11 111
16898+
12 112
16899+
13 113
16900+
14 114
16901+
15 115
16902+
16 116
16903+
17 117
16904+
18 118
16905+
19 119
16906+
20 120
16907+
explain extended select id, a from t1
16908+
where id in (select id
16909+
from (select t1.* from t1 left join t2
16910+
on (t1.id = t2.ro_id AND t2.flag = 1)
16911+
group by t1.id) dt);
16912+
id select_type table type possible_keys key key_len ref rows filtered Extra
16913+
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00
16914+
1 PRIMARY <derived3> ref key0 key0 4 test.t1.id 2 100.00 FirstMatch(t1)
16915+
3 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00
16916+
3 LATERAL DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where
16917+
Warnings:
16918+
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` semi join ((/* select#3 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`ro_id` = `test`.`t1`.`id` and `test`.`t2`.`flag` = 1) where `test`.`t1`.`id` = `test`.`t1`.`id` group by `test`.`t1`.`id`) `dt`) where `dt`.`id` = `test`.`t1`.`id`
16919+
drop view v1;
16920+
drop table t1,t2;
1683216921
# End of 10.3 tests

mysql-test/main/derived_cond_pushdown.test

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
--source include/have_sequence.inc
12
--source include/default_optimizer_switch.inc
23
let $no_pushdown= set statement optimizer_switch='condition_pushdown_for_derived=off' for;
34
set @@join_buffer_size=256*1024;
@@ -3328,4 +3329,46 @@ set join_cache_level=default;
33283329

33293330
DROP TABLE t1,t2;
33303331

3332+
3333+
--echo #
3334+
--echo # MDEV-21614: potentially splittable materialized derived/view
3335+
--echo # within materialized semi-join
3336+
--echo #
3337+
3338+
create table t1 (
3339+
id int not null auto_increment primary key,
3340+
a int not null
3341+
) engine=myisam;
3342+
3343+
create table t2 (
3344+
id int not null auto_increment primary key,
3345+
ro_id int not null,
3346+
flag int not null, key (ro_id)
3347+
) engine=myisam;
3348+
3349+
insert into t1(a) select seq+100 from seq_1_to_20;
3350+
insert into t2(ro_id,flag) select seq, 1 from seq_1_to_20;
3351+
insert into t2(ro_id,flag) select seq, 0 from seq_1_to_20;
3352+
3353+
create view v1 as
3354+
select t1.* from t1 left join t2 on (t1.id = t2.ro_id AND t2.flag = 1)
3355+
group by t1.id;
3356+
3357+
let $q1=
3358+
select id, a from t1 where id in (select id from v1);
3359+
eval $q1;
3360+
eval explain extended $q1;
3361+
3362+
let $q2=
3363+
select id, a from t1
3364+
where id in (select id
3365+
from (select t1.* from t1 left join t2
3366+
on (t1.id = t2.ro_id AND t2.flag = 1)
3367+
group by t1.id) dt);
3368+
eval $q2;
3369+
eval explain extended $q2;
3370+
3371+
drop view v1;
3372+
drop table t1,t2;
3373+
33313374
--echo # End of 10.3 tests

sql/opt_split.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ struct SplM_field_ext_info: public SplM_field_info
307307
8. P contains some references on the columns of the joined tables C
308308
occurred also in the select list of this join
309309
9. There are defined some keys usable for ref access of fields from C
310-
with available statistics.
310+
with available statistics.
311311
312312
@retval
313313
true if the answer is positive
@@ -477,6 +477,15 @@ bool JOIN::check_for_splittable_materialized()
477477
/* Attach this info to the table T */
478478
derived->table->set_spl_opt_info(spl_opt_info);
479479

480+
/*
481+
If this is specification of a materialized derived table T that is
482+
potentially splittable and is used in the from list of the right operand
483+
of an IN predicand transformed to a semi-join then the embedding semi-join
484+
nest is not allowed to be materialized.
485+
*/
486+
if (derived && derived->is_materialized_derived() &&
487+
derived->embedding && derived->embedding->sj_subq_pred)
488+
derived->embedding->sj_subq_pred->types_allow_materialization= FALSE;
480489
return true;
481490
}
482491

0 commit comments

Comments
 (0)