Skip to content
/ server Public

Commit 2c2a418

Browse files
mariadb-YuchenPeispetrunia
authored andcommitted
MDEV-38327 Do not use rowid filter in ref_to_range when the range method is index merge
Index merge and rowid filter should not be used together, however, even if index merge is not chosen earlier in best_access_path, it may be chosen again in make_join_select, inside ref_to_range. Therefore this patch ensures that rowid filter is not used when index merge is chosen there.
1 parent 6229192 commit 2c2a418

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed

mysql-test/main/index_intersect.result

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,3 +973,69 @@ f1 f4 f5
973973
DROP TABLE t1;
974974
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
975975
SET SESSION optimizer_switch='rowid_filter=default';
976+
#
977+
# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
978+
#
979+
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
980+
INSERT INTO t1
981+
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
982+
explain select a, b, c from t1 where a=1000 and b=1001000;
983+
id select_type table type possible_keys key key_len ref rows Extra
984+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
985+
select a, b, c from t1 where a=1000 and b=1001000;
986+
a b c
987+
1000 1001000 1005000
988+
1000 1001000 1005001
989+
1000 1001000 1005002
990+
1000 1001000 1005003
991+
1000 1001000 1005004
992+
set optimizer_switch='index_merge_sort_intersection=on';
993+
explain select a, b, c from t1 where a=1000 and b=1001000;
994+
id select_type table type possible_keys key key_len ref rows Extra
995+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
996+
select a, b, c from t1 where a=1000 and b=1001000;
997+
a b c
998+
1000 1001000 1005000
999+
1000 1001000 1005001
1000+
1000 1001000 1005002
1001+
1000 1001000 1005003
1002+
1000 1001000 1005004
1003+
analyze table t1;
1004+
Table Op Msg_type Msg_text
1005+
test.t1 analyze status Engine-independent statistics collected
1006+
test.t1 analyze status Table is already up to date
1007+
explain select a, b, c from t1 where a=1000 and b=1001000;
1008+
id select_type table type possible_keys key key_len ref rows Extra
1009+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
1010+
select a, b, c from t1 where a=1000 and b=1001000;
1011+
a b c
1012+
1000 1001000 1005000
1013+
1000 1001000 1005001
1014+
1000 1001000 1005002
1015+
1000 1001000 1005003
1016+
1000 1001000 1005004
1017+
drop table t1;
1018+
## MDEV-28878 case
1019+
CREATE TABLE t1 (f int);
1020+
INSERT INTO t1 VALUES (0),(4);
1021+
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
1022+
INSERT INTO t2 VALUES
1023+
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
1024+
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
1025+
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
1026+
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
1027+
Table Op Msg_type Msg_text
1028+
test.t1 analyze status Engine-independent statistics collected
1029+
test.t1 analyze status OK
1030+
test.t2 analyze status Engine-independent statistics collected
1031+
test.t2 analyze status OK
1032+
SET optimizer_switch='rowid_filter=on';
1033+
SET optimizer_switch='index_merge_sort_intersection=off';
1034+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
1035+
f pk a b
1036+
4 3 4 p
1037+
SET optimizer_switch='index_merge_sort_intersection=on';
1038+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
1039+
f pk a b
1040+
4 3 4 p
1041+
DROP TABLE t1, t2;

mysql-test/main/index_intersect.test

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,3 +476,52 @@ DROP TABLE t1;
476476

477477
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
478478
SET SESSION optimizer_switch='rowid_filter=default';
479+
480+
--echo #
481+
--echo # MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
482+
--echo #
483+
--source include/have_sequence.inc
484+
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
485+
INSERT INTO t1
486+
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
487+
488+
let $query=
489+
select a, b, c from t1 where a=1000 and b=1001000;
490+
491+
eval explain $query;
492+
eval $query;
493+
494+
set optimizer_switch='index_merge_sort_intersection=on';
495+
496+
eval explain $query;
497+
eval $query;
498+
499+
analyze table t1;
500+
501+
eval explain $query;
502+
eval $query;
503+
504+
drop table t1;
505+
506+
--echo ## MDEV-28878 case
507+
508+
CREATE TABLE t1 (f int);
509+
INSERT INTO t1 VALUES (0),(4);
510+
511+
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
512+
INSERT INTO t2 VALUES
513+
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
514+
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
515+
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
516+
517+
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
518+
519+
SET optimizer_switch='rowid_filter=on'; # Default
520+
521+
SET optimizer_switch='index_merge_sort_intersection=off'; # Default
522+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
523+
524+
SET optimizer_switch='index_merge_sort_intersection=on';
525+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
526+
527+
DROP TABLE t1, t2;

mysql-test/main/index_intersect_innodb.result

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,72 @@ f1 f4 f5
979979
DROP TABLE t1;
980980
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
981981
SET SESSION optimizer_switch='rowid_filter=default';
982+
#
983+
# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on
984+
#
985+
CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d));
986+
INSERT INTO t1
987+
SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ;
988+
explain select a, b, c from t1 where a=1000 and b=1001000;
989+
id select_type table type possible_keys key key_len ref rows Extra
990+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
991+
select a, b, c from t1 where a=1000 and b=1001000;
992+
a b c
993+
1000 1001000 1005000
994+
1000 1001000 1005001
995+
1000 1001000 1005002
996+
1000 1001000 1005003
997+
1000 1001000 1005004
998+
set optimizer_switch='index_merge_sort_intersection=on';
999+
explain select a, b, c from t1 where a=1000 and b=1001000;
1000+
id select_type table type possible_keys key key_len ref rows Extra
1001+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
1002+
select a, b, c from t1 where a=1000 and b=1001000;
1003+
a b c
1004+
1000 1001000 1005000
1005+
1000 1001000 1005001
1006+
1000 1001000 1005002
1007+
1000 1001000 1005003
1008+
1000 1001000 1005004
1009+
analyze table t1;
1010+
Table Op Msg_type Msg_text
1011+
test.t1 analyze status Engine-independent statistics collected
1012+
test.t1 analyze status OK
1013+
explain select a, b, c from t1 where a=1000 and b=1001000;
1014+
id select_type table type possible_keys key key_len ref rows Extra
1015+
1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where
1016+
select a, b, c from t1 where a=1000 and b=1001000;
1017+
a b c
1018+
1000 1001000 1005000
1019+
1000 1001000 1005001
1020+
1000 1001000 1005002
1021+
1000 1001000 1005003
1022+
1000 1001000 1005004
1023+
drop table t1;
1024+
## MDEV-28878 case
1025+
CREATE TABLE t1 (f int);
1026+
INSERT INTO t1 VALUES (0),(4);
1027+
CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b));
1028+
INSERT INTO t2 VALUES
1029+
(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'),
1030+
(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'),
1031+
(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m');
1032+
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
1033+
Table Op Msg_type Msg_text
1034+
test.t1 analyze status Engine-independent statistics collected
1035+
test.t1 analyze status OK
1036+
test.t2 analyze status Engine-independent statistics collected
1037+
test.t2 analyze status OK
1038+
SET optimizer_switch='rowid_filter=on';
1039+
SET optimizer_switch='index_merge_sort_intersection=off';
1040+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
1041+
f pk a b
1042+
4 3 4 p
1043+
SET optimizer_switch='index_merge_sort_intersection=on';
1044+
SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5;
1045+
f pk a b
1046+
4 3 4 p
1047+
DROP TABLE t1, t2;
9821048
set global innodb_stats_persistent= @innodb_stats_persistent_save;
9831049
set global innodb_stats_persistent_sample_pages=
9841050
@innodb_stats_persistent_sample_pages_save;

sql/sql_select.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14456,6 +14456,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
1445614456
}
1445714457
tab->type= JT_RANGE;
1445814458
tab->use_quick=1;
14459+
if (is_index_merge(tab->quick->get_type()))
14460+
tab->clear_range_rowid_filter();
1445914461
tab->ref.key= -1;
1446014462
tab->ref.key_parts=0; // Don't use ref key.
1446114463
join->best_positions[i].records_read= rows2double(tab->quick->records);

0 commit comments

Comments
 (0)