mirror of
https://github.com/MariaDB/server.git
synced 2025-08-09 22:24:09 +03:00
Merge branch '10.2' of github.com:MariaDB/server into bb-10.2-mariarocks
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -97,6 +97,9 @@ pcre/pcre_chartables.c
|
|||||||
pcre/pcregrep
|
pcre/pcregrep
|
||||||
pcre/pcretest
|
pcre/pcretest
|
||||||
pcre/test*grep
|
pcre/test*grep
|
||||||
|
plugin/aws_key_management/aws-sdk-cpp
|
||||||
|
plugin/aws_key_management/aws_sdk_cpp
|
||||||
|
plugin/aws_key_management/aws_sdk_cpp-prefix
|
||||||
scripts/comp_sql
|
scripts/comp_sql
|
||||||
scripts/make_binary_distribution
|
scripts/make_binary_distribution
|
||||||
scripts/msql2mysql
|
scripts/msql2mysql
|
||||||
|
@@ -2332,3 +2332,677 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# MDEV-10454: range access keys extracted
|
||||||
|
# from <row> IN (<row value list>)
|
||||||
|
#
|
||||||
|
create table t1(a int, b int, c varchar(16), key idx(a,b)) engine=myisam;
|
||||||
|
insert into t1 values
|
||||||
|
(1,1,'xx'), (2,2,'yyy'), (3,3,'zzzz'), (1,2,'zz'), (1,3,'x'),
|
||||||
|
(2,3,'yy'), (4,5,'ww'), (7,8,'xxxxx'), (4,3,'zyx'), (1,2,'uuu'),
|
||||||
|
(2,1,'w'), (5,5,'wx'), (2,3,'ww'), (7,7,'xxxyy'), (3,3,'zyxw'),
|
||||||
|
(3,2,'uuuw'), (2,2,'wxz'), (5,5,'xw'), (12,12,'xx'), (12,12,'y'),
|
||||||
|
(13,13,'z'), (11,12,'zz'), (11,13,'x'), (12,13,'y'), (14,15,'w'),
|
||||||
|
(17,18,'xx'), (14,13,'zx'), (11,12,'u'), (12,11,'w'), (5,5,'wx'),
|
||||||
|
(12,13,'ww'), (17,17,'xxxyy'), (13,13,'zyxw'), (13,12,'uuuw'), (12,12,'wxz'),
|
||||||
|
(15,15,'xw'), (1,1,'xa'), (2,2,'yya'), (3,3,'zzza'), (1,2,'za'),
|
||||||
|
(1,3,'xb'), (2,3,'ya'), (4,5,'wa'), (7,8,'xxxxa'), (4,3,'zya'),
|
||||||
|
(1,2,'uua'), (2,1,'wb'), (5,5,'wc'), (2,3,'wa'), (7,7,'xxxya'),
|
||||||
|
(3,3,'zyxa'), (3,2,'uuua'), (2,2,'wxa'), (5,5,'xa'), (12,12,'xa'),
|
||||||
|
(22,12,'yb'), (23,13,'zb'), (21,12,'za'), (24,13,'c'), (32,13,'d'),
|
||||||
|
(34,15,'wd'), (47,18,'xa'), (54,13,'za'), (51,12,'ub'), (52,11,'wc'),
|
||||||
|
(5,5,'wd'), (62,13,'wa'), (67,17,'xxxya'), (63,13,'zyxa'), (73,12,'uuua'),
|
||||||
|
(82,12,'wxa'), (85,15,'xd');
|
||||||
|
# range access to t1 by 2-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 10 NULL 7 Using where
|
||||||
|
explain format=json select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "10",
|
||||||
|
"used_key_parts": ["a", "b"],
|
||||||
|
"rows": 7,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b) in (<cache>((2,3)),<cache>((3,3)),<cache>((8,8)),<cache>((7,7)))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
a b c
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
3 3 zzzz
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
3 3 zyxa
|
||||||
|
7 7 xxxyy
|
||||||
|
7 7 xxxya
|
||||||
|
prepare stmt from "select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7))";
|
||||||
|
execute stmt;
|
||||||
|
a b c
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
3 3 zzzz
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
3 3 zyxa
|
||||||
|
7 7 xxxyy
|
||||||
|
7 7 xxxya
|
||||||
|
execute stmt;
|
||||||
|
a b c
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
3 3 zzzz
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
3 3 zyxa
|
||||||
|
7 7 xxxyy
|
||||||
|
7 7 xxxya
|
||||||
|
deallocate prepare stmt;
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 5 Using where
|
||||||
|
explain format=json select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b + t1.a) in (<cache>((4,9)),<cache>((8,8)),<cache>((7,7)))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
a b c
|
||||||
|
4 5 ww
|
||||||
|
4 5 wa
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 5 Using where
|
||||||
|
explain format=json select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b) in ((4,t1.a - 1),(8,t1.a + 8),(7,t1.a + 7))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
a b c
|
||||||
|
4 3 zyx
|
||||||
|
4 3 zya
|
||||||
|
set @save_optimizer_switch=@@optimizer_switch;
|
||||||
|
set optimizer_switch='index_merge=off';
|
||||||
|
create table t2(
|
||||||
|
d int, e int, key idx1(d), key idx2(e), f varchar(32)
|
||||||
|
) engine=myisam;
|
||||||
|
insert into t2 values
|
||||||
|
(9,5,'a'), (9,8,'b'), (9,3,'c'), (9,2,'d'), (9,1,'e'),
|
||||||
|
(6,5,'f'), (6,3,'g'), (6,7,'h'), (3,3,'i'), (6,2,'j'),
|
||||||
|
(9,5,'aa'), (9,8,'ba'), (9,3,'ca'), (2,2,'da'), (9,1,'ea'),
|
||||||
|
(6,5,'fa'), (6,3,'ga'), (6,7,'ha'), (9,3,'ia'), (6,2,'ja');
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t1 by keys for index idx1
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx1,idx2 idx1 5 NULL 3 Using index condition; Using where
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 8
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx1",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t2.d is not null",
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((2,2)))"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 8,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 2 da
|
||||||
|
2 1 wb 2 2 da
|
||||||
|
2 2 yyy 2 2 da
|
||||||
|
2 2 wxz 2 2 da
|
||||||
|
2 2 yya 2 2 da
|
||||||
|
2 2 wxa 2 2 da
|
||||||
|
2 3 yy 2 2 da
|
||||||
|
2 3 ww 2 2 da
|
||||||
|
2 3 ya 2 2 da
|
||||||
|
2 3 wa 2 2 da
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
insert into t2 values
|
||||||
|
(4,5,'a'), (7,8,'b'), (4,3,'c'), (1,2,'d'), (2,1,'e'), (5,5,'f'),
|
||||||
|
(2,3,'g'), (7,7,'h'), (3,3,'i'), (3,2,'j'), (2,2,'k'), (5,5,'l'),
|
||||||
|
(4,5,'aa'), (7,8,'bb'), (4,3,'cc'), (1,2,'dd'), (2,1,'ee'), (9,5,'ff'),
|
||||||
|
(2,3,'gg'), (7,7,'hh'), (3,3,'ii'), (3,2,'jj'), (2,2,'kk'), (9,5,'ll'),
|
||||||
|
(4,5,'aaa'), (7,8,'bbb'), (4,3,'ccc'), (1,2,'ddd'), (2,1,'eee'), (5,5,'fff'),
|
||||||
|
(2,3,'ggg'), (7,7,'hhh'), (3,3,'iii'), (3,2,'jjj'), (2,2,'kkk'), (5,5,'lll'),
|
||||||
|
(14,15,'a'), (17,18,'b'), (14,13,'c'), (11,12,'d'), (12,11,'e'), (15,15,'f'),
|
||||||
|
(12,13,'g'), (17,17,'h'), (13,13,'i'), (13,12,'j'), (12,12,'k'), (15,15,'l'),
|
||||||
|
(24,25,'a'), (27,28,'b'), (24,23,'c'), (21,22,'d'), (22,21,'e'), (25,25,'f'),
|
||||||
|
(22,23,'g'), (27,27,'h'), (23,23,'i'), (23,22,'j'), (22,22,'k'), (25,25,'l'),
|
||||||
|
(34,35,'a'), (37,38,'b'), (34,33,'c'), (31,32,'d'), (32,31,'e'), (35,35,'f'),
|
||||||
|
(32,33,'g'), (37,37,'h'), (33,33,'i'), (33,32,'j'), (32,32,'k'), (35,35,'l'),
|
||||||
|
(44,45,'a'), (47,48,'b'), (44,43,'c'), (41,42,'d'), (42,41,'e'), (45,45,'f'),
|
||||||
|
(42,43,'g'), (47,47,'h'), (43,43,'i'), (43,42,'j'), (42,42,'k'), (45,45,'l');
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 6 Using index condition
|
||||||
|
1 SIMPLE t2 ref idx1,idx2 idx1 5 test.t1.a 12 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 6,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx1",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 12,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
prepare stmt from "select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
deallocate prepare stmt;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t2 by keys for index idx2
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx1,idx2 idx2 5 NULL 6 Using where
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 11
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx2",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["e"],
|
||||||
|
"rows": 6,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1 and t2.d is not null"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 11,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
alter table t2 drop index idx1, drop index idx2, add index idx3(d,e);
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t2 by 2-component keys for index idx3
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using index condition; Using where
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 11
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "10",
|
||||||
|
"used_key_parts": ["d", "e"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t2.d is not null",
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 11,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 15 Using index condition
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 15,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
4 3 zyx 4 5 a
|
||||||
|
4 3 zya 4 5 a
|
||||||
|
4 3 zyx 4 5 a
|
||||||
|
4 3 zya 4 5 a
|
||||||
|
4 5 ww 4 5 a
|
||||||
|
4 5 wa 4 5 a
|
||||||
|
4 5 ww 4 5 a
|
||||||
|
4 5 wa 4 5 a
|
||||||
|
7 7 xxxyy 7 8 b
|
||||||
|
7 7 xxxya 7 8 b
|
||||||
|
7 7 xxxyy 7 8 b
|
||||||
|
7 7 xxxya 7 8 b
|
||||||
|
7 8 xxxxx 7 8 b
|
||||||
|
7 8 xxxxa 7 8 b
|
||||||
|
7 8 xxxxx 7 8 b
|
||||||
|
7 8 xxxxa 7 8 b
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# no range access
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL idx NULL NULL NULL 144 Using where
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"rows": 144,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "t1.a is not null"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 13,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
prepare stmt from "select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
deallocate prepare stmt;
|
||||||
|
create table t3 (id int primary key, v int) engine=myisam;
|
||||||
|
insert into t3 values
|
||||||
|
(3,2), (1,1), (4,12), (2,15);
|
||||||
|
# join order: (t3,t1,t2) with const t3 and ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t3",
|
||||||
|
"access_type": "const",
|
||||||
|
"possible_keys": ["PRIMARY"],
|
||||||
|
"key": "PRIMARY",
|
||||||
|
"key_length": "4",
|
||||||
|
"used_key_parts": ["id"],
|
||||||
|
"ref": ["const"],
|
||||||
|
"rows": 1,
|
||||||
|
"filtered": 100
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 13,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
a b c d e f id v
|
||||||
|
2 1 w 2 1 e 1 1
|
||||||
|
2 1 w 2 2 k 1 1
|
||||||
|
2 1 w 2 3 g 1 1
|
||||||
|
2 1 w 2 1 e 1 1
|
||||||
|
2 1 w 2 2 k 1 1
|
||||||
|
2 1 w 2 3 g 1 1
|
||||||
|
# IN predicate is always FALSE
|
||||||
|
explain select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((9,9),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
prepare stmt from "select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((9,9),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f id v
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f id v
|
||||||
|
deallocate prepare stmt;
|
||||||
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
#
|
||||||
|
# End of 10.2 tests
|
||||||
|
#
|
||||||
|
@@ -2334,4 +2334,688 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# MDEV-10454: range access keys extracted
|
||||||
|
# from <row> IN (<row value list>)
|
||||||
|
#
|
||||||
|
create table t1(a int, b int, c varchar(16), key idx(a,b)) engine=myisam;
|
||||||
|
insert into t1 values
|
||||||
|
(1,1,'xx'), (2,2,'yyy'), (3,3,'zzzz'), (1,2,'zz'), (1,3,'x'),
|
||||||
|
(2,3,'yy'), (4,5,'ww'), (7,8,'xxxxx'), (4,3,'zyx'), (1,2,'uuu'),
|
||||||
|
(2,1,'w'), (5,5,'wx'), (2,3,'ww'), (7,7,'xxxyy'), (3,3,'zyxw'),
|
||||||
|
(3,2,'uuuw'), (2,2,'wxz'), (5,5,'xw'), (12,12,'xx'), (12,12,'y'),
|
||||||
|
(13,13,'z'), (11,12,'zz'), (11,13,'x'), (12,13,'y'), (14,15,'w'),
|
||||||
|
(17,18,'xx'), (14,13,'zx'), (11,12,'u'), (12,11,'w'), (5,5,'wx'),
|
||||||
|
(12,13,'ww'), (17,17,'xxxyy'), (13,13,'zyxw'), (13,12,'uuuw'), (12,12,'wxz'),
|
||||||
|
(15,15,'xw'), (1,1,'xa'), (2,2,'yya'), (3,3,'zzza'), (1,2,'za'),
|
||||||
|
(1,3,'xb'), (2,3,'ya'), (4,5,'wa'), (7,8,'xxxxa'), (4,3,'zya'),
|
||||||
|
(1,2,'uua'), (2,1,'wb'), (5,5,'wc'), (2,3,'wa'), (7,7,'xxxya'),
|
||||||
|
(3,3,'zyxa'), (3,2,'uuua'), (2,2,'wxa'), (5,5,'xa'), (12,12,'xa'),
|
||||||
|
(22,12,'yb'), (23,13,'zb'), (21,12,'za'), (24,13,'c'), (32,13,'d'),
|
||||||
|
(34,15,'wd'), (47,18,'xa'), (54,13,'za'), (51,12,'ub'), (52,11,'wc'),
|
||||||
|
(5,5,'wd'), (62,13,'wa'), (67,17,'xxxya'), (63,13,'zyxa'), (73,12,'uuua'),
|
||||||
|
(82,12,'wxa'), (85,15,'xd');
|
||||||
|
# range access to t1 by 2-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 10 NULL 7 Using where; Rowid-ordered scan
|
||||||
|
explain format=json select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "10",
|
||||||
|
"used_key_parts": ["a", "b"],
|
||||||
|
"rows": 7,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b) in (<cache>((2,3)),<cache>((3,3)),<cache>((8,8)),<cache>((7,7)))",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
a b c
|
||||||
|
3 3 zzzz
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
7 7 xxxyy
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
7 7 xxxya
|
||||||
|
3 3 zyxa
|
||||||
|
prepare stmt from "select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7))";
|
||||||
|
execute stmt;
|
||||||
|
a b c
|
||||||
|
3 3 zzzz
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
7 7 xxxyy
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
7 7 xxxya
|
||||||
|
3 3 zyxa
|
||||||
|
execute stmt;
|
||||||
|
a b c
|
||||||
|
3 3 zzzz
|
||||||
|
2 3 yy
|
||||||
|
2 3 ww
|
||||||
|
7 7 xxxyy
|
||||||
|
3 3 zyxw
|
||||||
|
3 3 zzza
|
||||||
|
2 3 ya
|
||||||
|
2 3 wa
|
||||||
|
7 7 xxxya
|
||||||
|
3 3 zyxa
|
||||||
|
deallocate prepare stmt;
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 5 Using where; Rowid-ordered scan
|
||||||
|
explain format=json select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b + t1.a) in (<cache>((4,9)),<cache>((8,8)),<cache>((7,7)))",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
a b c
|
||||||
|
4 5 ww
|
||||||
|
4 5 wa
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 5 Using where; Rowid-ordered scan
|
||||||
|
explain format=json select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t1.b) in ((4,t1.a - 1),(8,t1.a + 8),(7,t1.a + 7))",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
a b c
|
||||||
|
4 3 zyx
|
||||||
|
4 3 zya
|
||||||
|
set @save_optimizer_switch=@@optimizer_switch;
|
||||||
|
set optimizer_switch='index_merge=off';
|
||||||
|
create table t2(
|
||||||
|
d int, e int, key idx1(d), key idx2(e), f varchar(32)
|
||||||
|
) engine=myisam;
|
||||||
|
insert into t2 values
|
||||||
|
(9,5,'a'), (9,8,'b'), (9,3,'c'), (9,2,'d'), (9,1,'e'),
|
||||||
|
(6,5,'f'), (6,3,'g'), (6,7,'h'), (3,3,'i'), (6,2,'j'),
|
||||||
|
(9,5,'aa'), (9,8,'ba'), (9,3,'ca'), (2,2,'da'), (9,1,'ea'),
|
||||||
|
(6,5,'fa'), (6,3,'ga'), (6,7,'ha'), (9,3,'ia'), (6,2,'ja');
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t1 by keys for index idx1
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx1,idx2 idx1 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 8
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx1",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t2.d is not null",
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((2,2)))",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 8,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
a b c d e f
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
2 1 w 2 2 da
|
||||||
|
2 1 wb 2 2 da
|
||||||
|
2 2 yyy 2 2 da
|
||||||
|
2 2 wxz 2 2 da
|
||||||
|
2 2 yya 2 2 da
|
||||||
|
2 2 wxa 2 2 da
|
||||||
|
2 3 yy 2 2 da
|
||||||
|
2 3 ww 2 2 da
|
||||||
|
2 3 ya 2 2 da
|
||||||
|
2 3 wa 2 2 da
|
||||||
|
insert into t2 values
|
||||||
|
(4,5,'a'), (7,8,'b'), (4,3,'c'), (1,2,'d'), (2,1,'e'), (5,5,'f'),
|
||||||
|
(2,3,'g'), (7,7,'h'), (3,3,'i'), (3,2,'j'), (2,2,'k'), (5,5,'l'),
|
||||||
|
(4,5,'aa'), (7,8,'bb'), (4,3,'cc'), (1,2,'dd'), (2,1,'ee'), (9,5,'ff'),
|
||||||
|
(2,3,'gg'), (7,7,'hh'), (3,3,'ii'), (3,2,'jj'), (2,2,'kk'), (9,5,'ll'),
|
||||||
|
(4,5,'aaa'), (7,8,'bbb'), (4,3,'ccc'), (1,2,'ddd'), (2,1,'eee'), (5,5,'fff'),
|
||||||
|
(2,3,'ggg'), (7,7,'hhh'), (3,3,'iii'), (3,2,'jjj'), (2,2,'kkk'), (5,5,'lll'),
|
||||||
|
(14,15,'a'), (17,18,'b'), (14,13,'c'), (11,12,'d'), (12,11,'e'), (15,15,'f'),
|
||||||
|
(12,13,'g'), (17,17,'h'), (13,13,'i'), (13,12,'j'), (12,12,'k'), (15,15,'l'),
|
||||||
|
(24,25,'a'), (27,28,'b'), (24,23,'c'), (21,22,'d'), (22,21,'e'), (25,25,'f'),
|
||||||
|
(22,23,'g'), (27,27,'h'), (23,23,'i'), (23,22,'j'), (22,22,'k'), (25,25,'l'),
|
||||||
|
(34,35,'a'), (37,38,'b'), (34,33,'c'), (31,32,'d'), (32,31,'e'), (35,35,'f'),
|
||||||
|
(32,33,'g'), (37,37,'h'), (33,33,'i'), (33,32,'j'), (32,32,'k'), (35,35,'l'),
|
||||||
|
(44,45,'a'), (47,48,'b'), (44,43,'c'), (41,42,'d'), (42,41,'e'), (45,45,'f'),
|
||||||
|
(42,43,'g'), (47,47,'h'), (43,43,'i'), (43,42,'j'), (42,42,'k'), (45,45,'l');
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 6 Using index condition; Rowid-ordered scan
|
||||||
|
1 SIMPLE t2 ref idx1,idx2 idx1 5 test.t1.a 12 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 6,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx1",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 12,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
prepare stmt from "select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
3 3 zzzz 3 3 i
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 3 zyxw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 2 uuuw 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
3 3 zzza 3 3 i
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 3 zyxa 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
3 2 uuua 3 3 i
|
||||||
|
deallocate prepare stmt;
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t2 by keys for index idx2
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx1,idx2 idx2 5 NULL 6 Using where; Rowid-ordered scan
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 11
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx1", "idx2"],
|
||||||
|
"key": "idx2",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["e"],
|
||||||
|
"rows": 6,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1 and t2.d is not null",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 11,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
alter table t2 drop index idx1, drop index idx2, add index idx3(d,e);
|
||||||
|
# join order: (t2,t1) with ref access of t1
|
||||||
|
# range access to t2 by 2-component keys for index idx3
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using index condition; Using where; Rowid-ordered scan
|
||||||
|
1 SIMPLE t1 ref idx idx 5 test.t2.d 11
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "10",
|
||||||
|
"used_key_parts": ["d", "e"],
|
||||||
|
"rows": 5,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t2.d is not null",
|
||||||
|
"attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"ref": ["test.t2.d"],
|
||||||
|
"rows": 11,
|
||||||
|
"filtered": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 15 Using index condition; Rowid-ordered scan
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 15,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
4 5 ww 4 5 a
|
||||||
|
7 8 xxxxx 7 8 b
|
||||||
|
4 3 zyx 4 5 a
|
||||||
|
7 7 xxxyy 7 8 b
|
||||||
|
4 5 wa 4 5 a
|
||||||
|
7 8 xxxxa 7 8 b
|
||||||
|
4 3 zya 4 5 a
|
||||||
|
7 7 xxxya 7 8 b
|
||||||
|
4 5 ww 4 5 a
|
||||||
|
7 8 xxxxx 7 8 b
|
||||||
|
4 3 zyx 4 5 a
|
||||||
|
7 7 xxxyy 7 8 b
|
||||||
|
4 5 wa 4 5 a
|
||||||
|
7 8 xxxxa 7 8 b
|
||||||
|
4 3 zya 4 5 a
|
||||||
|
7 7 xxxya 7 8 b
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# no range access
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL idx NULL NULL NULL 144 Using where
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"rows": 144,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "t1.a is not null"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
7 8 xxxxx 7 7 h
|
||||||
|
7 7 xxxyy 7 7 h
|
||||||
|
7 8 xxxxa 7 7 h
|
||||||
|
7 7 xxxya 7 7 h
|
||||||
|
# join order: (t1,t2) with ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where; Rowid-ordered scan
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 13,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
prepare stmt from "select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
2 1 w 2 1 e
|
||||||
|
2 1 w 2 2 k
|
||||||
|
2 1 w 2 3 g
|
||||||
|
deallocate prepare stmt;
|
||||||
|
create table t3 (id int primary key, v int) engine=myisam;
|
||||||
|
insert into t3 values
|
||||||
|
(3,2), (1,1), (4,12), (2,15);
|
||||||
|
# join order: (t3,t1,t2) with const t3 and ref access of t2
|
||||||
|
# range access to t1 by 1-component keys for index idx
|
||||||
|
explain select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t3 const PRIMARY PRIMARY 4 const 1
|
||||||
|
1 SIMPLE t1 range idx idx 5 NULL 13 Using index condition; Using where; Rowid-ordered scan
|
||||||
|
1 SIMPLE t2 ref idx3 idx3 5 test.t1.a 3 Using where
|
||||||
|
explain format=json select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t3",
|
||||||
|
"access_type": "const",
|
||||||
|
"possible_keys": ["PRIMARY"],
|
||||||
|
"key": "PRIMARY",
|
||||||
|
"key_length": "4",
|
||||||
|
"used_key_parts": ["id"],
|
||||||
|
"ref": ["const"],
|
||||||
|
"rows": 1,
|
||||||
|
"filtered": 100
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "range",
|
||||||
|
"possible_keys": ["idx"],
|
||||||
|
"key": "idx",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["a"],
|
||||||
|
"rows": 13,
|
||||||
|
"filtered": 100,
|
||||||
|
"index_condition": "t1.a is not null",
|
||||||
|
"attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1",
|
||||||
|
"mrr_type": "Rowid-ordered scan"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ref",
|
||||||
|
"possible_keys": ["idx3"],
|
||||||
|
"key": "idx3",
|
||||||
|
"key_length": "5",
|
||||||
|
"used_key_parts": ["d"],
|
||||||
|
"ref": ["test.t1.a"],
|
||||||
|
"rows": 3,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "length(t2.f) = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
a b c d e f id v
|
||||||
|
2 1 w 2 1 e 1 1
|
||||||
|
2 1 w 2 2 k 1 1
|
||||||
|
2 1 w 2 3 g 1 1
|
||||||
|
2 1 w 2 1 e 1 1
|
||||||
|
2 1 w 2 2 k 1 1
|
||||||
|
2 1 w 2 3 g 1 1
|
||||||
|
# IN predicate is always FALSE
|
||||||
|
explain select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((9,9),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
prepare stmt from "select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((9,9),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1";
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f id v
|
||||||
|
execute stmt;
|
||||||
|
a b c d e f id v
|
||||||
|
deallocate prepare stmt;
|
||||||
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
#
|
||||||
|
# End of 10.2 tests
|
||||||
|
#
|
||||||
set optimizer_switch=@mrr_icp_extra_tmp;
|
set optimizer_switch=@mrr_icp_extra_tmp;
|
||||||
|
@@ -1857,3 +1857,195 @@ DROP TABLE t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10454: range access keys extracted
|
||||||
|
--echo # from <row> IN (<row value list>)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1(a int, b int, c varchar(16), key idx(a,b)) engine=myisam;
|
||||||
|
|
||||||
|
insert into t1 values
|
||||||
|
(1,1,'xx'), (2,2,'yyy'), (3,3,'zzzz'), (1,2,'zz'), (1,3,'x'),
|
||||||
|
(2,3,'yy'), (4,5,'ww'), (7,8,'xxxxx'), (4,3,'zyx'), (1,2,'uuu'),
|
||||||
|
(2,1,'w'), (5,5,'wx'), (2,3,'ww'), (7,7,'xxxyy'), (3,3,'zyxw'),
|
||||||
|
(3,2,'uuuw'), (2,2,'wxz'), (5,5,'xw'), (12,12,'xx'), (12,12,'y'),
|
||||||
|
(13,13,'z'), (11,12,'zz'), (11,13,'x'), (12,13,'y'), (14,15,'w'),
|
||||||
|
(17,18,'xx'), (14,13,'zx'), (11,12,'u'), (12,11,'w'), (5,5,'wx'),
|
||||||
|
(12,13,'ww'), (17,17,'xxxyy'), (13,13,'zyxw'), (13,12,'uuuw'), (12,12,'wxz'),
|
||||||
|
(15,15,'xw'), (1,1,'xa'), (2,2,'yya'), (3,3,'zzza'), (1,2,'za'),
|
||||||
|
(1,3,'xb'), (2,3,'ya'), (4,5,'wa'), (7,8,'xxxxa'), (4,3,'zya'),
|
||||||
|
(1,2,'uua'), (2,1,'wb'), (5,5,'wc'), (2,3,'wa'), (7,7,'xxxya'),
|
||||||
|
(3,3,'zyxa'), (3,2,'uuua'), (2,2,'wxa'), (5,5,'xa'), (12,12,'xa'),
|
||||||
|
(22,12,'yb'), (23,13,'zb'), (21,12,'za'), (24,13,'c'), (32,13,'d'),
|
||||||
|
(34,15,'wd'), (47,18,'xa'), (54,13,'za'), (51,12,'ub'), (52,11,'wc'),
|
||||||
|
(5,5,'wd'), (62,13,'wa'), (67,17,'xxxya'), (63,13,'zyxa'), (73,12,'uuua'),
|
||||||
|
(82,12,'wxa'), (85,15,'xd');
|
||||||
|
|
||||||
|
--echo # range access to t1 by 2-component keys for index idx
|
||||||
|
let $q1=
|
||||||
|
select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7));
|
||||||
|
eval explain $q1;
|
||||||
|
eval explain format=json $q1;
|
||||||
|
eval $q1;
|
||||||
|
eval prepare stmt from "$q1";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q2=
|
||||||
|
select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7));
|
||||||
|
eval explain $q2;
|
||||||
|
eval explain format=json $q2;
|
||||||
|
eval $q2;
|
||||||
|
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q3=
|
||||||
|
select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7));
|
||||||
|
eval explain $q3;
|
||||||
|
eval explain format=json $q3;
|
||||||
|
eval $q3;
|
||||||
|
|
||||||
|
# this setting should be removed after fixes for mdev-12186, mdev-12187
|
||||||
|
set @save_optimizer_switch=@@optimizer_switch;
|
||||||
|
set optimizer_switch='index_merge=off';
|
||||||
|
|
||||||
|
create table t2(
|
||||||
|
d int, e int, key idx1(d), key idx2(e), f varchar(32)
|
||||||
|
) engine=myisam;
|
||||||
|
|
||||||
|
insert into t2 values
|
||||||
|
(9,5,'a'), (9,8,'b'), (9,3,'c'), (9,2,'d'), (9,1,'e'),
|
||||||
|
(6,5,'f'), (6,3,'g'), (6,7,'h'), (3,3,'i'), (6,2,'j'),
|
||||||
|
(9,5,'aa'), (9,8,'ba'), (9,3,'ca'), (2,2,'da'), (9,1,'ea'),
|
||||||
|
(6,5,'fa'), (6,3,'ga'), (6,7,'ha'), (9,3,'ia'), (6,2,'ja');
|
||||||
|
|
||||||
|
--echo # join order: (t2,t1) with ref access of t1
|
||||||
|
--echo # range access to t1 by keys for index idx1
|
||||||
|
let $q4=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(2,2));
|
||||||
|
eval explain $q4;
|
||||||
|
eval explain format=json $q4;
|
||||||
|
eval $q4;
|
||||||
|
|
||||||
|
insert into t2 values
|
||||||
|
(4,5,'a'), (7,8,'b'), (4,3,'c'), (1,2,'d'), (2,1,'e'), (5,5,'f'),
|
||||||
|
(2,3,'g'), (7,7,'h'), (3,3,'i'), (3,2,'j'), (2,2,'k'), (5,5,'l'),
|
||||||
|
(4,5,'aa'), (7,8,'bb'), (4,3,'cc'), (1,2,'dd'), (2,1,'ee'), (9,5,'ff'),
|
||||||
|
(2,3,'gg'), (7,7,'hh'), (3,3,'ii'), (3,2,'jj'), (2,2,'kk'), (9,5,'ll'),
|
||||||
|
(4,5,'aaa'), (7,8,'bbb'), (4,3,'ccc'), (1,2,'ddd'), (2,1,'eee'), (5,5,'fff'),
|
||||||
|
(2,3,'ggg'), (7,7,'hhh'), (3,3,'iii'), (3,2,'jjj'), (2,2,'kkk'), (5,5,'lll'),
|
||||||
|
(14,15,'a'), (17,18,'b'), (14,13,'c'), (11,12,'d'), (12,11,'e'), (15,15,'f'),
|
||||||
|
(12,13,'g'), (17,17,'h'), (13,13,'i'), (13,12,'j'), (12,12,'k'), (15,15,'l'),
|
||||||
|
(24,25,'a'), (27,28,'b'), (24,23,'c'), (21,22,'d'), (22,21,'e'), (25,25,'f'),
|
||||||
|
(22,23,'g'), (27,27,'h'), (23,23,'i'), (23,22,'j'), (22,22,'k'), (25,25,'l'),
|
||||||
|
(34,35,'a'), (37,38,'b'), (34,33,'c'), (31,32,'d'), (32,31,'e'), (35,35,'f'),
|
||||||
|
(32,33,'g'), (37,37,'h'), (33,33,'i'), (33,32,'j'), (32,32,'k'), (35,35,'l'),
|
||||||
|
(44,45,'a'), (47,48,'b'), (44,43,'c'), (41,42,'d'), (42,41,'e'), (45,45,'f'),
|
||||||
|
(42,43,'g'), (47,47,'h'), (43,43,'i'), (43,42,'j'), (42,42,'k'), (45,45,'l');
|
||||||
|
|
||||||
|
--echo # join order: (t1,t2) with ref access of t2
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q5=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
eval explain $q5;
|
||||||
|
eval explain format=json $q5;
|
||||||
|
eval $q5;
|
||||||
|
eval prepare stmt from "$q5";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
insert into t1 select * from t1;
|
||||||
|
|
||||||
|
--echo # join order: (t2,t1) with ref access of t1
|
||||||
|
--echo # range access to t2 by keys for index idx2
|
||||||
|
let $q6=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
eval explain $q6;
|
||||||
|
eval explain format=json $q6;
|
||||||
|
eval $q6;
|
||||||
|
|
||||||
|
alter table t2 drop index idx1, drop index idx2, add index idx3(d,e);
|
||||||
|
|
||||||
|
--echo # join order: (t2,t1) with ref access of t1
|
||||||
|
--echo # range access to t2 by 2-component keys for index idx3
|
||||||
|
let $q7=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
eval explain $q7;
|
||||||
|
eval explain format=json $q7;
|
||||||
|
eval $q7;
|
||||||
|
|
||||||
|
--echo # join order: (t1,t2) with ref access of t2
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q8=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1;
|
||||||
|
eval explain $q8;
|
||||||
|
eval explain format=json $q8;
|
||||||
|
eval $q8;
|
||||||
|
|
||||||
|
--echo # join order: (t1,t2) with ref access of t2
|
||||||
|
--echo # no range access
|
||||||
|
let $q9=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1;
|
||||||
|
eval explain $q9;
|
||||||
|
eval explain format=json $q9;
|
||||||
|
eval $q9;
|
||||||
|
|
||||||
|
--echo # join order: (t1,t2) with ref access of t2
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q10=
|
||||||
|
select * from t1,t2
|
||||||
|
where a = d and (a,2) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
eval explain $q10;
|
||||||
|
eval explain format=json $q10;
|
||||||
|
eval $q10;
|
||||||
|
eval prepare stmt from "$q10";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
create table t3 (id int primary key, v int) engine=myisam;
|
||||||
|
|
||||||
|
insert into t3 values
|
||||||
|
(3,2), (1,1), (4,12), (2,15);
|
||||||
|
|
||||||
|
--echo # join order: (t3,t1,t2) with const t3 and ref access of t2
|
||||||
|
--echo # range access to t1 by 1-component keys for index idx
|
||||||
|
let $q11=
|
||||||
|
select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((2,2),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
eval explain $q11;
|
||||||
|
eval explain format=json $q11;
|
||||||
|
eval $q11;
|
||||||
|
|
||||||
|
--echo # IN predicate is always FALSE
|
||||||
|
let $q12=
|
||||||
|
select * from t1,t2,t3
|
||||||
|
where id = 1 and a = d and
|
||||||
|
(a,v+1) in ((9,9),(7,7),(8,8)) and
|
||||||
|
length(c) = 1 and length(f) = 1;
|
||||||
|
eval explain $q12;
|
||||||
|
eval prepare stmt from "$q12";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.2 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
@@ -51,10 +51,11 @@ ENDIF()
|
|||||||
FIND_LIBRARY(AWS_CPP_SDK_CORE NAMES aws-cpp-sdk-core PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
|
FIND_LIBRARY(AWS_CPP_SDK_CORE NAMES aws-cpp-sdk-core PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
|
||||||
FIND_LIBRARY(AWS_CPP_SDK_KMS NAMES aws-cpp-sdk-kms PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
|
FIND_LIBRARY(AWS_CPP_SDK_KMS NAMES aws-cpp-sdk-kms PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
|
||||||
SET(CMAKE_REQUIRED_FLAGS ${CXX11_FLAGS})
|
SET(CMAKE_REQUIRED_FLAGS ${CXX11_FLAGS})
|
||||||
CHECK_INCLUDE_FILE_CXX(aws/kms/KMSClient.h HAVE_AWS_HEADERS)
|
FIND_PATH(AWS_CPP_SDK_INCLUDE_DIR NAMES aws/kms/KMSClient.h)
|
||||||
|
|
||||||
IF(AWS_CPP_SDK_CORE AND AWS_CPP_SDK_KMS AND HAVE_AWS_HEADERS)
|
IF(AWS_CPP_SDK_CORE AND AWS_CPP_SDK_KMS AND AWS_CPP_SDK_INCLUDE_DIR)
|
||||||
# AWS C++ SDK installed
|
# AWS C++ SDK installed
|
||||||
|
INCLUDE_DIRECTORIES(${AWS_CPP_SDK_INCLUDE_DIR})
|
||||||
SET(AWS_SDK_LIBS ${AWS_CPP_SDK_CORE} ${AWS_CPP_SDK_KMS})
|
SET(AWS_SDK_LIBS ${AWS_CPP_SDK_CORE} ${AWS_CPP_SDK_KMS})
|
||||||
ELSE()
|
ELSE()
|
||||||
OPTION(AWS_SDK_EXTERNAL_PROJECT "Allow download and build AWS C++ SDK" OFF)
|
OPTION(AWS_SDK_EXTERNAL_PROJECT "Allow download and build AWS C++ SDK" OFF)
|
||||||
@@ -95,14 +96,28 @@ ELSE()
|
|||||||
SET(EXTRA_SDK_CMAKE_FLAGS ${EXTRA_SDK_CMAKE_FLAGS} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
|
SET(EXTRA_SDK_CMAKE_FLAGS ${EXTRA_SDK_CMAKE_FLAGS} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
SET(byproducts )
|
||||||
|
# We do not need to build the whole SDK , just 2 of its libs
|
||||||
|
set(AWS_SDK_LIBS aws-cpp-sdk-core aws-cpp-sdk-kms)
|
||||||
|
FOREACH(lib ${AWS_SDK_LIBS})
|
||||||
|
ADD_LIBRARY(${lib} STATIC IMPORTED GLOBAL)
|
||||||
|
ADD_DEPENDENCIES(${lib} aws_sdk_cpp)
|
||||||
|
SET(loc "${CMAKE_CURRENT_BINARY_DIR}/aws_sdk_cpp/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
IF(CMAKE_VERSION VERSION_GREATER "3.1")
|
||||||
|
SET(byproducts ${byproducts} BUILD_BYPRODUCTS ${loc})
|
||||||
|
ENDIF()
|
||||||
|
SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${loc})
|
||||||
|
ENDFOREACH()
|
||||||
|
|
||||||
SET(AWS_SDK_PATCH_COMMAND )
|
SET(AWS_SDK_PATCH_COMMAND )
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
aws_sdk_cpp
|
aws_sdk_cpp
|
||||||
GIT_REPOSITORY "https://github.com/awslabs/aws-sdk-cpp.git"
|
GIT_REPOSITORY "https://github.com/awslabs/aws-sdk-cpp.git"
|
||||||
GIT_TAG "1.0.8"
|
GIT_TAG "1.0.8"
|
||||||
UPDATE_COMMAND ""
|
UPDATE_COMMAND ""
|
||||||
SOURCE_DIR "${CMAKE_BINARY_DIR}/aws-sdk-cpp"
|
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/aws-sdk-cpp"
|
||||||
CMAKE_ARGS
|
${byproducts}
|
||||||
|
CMAKE_ARGS
|
||||||
-DBUILD_ONLY=kms
|
-DBUILD_ONLY=kms
|
||||||
-DBUILD_SHARED_LIBS=OFF
|
-DBUILD_SHARED_LIBS=OFF
|
||||||
-DFORCE_SHARED_CRT=OFF
|
-DFORCE_SHARED_CRT=OFF
|
||||||
@@ -111,34 +126,28 @@ ELSE()
|
|||||||
"-DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} ${PIC_FLAG}"
|
"-DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} ${PIC_FLAG}"
|
||||||
"-DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL} ${PIC_FLAG}"
|
"-DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL} ${PIC_FLAG}"
|
||||||
${EXTRA_SDK_CMAKE_FLAGS}
|
${EXTRA_SDK_CMAKE_FLAGS}
|
||||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/aws_sdk_cpp
|
-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/aws_sdk_cpp
|
||||||
TEST_COMMAND ""
|
TEST_COMMAND ""
|
||||||
)
|
)
|
||||||
SET_TARGET_PROPERTIES(aws_sdk_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
SET_TARGET_PROPERTIES(aws_sdk_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||||
# We do not need to build the whole SDK , just 2 of its libs
|
|
||||||
set(AWS_SDK_LIBS aws-cpp-sdk-core aws-cpp-sdk-kms)
|
|
||||||
FOREACH(lib ${AWS_SDK_LIBS})
|
|
||||||
ADD_LIBRARY(${lib} STATIC IMPORTED GLOBAL)
|
|
||||||
ADD_DEPENDENCIES(${lib} aws_sdk_cpp)
|
|
||||||
SET(loc "${CMAKE_BINARY_DIR}/aws_sdk_cpp/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
|
||||||
SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${loc})
|
|
||||||
IF(WIN32)
|
|
||||||
SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "bcrypt;winhttp;wininet;userenv")
|
|
||||||
ELSE()
|
|
||||||
SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${SSL_LIBRARIES};${CURL_LIBRARIES};${UUID_LIBRARIES}")
|
|
||||||
ENDIF()
|
|
||||||
ENDFOREACH()
|
|
||||||
|
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
# Need whole-archive , otherwise static libraries are not linked
|
# Need whole-archive , otherwise static libraries are not linked
|
||||||
SET(AWS_SDK_LIBS -Wl,--whole-archive ${AWS_SDK_LIBS} -Wl,--no-whole-archive)
|
SET(AWS_SDK_LIBS -Wl,--whole-archive ${AWS_SDK_LIBS} -Wl,--no-whole-archive)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET_TARGET_PROPERTIES(aws_sdk_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
SET_TARGET_PROPERTIES(aws_sdk_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/aws_sdk_cpp/include)
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/aws_sdk_cpp/include)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
ADD_DEFINITIONS(${SSL_DEFINES}) # Need to know whether openssl should be initialized
|
ADD_DEFINITIONS(${SSL_DEFINES}) # Need to know whether openssl should be initialized
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAGS}")
|
||||||
|
IF(WIN32)
|
||||||
|
SET(AWS_CPP_SDK_DEPENDENCIES bcrypt winhttp wininet userenv version)
|
||||||
|
ELSE()
|
||||||
|
SET(AWS_CPP_SDK_DEPENDENCIES ${SSL_LIBRARIES} ${CURL_LIBRARIES} ${UUID_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
MYSQL_ADD_PLUGIN(aws_key_management aws_key_management_plugin.cc
|
MYSQL_ADD_PLUGIN(aws_key_management aws_key_management_plugin.cc
|
||||||
LINK_LIBRARIES ${AWS_SDK_LIBS}
|
LINK_LIBRARIES ${AWS_SDK_LIBS} ${AWS_CPP_SDK_DEPENDENCIES}
|
||||||
COMPONENT aws-key-management)
|
COMPONENT aws-key-management)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1662,6 +1662,7 @@ public:
|
|||||||
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||||
table_map usable_tables, SARGABLE_PARAM **sargables);
|
table_map usable_tables, SARGABLE_PARAM **sargables);
|
||||||
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
|
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
|
||||||
|
SEL_TREE *get_func_row_mm_tree(RANGE_OPT_PARAM *param, Item_row *key_row);
|
||||||
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -1714,6 +1715,7 @@ public:
|
|||||||
cmp_item *make_same();
|
cmp_item *make_same();
|
||||||
void store_value_by_template(THD *thd, cmp_item *tmpl, Item *);
|
void store_value_by_template(THD *thd, cmp_item *tmpl, Item *);
|
||||||
friend void Item_func_in::fix_length_and_dec();
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
|
cmp_item *get_comparator(uint i) { return comparators[i]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1727,6 +1729,7 @@ public:
|
|||||||
uchar *get_value(Item *item);
|
uchar *get_value(Item *item);
|
||||||
friend void Item_func_in::fix_length_and_dec();
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
Item_result result_type() { return ROW_RESULT; }
|
Item_result result_type() { return ROW_RESULT; }
|
||||||
|
cmp_item *get_cmp_item() { return &tmp; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Functions used by where clause */
|
/* Functions used by where clause */
|
||||||
|
@@ -119,6 +119,13 @@ public:
|
|||||||
bool check_cols(uint c);
|
bool check_cols(uint c);
|
||||||
bool null_inside() { return with_null; };
|
bool null_inside() { return with_null; };
|
||||||
void bring_value();
|
void bring_value();
|
||||||
|
|
||||||
|
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
||||||
|
{
|
||||||
|
Item_args::propagate_equal_fields(thd, Context_identity(), cond);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
bool check_vcol_func_processor(void *arg) {return FALSE; }
|
bool check_vcol_func_processor(void *arg) {return FALSE; }
|
||||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||||
{ return get_item_copy<Item_row>(thd, mem_root, this); }
|
{ return get_item_copy<Item_row>(thd, mem_root, this); }
|
||||||
|
217
sql/opt_range.cc
217
sql/opt_range.cc
@@ -7210,6 +7210,205 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The structure Key_col_info is purely auxiliary and is used
|
||||||
|
only in the method Item_func_in::get_func_row_mm_tree
|
||||||
|
*/
|
||||||
|
struct Key_col_info {
|
||||||
|
Field *field; /* If != NULL the column can be used for keys */
|
||||||
|
cmp_item *comparator; /* If != 0 the column can be evaluated */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build SEL_TREE for the IN predicate whose arguments are rows
|
||||||
|
|
||||||
|
@param param PARAM from SQL_SELECT::test_quick_select
|
||||||
|
@param key_row First operand of the IN predicate
|
||||||
|
|
||||||
|
@note
|
||||||
|
The function builds a SEL_TREE for in IN predicate in the case
|
||||||
|
when the predicate uses row arguments. First the function
|
||||||
|
detects among the components of the key_row (c[1],...,c[n]) taken
|
||||||
|
from in the left part the predicate those that can be usable
|
||||||
|
for building SEL_TREE (c[i1],...,c[ik]). They have to contain
|
||||||
|
items whose real items are field items referring to the current
|
||||||
|
table or equal to the items referring to the current table.
|
||||||
|
For the remaining components of the row it checks whether they
|
||||||
|
can be evaluated. The result of the analysis is put into the
|
||||||
|
array of structures of the type Key_row_col_info.
|
||||||
|
|
||||||
|
After this the function builds the SEL_TREE for the following
|
||||||
|
formula that can be inferred from the given IN predicate:
|
||||||
|
c[i11]=a[1][i11] AND ... AND c[i1k1]=a[1][i1k1]
|
||||||
|
OR
|
||||||
|
...
|
||||||
|
OR
|
||||||
|
c[im1]=a[m][im1] AND ... AND c[imkm]=a[m][imkm].
|
||||||
|
Here a[1],...,a[m] are all arguments of the IN predicate from
|
||||||
|
the right part and for each j ij1,...,ijkj is a subset of
|
||||||
|
i1,...,ik such that a[j][ij1],...,a[j][ijkj] can be evaluated.
|
||||||
|
|
||||||
|
If for some j there no a[j][i1],...,a[j][ik] can be evaluated
|
||||||
|
then no SEL_TREE can be built for this predicate and the
|
||||||
|
function immediately returns 0.
|
||||||
|
|
||||||
|
If for some j by using evaluated values of key_row it can be
|
||||||
|
proven that c[ij1]=a[j][ij1] AND ... AND c[ijkj]=a[j][ijkj]
|
||||||
|
is always FALSE then this disjunct is omitted.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
the built SEL_TREE if it can be constructed
|
||||||
|
0 - otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SEL_TREE *Item_func_in::get_func_row_mm_tree(RANGE_OPT_PARAM *param,
|
||||||
|
Item_row *key_row)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Item_func_in::get_func_row_mm_tree");
|
||||||
|
|
||||||
|
if (negated)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
SEL_TREE *res_tree= 0;
|
||||||
|
uint used_key_cols= 0;
|
||||||
|
uint col_comparators= 0;
|
||||||
|
table_map param_comp= ~(param->prev_tables | param->read_tables |
|
||||||
|
param->current_table);
|
||||||
|
uint row_cols= key_row->cols();
|
||||||
|
Dynamic_array <Key_col_info> key_cols_info(row_cols);
|
||||||
|
cmp_item_row *row_cmp_item= (cmp_item_row *)
|
||||||
|
(array ? ((in_row *) array)->get_cmp_item() :
|
||||||
|
cmp_items[(uint) ROW_RESULT]);
|
||||||
|
|
||||||
|
Item **key_col_ptr= key_row->addr(0);
|
||||||
|
for(uint i= 0; i < row_cols; i++, key_col_ptr++)
|
||||||
|
{
|
||||||
|
Key_col_info key_col_info= {0, NULL};
|
||||||
|
Item *key_col= *key_col_ptr;
|
||||||
|
if (key_col->real_item()->type() == Item::FIELD_ITEM)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The i-th component of key_row can be used for key access if
|
||||||
|
key_col->real_item() points to a field of the current table or
|
||||||
|
if it is equal to a field item pointing to such a field.
|
||||||
|
*/
|
||||||
|
Item_field *col_field_item= (Item_field *) (key_col->real_item());
|
||||||
|
Field *key_col_field= col_field_item->field;
|
||||||
|
if (key_col_field->table->map != param->current_table)
|
||||||
|
{
|
||||||
|
Item_equal *item_equal= col_field_item->item_equal;
|
||||||
|
if (item_equal)
|
||||||
|
{
|
||||||
|
Item_equal_fields_iterator it(*item_equal);
|
||||||
|
while (it++)
|
||||||
|
{
|
||||||
|
key_col_field= it.get_curr_field();
|
||||||
|
if (key_col_field->table->map == param->current_table)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key_col_field->table->map == param->current_table)
|
||||||
|
{
|
||||||
|
key_col_info.field= key_col_field;
|
||||||
|
used_key_cols++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(key_col->used_tables() & (param_comp | param->current_table))
|
||||||
|
&& !key_col->is_expensive())
|
||||||
|
{
|
||||||
|
/* The i-th component of key_row can be evaluated */
|
||||||
|
|
||||||
|
/* See the comment in Item::get_mm_tree_for_const */
|
||||||
|
MEM_ROOT *tmp_root= param->mem_root;
|
||||||
|
param->thd->mem_root= param->old_root;
|
||||||
|
|
||||||
|
key_col->bring_value();
|
||||||
|
key_col_info.comparator= row_cmp_item->get_comparator(i);
|
||||||
|
key_col_info.comparator->store_value(key_col);
|
||||||
|
col_comparators++;
|
||||||
|
|
||||||
|
param->thd->mem_root= tmp_root;
|
||||||
|
}
|
||||||
|
key_cols_info.push(key_col_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!used_key_cols)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
uint omitted_tuples= 0;
|
||||||
|
Item **arg_start= arguments() + 1;
|
||||||
|
Item **arg_end= arg_start + argument_count() - 1;
|
||||||
|
for (Item **arg= arg_start ; arg < arg_end; arg++)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
First check whether the disjunct constructed for *arg
|
||||||
|
is really needed
|
||||||
|
*/
|
||||||
|
Item_row *arg_tuple= (Item_row *) (*arg);
|
||||||
|
if (col_comparators)
|
||||||
|
{
|
||||||
|
MEM_ROOT *tmp_root= param->mem_root;
|
||||||
|
param->thd->mem_root= param->old_root;
|
||||||
|
for (i= 0; i < row_cols; i++)
|
||||||
|
{
|
||||||
|
Key_col_info *key_col_info= &key_cols_info.at(i);
|
||||||
|
if (key_col_info->comparator)
|
||||||
|
{
|
||||||
|
Item *arg_col= arg_tuple->element_index(i);
|
||||||
|
if (!(arg_col->used_tables() & (param_comp | param->current_table)) &&
|
||||||
|
!arg_col->is_expensive() &&
|
||||||
|
key_col_info->comparator->cmp(arg_col))
|
||||||
|
{
|
||||||
|
omitted_tuples++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param->thd->mem_root= tmp_root;
|
||||||
|
if (i < row_cols)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The disjunct for *arg is needed: build it. */
|
||||||
|
SEL_TREE *and_tree= 0;
|
||||||
|
Item **arg_col_ptr= arg_tuple->addr(0);
|
||||||
|
for (uint i= 0; i < row_cols; i++, arg_col_ptr++)
|
||||||
|
{
|
||||||
|
Key_col_info *key_col_info= &key_cols_info.at(i);
|
||||||
|
if (!key_col_info->field)
|
||||||
|
continue;
|
||||||
|
Item *arg_col= *arg_col_ptr;
|
||||||
|
if (!(arg_col->used_tables() & (param_comp | param->current_table)) &&
|
||||||
|
!arg_col->is_expensive())
|
||||||
|
{
|
||||||
|
and_tree= tree_and(param, and_tree,
|
||||||
|
get_mm_parts(param,
|
||||||
|
key_col_info->field,
|
||||||
|
Item_func::EQ_FUNC,
|
||||||
|
arg_col->real_item()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!and_tree)
|
||||||
|
{
|
||||||
|
res_tree= 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Join the disjunct the the OR tree that is being constructed */
|
||||||
|
res_tree= !res_tree ? and_tree : tree_or(param, res_tree, and_tree);
|
||||||
|
}
|
||||||
|
if (omitted_tuples == argument_count() - 1)
|
||||||
|
{
|
||||||
|
/* It's turned out that all disjuncts are always FALSE */
|
||||||
|
res_tree= new (param->mem_root) SEL_TREE(SEL_TREE::IMPOSSIBLE,
|
||||||
|
param->mem_root, param->keys);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(res_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Build conjunction of all SEL_TREEs for a simple predicate applying equalities
|
Build conjunction of all SEL_TREEs for a simple predicate applying equalities
|
||||||
|
|
||||||
@@ -7544,12 +7743,22 @@ SEL_TREE *Item_func_in::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
|||||||
if (const_item())
|
if (const_item())
|
||||||
DBUG_RETURN(get_mm_tree_for_const(param));
|
DBUG_RETURN(get_mm_tree_for_const(param));
|
||||||
|
|
||||||
if (key_item()->real_item()->type() != Item::FIELD_ITEM)
|
SEL_TREE *tree= 0;
|
||||||
|
switch (key_item()->real_item()->type()) {
|
||||||
|
case Item::FIELD_ITEM:
|
||||||
|
tree= get_full_func_mm_tree(param,
|
||||||
|
(Item_field*) (key_item()->real_item()),
|
||||||
|
NULL);
|
||||||
|
break;
|
||||||
|
case Item::ROW_ITEM:
|
||||||
|
tree= get_func_row_mm_tree(param,
|
||||||
|
(Item_row *) (key_item()->real_item()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
Item_field *field= (Item_field*) (key_item()->real_item());
|
}
|
||||||
SEL_TREE *tree= get_full_func_mm_tree(param, field, NULL);
|
|
||||||
DBUG_RETURN(tree);
|
DBUG_RETURN(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SEL_TREE *Item_equal::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
SEL_TREE *Item_equal::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
||||||
|
@@ -4709,6 +4709,8 @@ static uint get_semi_join_select_list_index(Field *field)
|
|||||||
@param num_values Number of values[] that we are comparing against
|
@param num_values Number of values[] that we are comparing against
|
||||||
@param usable_tables Tables which can be used for key optimization
|
@param usable_tables Tables which can be used for key optimization
|
||||||
@param sargables IN/OUT Array of found sargable candidates
|
@param sargables IN/OUT Array of found sargable candidates
|
||||||
|
@param row_col_no if = n that > 0 then field is compared only
|
||||||
|
against the n-th component of row values
|
||||||
|
|
||||||
@note
|
@note
|
||||||
If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
|
If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
|
||||||
@@ -4722,7 +4724,8 @@ static void
|
|||||||
add_key_field(JOIN *join,
|
add_key_field(JOIN *join,
|
||||||
KEY_FIELD **key_fields,uint and_level, Item_bool_func *cond,
|
KEY_FIELD **key_fields,uint and_level, Item_bool_func *cond,
|
||||||
Field *field, bool eq_func, Item **value, uint num_values,
|
Field *field, bool eq_func, Item **value, uint num_values,
|
||||||
table_map usable_tables, SARGABLE_PARAM **sargables)
|
table_map usable_tables, SARGABLE_PARAM **sargables,
|
||||||
|
uint row_col_no= 0)
|
||||||
{
|
{
|
||||||
uint optimize= 0;
|
uint optimize= 0;
|
||||||
if (eq_func &&
|
if (eq_func &&
|
||||||
@@ -4751,7 +4754,15 @@ add_key_field(JOIN *join,
|
|||||||
bool optimizable=0;
|
bool optimizable=0;
|
||||||
for (uint i=0; i<num_values; i++)
|
for (uint i=0; i<num_values; i++)
|
||||||
{
|
{
|
||||||
table_map value_used_tables= (value[i])->used_tables();
|
Item *curr_val;
|
||||||
|
if (row_col_no && value[i]->real_item()->type() == Item::ROW_ITEM)
|
||||||
|
{
|
||||||
|
Item_row *value_tuple= (Item_row *) (value[i]->real_item());
|
||||||
|
curr_val= value_tuple->element_index(row_col_no - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
curr_val= value[i];
|
||||||
|
table_map value_used_tables= curr_val->used_tables();
|
||||||
used_tables|= value_used_tables;
|
used_tables|= value_used_tables;
|
||||||
if (!(value_used_tables & (field->table->map | RAND_TABLE_BIT)))
|
if (!(value_used_tables & (field->table->map | RAND_TABLE_BIT)))
|
||||||
optimizable=1;
|
optimizable=1;
|
||||||
@@ -4789,7 +4800,15 @@ add_key_field(JOIN *join,
|
|||||||
bool is_const=1;
|
bool is_const=1;
|
||||||
for (uint i=0; i<num_values; i++)
|
for (uint i=0; i<num_values; i++)
|
||||||
{
|
{
|
||||||
if (!(is_const&= value[i]->const_item()))
|
Item *curr_val;
|
||||||
|
if (row_col_no && value[i]->real_item()->type() == Item::ROW_ITEM)
|
||||||
|
{
|
||||||
|
Item_row *value_tuple= (Item_row *) (value[i]->real_item());
|
||||||
|
curr_val= value_tuple->element_index(row_col_no - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
curr_val= value[i];
|
||||||
|
if (!(is_const&= curr_val->const_item()))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (is_const)
|
if (is_const)
|
||||||
@@ -4856,12 +4875,14 @@ add_key_field(JOIN *join,
|
|||||||
@param key_fields Pointer to add key, if usable
|
@param key_fields Pointer to add key, if usable
|
||||||
@param and_level And level, to be stored in KEY_FIELD
|
@param and_level And level, to be stored in KEY_FIELD
|
||||||
@param cond Condition predicate
|
@param cond Condition predicate
|
||||||
@param field Field used in comparision
|
@param field_item Field item used for comparison
|
||||||
@param eq_func True if we used =, <=> or IS NULL
|
@param eq_func True if we used =, <=> or IS NULL
|
||||||
@param value Value used for comparison with field
|
@param value Value used for comparison with field_item
|
||||||
Is NULL for BETWEEN and IN
|
@param num_values Number of values[] that we are comparing against
|
||||||
@param usable_tables Tables which can be used for key optimization
|
@param usable_tables Tables which can be used for key optimization
|
||||||
@param sargables IN/OUT Array of found sargable candidates
|
@param sargables IN/OUT Array of found sargable candidates
|
||||||
|
@param row_col_no if = n that > 0 then field is compared only
|
||||||
|
against the n-th component of row values
|
||||||
|
|
||||||
@note
|
@note
|
||||||
If field items f1 and f2 belong to the same multiple equality and
|
If field items f1 and f2 belong to the same multiple equality and
|
||||||
@@ -4876,11 +4897,12 @@ add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level,
|
|||||||
Item_bool_func *cond, Item *field_item,
|
Item_bool_func *cond, Item *field_item,
|
||||||
bool eq_func, Item **val,
|
bool eq_func, Item **val,
|
||||||
uint num_values, table_map usable_tables,
|
uint num_values, table_map usable_tables,
|
||||||
SARGABLE_PARAM **sargables)
|
SARGABLE_PARAM **sargables, uint row_col_no= 0)
|
||||||
{
|
{
|
||||||
Field *field= ((Item_field *) (field_item->real_item()))->field;
|
Field *field= ((Item_field *) (field_item->real_item()))->field;
|
||||||
add_key_field(join, key_fields, and_level, cond, field,
|
add_key_field(join, key_fields, and_level, cond, field,
|
||||||
eq_func, val, num_values, usable_tables, sargables);
|
eq_func, val, num_values, usable_tables, sargables,
|
||||||
|
row_col_no);
|
||||||
Item_equal *item_equal= field_item->get_item_equal();
|
Item_equal *item_equal= field_item->get_item_equal();
|
||||||
if (item_equal)
|
if (item_equal)
|
||||||
{
|
{
|
||||||
@@ -4896,7 +4918,7 @@ add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level,
|
|||||||
{
|
{
|
||||||
add_key_field(join, key_fields, and_level, cond, equal_field,
|
add_key_field(join, key_fields, and_level, cond, equal_field,
|
||||||
eq_func, val, num_values, usable_tables,
|
eq_func, val, num_values, usable_tables,
|
||||||
sargables);
|
sargables, row_col_no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5078,6 +5100,24 @@ Item_func_in::add_key_fields(JOIN *join, KEY_FIELD **key_fields,
|
|||||||
(Item_field*) (args[0]->real_item()), false,
|
(Item_field*) (args[0]->real_item()), false,
|
||||||
args + 1, arg_count - 1, usable_tables, sargables);
|
args + 1, arg_count - 1, usable_tables, sargables);
|
||||||
}
|
}
|
||||||
|
else if (key_item()->type() == Item::ROW_ITEM &&
|
||||||
|
!(used_tables() & OUTER_REF_TABLE_BIT))
|
||||||
|
{
|
||||||
|
Item_row *key_row= (Item_row *) key_item();
|
||||||
|
Item **key_col= key_row->addr(0);
|
||||||
|
uint row_cols= key_row->cols();
|
||||||
|
for (uint i= 0; i < row_cols; i++, key_col++)
|
||||||
|
{
|
||||||
|
if (is_local_field(*key_col))
|
||||||
|
{
|
||||||
|
Item_field *field_item= (Item_field *)((*key_col)->real_item());
|
||||||
|
add_key_equal_fields(join, key_fields, *and_level, this,
|
||||||
|
field_item, false, args + 1, arg_count - 1,
|
||||||
|
usable_tables, sargables, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -136,15 +136,15 @@ btr_scrub_lock_dict_func(ulint space_id, bool lock_to_close_table,
|
|||||||
* if we don't lock to close a table, we check if space
|
* if we don't lock to close a table, we check if space
|
||||||
* is closing, and then instead give up
|
* is closing, and then instead give up
|
||||||
*/
|
*/
|
||||||
if (lock_to_close_table == false) {
|
if (lock_to_close_table) {
|
||||||
fil_space_t* space = fil_space_acquire(space_id);
|
} else if (fil_space_t* space = fil_space_acquire(space_id)) {
|
||||||
if (!space || space->stop_new_ops) {
|
bool stopping = space->is_stopping();
|
||||||
if (space) {
|
fil_space_release(space);
|
||||||
fil_space_release(space);
|
if (stopping) {
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fil_space_release(space);
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
os_thread_sleep(250000);
|
os_thread_sleep(250000);
|
||||||
|
|
||||||
@@ -206,18 +206,15 @@ btr_scrub_table_close_for_thread(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_t* space = fil_space_acquire(scrub_data->space);
|
if (fil_space_t* space = fil_space_acquire(scrub_data->space)) {
|
||||||
|
/* If tablespace is not marked as stopping perform
|
||||||
/* If tablespace is not marked as stopping perform
|
the actual close. */
|
||||||
the actual close. */
|
if (!space->is_stopping()) {
|
||||||
if (space && !space->is_stopping()) {
|
mutex_enter(&dict_sys->mutex);
|
||||||
mutex_enter(&dict_sys->mutex);
|
/* perform the actual closing */
|
||||||
/* perform the actual closing */
|
btr_scrub_table_close(scrub_data->current_table);
|
||||||
btr_scrub_table_close(scrub_data->current_table);
|
mutex_exit(&dict_sys->mutex);
|
||||||
mutex_exit(&dict_sys->mutex);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (space) {
|
|
||||||
fil_space_release(space);
|
fil_space_release(space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7535,12 +7535,12 @@ buf_page_decrypt_after_read(buf_page_t* bpage)
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilSpace space(bpage->id.space());
|
FilSpace space(bpage->id.space(), true);
|
||||||
|
|
||||||
/* Page is encrypted if encryption information is found from
|
/* Page is encrypted if encryption information is found from
|
||||||
tablespace and page contains used key_version. This is true
|
tablespace and page contains used key_version. This is true
|
||||||
also for pages first compressed and then encrypted. */
|
also for pages first compressed and then encrypted. */
|
||||||
if (!space()->crypt_data) {
|
if (!space() || !space()->crypt_data) {
|
||||||
key_version = 0;
|
key_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2268,12 +2268,13 @@ Used by background threads that do not necessarily hold proper locks
|
|||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@param[in] silent whether to silently ignore missing tablespaces
|
@param[in] silent whether to silently ignore missing tablespaces
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
inline
|
inline
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_low(
|
fil_space_acquire_low(ulint id, bool silent, bool for_io = false)
|
||||||
ulint id,
|
|
||||||
bool silent)
|
|
||||||
{
|
{
|
||||||
fil_space_t* space;
|
fil_space_t* space;
|
||||||
|
|
||||||
@@ -2286,7 +2287,7 @@ fil_space_acquire_low(
|
|||||||
ib::warn() << "Trying to access missing"
|
ib::warn() << "Trying to access missing"
|
||||||
" tablespace " << id;
|
" tablespace " << id;
|
||||||
}
|
}
|
||||||
} else if (space->stop_new_ops || space->is_being_truncated) {
|
} else if (!for_io && space->is_stopping()) {
|
||||||
space = NULL;
|
space = NULL;
|
||||||
} else {
|
} else {
|
||||||
space->n_pending_ops++;
|
space->n_pending_ops++;
|
||||||
@@ -2301,22 +2302,24 @@ fil_space_acquire_low(
|
|||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire(
|
fil_space_acquire(ulint id, bool for_io)
|
||||||
ulint id)
|
|
||||||
{
|
{
|
||||||
return(fil_space_acquire_low(id, false));
|
return(fil_space_acquire_low(id, false, for_io));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Acquire a tablespace that may not exist.
|
/** Acquire a tablespace that may not exist.
|
||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_silent(
|
fil_space_acquire_silent(ulint id)
|
||||||
ulint id)
|
|
||||||
{
|
{
|
||||||
return(fil_space_acquire_low(id, true));
|
return(fil_space_acquire_low(id, true));
|
||||||
}
|
}
|
||||||
@@ -2324,8 +2327,7 @@ fil_space_acquire_silent(
|
|||||||
/** Release a tablespace acquired with fil_space_acquire().
|
/** Release a tablespace acquired with fil_space_acquire().
|
||||||
@param[in,out] space tablespace to release */
|
@param[in,out] space tablespace to release */
|
||||||
void
|
void
|
||||||
fil_space_release(
|
fil_space_release(fil_space_t* space)
|
||||||
fil_space_t* space)
|
|
||||||
{
|
{
|
||||||
mutex_enter(&fil_system->mutex);
|
mutex_enter(&fil_system->mutex);
|
||||||
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N);
|
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N);
|
||||||
@@ -5479,8 +5481,7 @@ fil_flush(
|
|||||||
|
|
||||||
if (fil_space_t* space = fil_space_get_by_id(space_id)) {
|
if (fil_space_t* space = fil_space_get_by_id(space_id)) {
|
||||||
if (space->purpose != FIL_TYPE_TEMPORARY
|
if (space->purpose != FIL_TYPE_TEMPORARY
|
||||||
&& !space->stop_new_ops
|
&& !space->is_stopping()) {
|
||||||
&& !space->is_being_truncated) {
|
|
||||||
fil_flush_low(space);
|
fil_flush_low(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5524,8 +5525,7 @@ fil_flush_file_spaces(
|
|||||||
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
|
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
|
||||||
|
|
||||||
if (space->purpose == purpose
|
if (space->purpose == purpose
|
||||||
&& !space->stop_new_ops
|
&& !space->is_stopping()) {
|
||||||
&& !space->is_being_truncated) {
|
|
||||||
|
|
||||||
space_ids[n_space_ids++] = space->id;
|
space_ids[n_space_ids++] = space->id;
|
||||||
}
|
}
|
||||||
@@ -6701,8 +6701,7 @@ If NULL, use the first fil_space_t on fil_system->space_list.
|
|||||||
@return pointer to the next fil_space_t.
|
@return pointer to the next fil_space_t.
|
||||||
@retval NULL if this was the last*/
|
@retval NULL if this was the last*/
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_next(
|
fil_space_next(fil_space_t* prev_space)
|
||||||
fil_space_t* prev_space)
|
|
||||||
{
|
{
|
||||||
fil_space_t* space=prev_space;
|
fil_space_t* space=prev_space;
|
||||||
|
|
||||||
@@ -6725,8 +6724,8 @@ fil_space_next(
|
|||||||
fil_ibd_create(), or dropped, or !tablespace. */
|
fil_ibd_create(), or dropped, or !tablespace. */
|
||||||
while (space != NULL
|
while (space != NULL
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
&& (UT_LIST_GET_LEN(space->chain) == 0
|
||||||
|| space->stop_new_ops
|
|| space->is_stopping()
|
||||||
|| space->purpose != FIL_TYPE_TABLESPACE)) {
|
|| space->purpose != FIL_TYPE_TABLESPACE)) {
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
space = UT_LIST_GET_NEXT(space_list, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -735,27 +735,28 @@ MY_ATTRIBUTE((warn_unused_result));
|
|||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire(
|
fil_space_acquire(ulint id, bool for_io = false)
|
||||||
ulint id)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Acquire a tablespace that may not exist.
|
/** Acquire a tablespace that may not exist.
|
||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_silent(
|
fil_space_acquire_silent(ulint id)
|
||||||
ulint id)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Release a tablespace acquired with fil_space_acquire().
|
/** Release a tablespace acquired with fil_space_acquire().
|
||||||
@param[in,out] space tablespace to release */
|
@param[in,out] space tablespace to release */
|
||||||
void
|
void
|
||||||
fil_space_release(
|
fil_space_release(fil_space_t* space);
|
||||||
fil_space_t* space);
|
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
/** Return the next fil_space_t.
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
Once started, the caller must keep calling this until it returns NULL.
|
||||||
@@ -792,17 +793,19 @@ public:
|
|||||||
FilSpace() : m_space(NULL) {}
|
FilSpace() : m_space(NULL) {}
|
||||||
|
|
||||||
/** Constructor: Look up the tablespace and increment the
|
/** Constructor: Look up the tablespace and increment the
|
||||||
referece count if found.
|
reference count if found.
|
||||||
@param[in] space_id tablespace ID */
|
@param[in] space_id tablespace ID
|
||||||
explicit FilSpace(ulint space_id)
|
@param[in] for_io whether to look up the tablespace
|
||||||
: m_space(fil_space_acquire(space_id)) {}
|
while performing I/O
|
||||||
|
(possibly executing TRUNCATE) */
|
||||||
|
explicit FilSpace(ulint space_id, bool for_io = false)
|
||||||
|
: m_space(fil_space_acquire(space_id, for_io)) {}
|
||||||
|
|
||||||
/** Assignment operator: This assumes that fil_space_acquire()
|
/** Assignment operator: This assumes that fil_space_acquire()
|
||||||
has already been done for the fil_space_t. The caller must
|
has already been done for the fil_space_t. The caller must
|
||||||
assign NULL if it calls fil_space_release().
|
assign NULL if it calls fil_space_release().
|
||||||
@param[in] space tablespace to assign */
|
@param[in] space tablespace to assign */
|
||||||
class FilSpace& operator=(
|
class FilSpace& operator=(fil_space_t* space)
|
||||||
fil_space_t* space)
|
|
||||||
{
|
{
|
||||||
/* fil_space_acquire() must have been invoked. */
|
/* fil_space_acquire() must have been invoked. */
|
||||||
ut_ad(space == NULL || space->n_pending_ops > 0);
|
ut_ad(space == NULL || space->n_pending_ops > 0);
|
||||||
|
@@ -129,15 +129,15 @@ btr_scrub_lock_dict_func(ulint space_id, bool lock_to_close_table,
|
|||||||
* if we don't lock to close a table, we check if space
|
* if we don't lock to close a table, we check if space
|
||||||
* is closing, and then instead give up
|
* is closing, and then instead give up
|
||||||
*/
|
*/
|
||||||
if (lock_to_close_table == false) {
|
if (lock_to_close_table) {
|
||||||
fil_space_t* space = fil_space_acquire(space_id);
|
} else if (fil_space_t* space = fil_space_acquire(space_id)) {
|
||||||
if (!space || space->stop_new_ops) {
|
bool stopping = space->is_stopping();
|
||||||
if (space) {
|
fil_space_release(space);
|
||||||
fil_space_release(space);
|
if (stopping) {
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fil_space_release(space);
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
os_thread_sleep(250000);
|
os_thread_sleep(250000);
|
||||||
|
|
||||||
@@ -197,18 +197,15 @@ btr_scrub_table_close_for_thread(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_t* space = fil_space_acquire(scrub_data->space);
|
if (fil_space_t* space = fil_space_acquire(scrub_data->space)) {
|
||||||
|
/* If tablespace is not marked as stopping perform
|
||||||
/* If tablespace is not marked as stopping perform
|
the actual close. */
|
||||||
the actual close. */
|
if (!space->is_stopping()) {
|
||||||
if (space && !space->is_stopping()) {
|
mutex_enter(&dict_sys->mutex);
|
||||||
mutex_enter(&dict_sys->mutex);
|
/* perform the actual closing */
|
||||||
/* perform the actual closing */
|
btr_scrub_table_close(scrub_data->current_table);
|
||||||
btr_scrub_table_close(scrub_data->current_table);
|
mutex_exit(&dict_sys->mutex);
|
||||||
mutex_exit(&dict_sys->mutex);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (space) {
|
|
||||||
fil_space_release(space);
|
fil_space_release(space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6413,14 +6413,12 @@ buf_page_decrypt_after_read(
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_t* space = fil_space_acquire(bpage->space);
|
fil_space_t* space = fil_space_acquire(bpage->space, true);
|
||||||
|
|
||||||
fil_space_crypt_t* crypt_data = space->crypt_data;
|
|
||||||
|
|
||||||
/* Page is encrypted if encryption information is found from
|
/* Page is encrypted if encryption information is found from
|
||||||
tablespace and page contains used key_version. This is true
|
tablespace and page contains used key_version. This is true
|
||||||
also for pages first compressed and then encrypted. */
|
also for pages first compressed and then encrypted. */
|
||||||
if (!crypt_data) {
|
if (!space || !space->crypt_data) {
|
||||||
key_version = 0;
|
key_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6504,6 +6502,8 @@ buf_page_decrypt_after_read(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_release(space);
|
if (space != NULL) {
|
||||||
|
fil_space_release(space);
|
||||||
|
}
|
||||||
return (success);
|
return (success);
|
||||||
}
|
}
|
||||||
|
@@ -6389,16 +6389,12 @@ fil_flush(
|
|||||||
{
|
{
|
||||||
mutex_enter(&fil_system->mutex);
|
mutex_enter(&fil_system->mutex);
|
||||||
|
|
||||||
fil_space_t* space = fil_space_get_by_id(space_id);
|
if (fil_space_t* space = fil_space_get_by_id(space_id)) {
|
||||||
|
if (!space->is_stopping()) {
|
||||||
if (!space || space->stop_new_ops) {
|
fil_flush_low(space);
|
||||||
mutex_exit(&fil_system->mutex);
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_flush_low(space);
|
|
||||||
|
|
||||||
mutex_exit(&fil_system->mutex);
|
mutex_exit(&fil_system->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6438,8 +6434,7 @@ fil_flush_file_spaces(
|
|||||||
space;
|
space;
|
||||||
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
|
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
|
||||||
|
|
||||||
if (space->purpose == purpose && !space->stop_new_ops) {
|
if (space->purpose == purpose && !space->is_stopping()) {
|
||||||
|
|
||||||
space_ids[n_space_ids++] = space->id;
|
space_ids[n_space_ids++] = space->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7388,12 +7383,13 @@ Used by background threads that do not necessarily hold proper locks
|
|||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@param[in] silent whether to silently ignore missing tablespaces
|
@param[in] silent whether to silently ignore missing tablespaces
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
inline
|
inline
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_low(
|
fil_space_acquire_low(ulint id, bool silent, bool for_io = false)
|
||||||
ulint id,
|
|
||||||
bool silent)
|
|
||||||
{
|
{
|
||||||
fil_space_t* space;
|
fil_space_t* space;
|
||||||
|
|
||||||
@@ -7407,7 +7403,7 @@ fil_space_acquire_low(
|
|||||||
" tablespace " ULINTPF ".", id);
|
" tablespace " ULINTPF ".", id);
|
||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
} else if (space->stop_new_ops) {
|
} else if (!for_io && space->is_stopping()) {
|
||||||
space = NULL;
|
space = NULL;
|
||||||
} else {
|
} else {
|
||||||
space->n_pending_ops++;
|
space->n_pending_ops++;
|
||||||
@@ -7422,22 +7418,24 @@ fil_space_acquire_low(
|
|||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire(
|
fil_space_acquire(ulint id, bool for_io)
|
||||||
ulint id)
|
|
||||||
{
|
{
|
||||||
return(fil_space_acquire_low(id, false));
|
return(fil_space_acquire_low(id, false, for_io));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Acquire a tablespace that may not exist.
|
/** Acquire a tablespace that may not exist.
|
||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_silent(
|
fil_space_acquire_silent(ulint id)
|
||||||
ulint id)
|
|
||||||
{
|
{
|
||||||
return(fil_space_acquire_low(id, true));
|
return(fil_space_acquire_low(id, true));
|
||||||
}
|
}
|
||||||
@@ -7445,8 +7443,7 @@ fil_space_acquire_silent(
|
|||||||
/** Release a tablespace acquired with fil_space_acquire().
|
/** Release a tablespace acquired with fil_space_acquire().
|
||||||
@param[in,out] space tablespace to release */
|
@param[in,out] space tablespace to release */
|
||||||
void
|
void
|
||||||
fil_space_release(
|
fil_space_release(fil_space_t* space)
|
||||||
fil_space_t* space)
|
|
||||||
{
|
{
|
||||||
mutex_enter(&fil_system->mutex);
|
mutex_enter(&fil_system->mutex);
|
||||||
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N);
|
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N);
|
||||||
@@ -7464,8 +7461,7 @@ If NULL, use the first fil_space_t on fil_system->space_list.
|
|||||||
@return pointer to the next fil_space_t.
|
@return pointer to the next fil_space_t.
|
||||||
@retval NULL if this was the last*/
|
@retval NULL if this was the last*/
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_next(
|
fil_space_next(fil_space_t* prev_space)
|
||||||
fil_space_t* prev_space)
|
|
||||||
{
|
{
|
||||||
fil_space_t* space=prev_space;
|
fil_space_t* space=prev_space;
|
||||||
|
|
||||||
@@ -7488,8 +7484,8 @@ fil_space_next(
|
|||||||
fil_ibd_create(), or dropped, or !tablespace. */
|
fil_ibd_create(), or dropped, or !tablespace. */
|
||||||
while (space != NULL
|
while (space != NULL
|
||||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
&& (UT_LIST_GET_LEN(space->chain) == 0
|
||||||
|| space->stop_new_ops
|
|| space->is_stopping()
|
||||||
|| space->purpose != FIL_TABLESPACE)) {
|
|| space->purpose != FIL_TABLESPACE)) {
|
||||||
space = UT_LIST_GET_NEXT(space_list, space);
|
space = UT_LIST_GET_NEXT(space_list, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -650,27 +650,28 @@ fil_write_flushed_lsn_to_data_files(
|
|||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@param[in] for_io whether to look up the tablespace while performing I/O
|
||||||
|
(possibly executing TRUNCATE)
|
||||||
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted or truncated */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire(
|
fil_space_acquire(ulint id, bool for_io = false)
|
||||||
ulint id)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Acquire a tablespace that may not exist.
|
/** Acquire a tablespace that may not exist.
|
||||||
Used by background threads that do not necessarily hold proper locks
|
Used by background threads that do not necessarily hold proper locks
|
||||||
for concurrency control.
|
for concurrency control.
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@return the tablespace, or NULL if missing or being deleted */
|
@return the tablespace
|
||||||
|
@retval NULL if missing or being deleted */
|
||||||
fil_space_t*
|
fil_space_t*
|
||||||
fil_space_acquire_silent(
|
fil_space_acquire_silent(ulint id)
|
||||||
ulint id)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Release a tablespace acquired with fil_space_acquire().
|
/** Release a tablespace acquired with fil_space_acquire().
|
||||||
@param[in,out] space tablespace to release */
|
@param[in,out] space tablespace to release */
|
||||||
void
|
void
|
||||||
fil_space_release(
|
fil_space_release(fil_space_t* space);
|
||||||
fil_space_t* space);
|
|
||||||
|
|
||||||
/** Return the next fil_space_t.
|
/** Return the next fil_space_t.
|
||||||
Once started, the caller must keep calling this until it returns NULL.
|
Once started, the caller must keep calling this until it returns NULL.
|
||||||
|
Reference in New Issue
Block a user