mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Change optimizer_switch from no_xxx to xxx=on/xx=off.
This commit is contained in:
@ -1392,11 +1392,46 @@ WHERE
|
|||||||
`TESTID`='' AND `UCCHECK`='';
|
`TESTID`='' AND `UCCHECK`='';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
# @@optimizer_switch support and check
|
# Generic @@optimizer_switch tests (move those into a separate file if
|
||||||
|
# we get another @@optimizer_switch user)
|
||||||
#
|
#
|
||||||
select @@optimizer_switch;
|
select @@optimizer_switch;
|
||||||
@@optimizer_switch
|
@@optimizer_switch
|
||||||
|
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||||
|
set optimizer_switch='index_merge=off,index_merge_union=off';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
@@optimizer_switch
|
||||||
|
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
|
||||||
|
set optimizer_switch='index_merge_union=on';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
@@optimizer_switch
|
||||||
|
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||||
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
@@optimizer_switch
|
||||||
|
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on
|
||||||
|
set optimizer_switch=4;
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
|
||||||
|
set optimizer_switch=NULL;
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL'
|
||||||
|
set optimizer_switch='default,index_merge';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
|
||||||
|
set optimizer_switch='index_merge=index_merge';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge=index_merge'
|
||||||
|
set optimizer_switch='index_merge=on,but...';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'but...'
|
||||||
|
set optimizer_switch='index_merge=';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge='
|
||||||
|
set optimizer_switch='index_merge';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
|
||||||
|
set optimizer_switch='on';
|
||||||
|
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'on'
|
||||||
|
#
|
||||||
|
# Check index_merge's @@optimizer_switch flags
|
||||||
|
#
|
||||||
|
select @@optimizer_switch;
|
||||||
|
@@optimizer_switch
|
||||||
|
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on
|
||||||
create table t0 (a int);
|
create table t0 (a int);
|
||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
create table t1 (a int, b int, c int, filler char(100),
|
create table t1 (a int, b int, c int, filler char(100),
|
||||||
@ -1412,44 +1447,44 @@ explain select * from t1 where a=1 or b=1;
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using union(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using union(a,b); Using where
|
||||||
This should use ALL:
|
This should use ALL:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a=1 or b=1;
|
explain select * from t1 where a=1 or b=1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
||||||
This should use sort-union:
|
This should use sort-union:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=1 or b=1;
|
explain select * from t1 where a=1 or b=1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using sort_union(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using sort_union(a,b); Using where
|
||||||
This will use sort-union:
|
This will use sort-union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where
|
||||||
This should use ALL:
|
This should use ALL:
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
||||||
This should use ALL:
|
This should use ALL:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
1 SIMPLE t1 ALL a,b NULL NULL NULL 1000 Using where
|
||||||
This will use sort-union:
|
This will use sort-union:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 38 Using sort_union(a,b); Using where
|
||||||
alter table t1 add d int, add key(d);
|
alter table t1 add d int, add key(d);
|
||||||
update t1 set d=a;
|
update t1 set d=a;
|
||||||
This will use sort_union:
|
This will use sort_union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b,c,d a,b 5,5 NULL 3 Using sort_union(a,b); Using where
|
1 SIMPLE t1 index_merge a,b,c,d a,b 5,5 NULL 3 Using sort_union(a,b); Using where
|
||||||
And if we disable sort_union, union:
|
And if we disable sort_union, union:
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b,c,d c,d 5,5 NULL 100 Using union(c,d); Using where
|
1 SIMPLE t1 index_merge a,b,c,d c,d 5,5 NULL 100 Using union(c,d); Using where
|
||||||
@ -1463,48 +1498,48 @@ insert into t1
|
|||||||
select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a, 'foo', 'bar'
|
select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a, 'foo', 'bar'
|
||||||
from t0 A, t0 B, t0 C, t0 D where D.a<5;
|
from t0 A, t0 B, t0 C, t0 D where D.a<5;
|
||||||
This should be intersect:
|
This should be intersect:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
||||||
No intersect when index_merge is disabled:
|
No intersect when index_merge is disabled:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
||||||
No intersect if it is disabled:
|
No intersect if it is disabled:
|
||||||
set optimizer_switch='no_index_merge_intersection';
|
set optimizer_switch='default,index_merge_intersection=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
||||||
Do intersect when union was disabled
|
Do intersect when union was disabled
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
||||||
Do intersect when sort_union was disabled
|
Do intersect when sort_union was disabled
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
|
||||||
This will use intersection inside a union:
|
This will use intersection inside a union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b,c a,b,c 5,5,5 NULL 6 Using union(intersect(a,b),c); Using where
|
1 SIMPLE t1 index_merge a,b,c a,b,c 5,5,5 NULL 6 Using union(intersect(a,b),c); Using where
|
||||||
Should be only union left:
|
Should be only union left:
|
||||||
set optimizer_switch='no_index_merge_intersection';
|
set optimizer_switch='default,index_merge_intersection=off';
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using union(a,c); Using where
|
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using union(a,c); Using where
|
||||||
This will switch to sort-union (intersection will be gone, too,
|
This will switch to sort-union (intersection will be gone, too,
|
||||||
thats a known limitation:
|
thats a known limitation:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
|
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
|
||||||
set optimizer_switch=default;
|
set optimizer_switch=default;
|
||||||
show variables like 'optimizer_switch';
|
show variables like 'optimizer_switch';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
optimizer_switch
|
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
@ -21,7 +21,47 @@ let $merge_table_support= 1;
|
|||||||
--source include/index_merge_ror_cpk.inc
|
--source include/index_merge_ror_cpk.inc
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # @@optimizer_switch support and check
|
--echo # Generic @@optimizer_switch tests (move those into a separate file if
|
||||||
|
--echo # we get another @@optimizer_switch user)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
select @@optimizer_switch;
|
||||||
|
|
||||||
|
set optimizer_switch='index_merge=off,index_merge_union=off';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
|
||||||
|
set optimizer_switch='index_merge_union=on';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
|
||||||
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
|
select @@optimizer_switch;
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch=4;
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch=NULL;
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='default,index_merge';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='index_merge=index_merge';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='index_merge=on,but...';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='index_merge=';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='index_merge';
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
set optimizer_switch='on';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Check index_merge's @@optimizer_switch flags
|
||||||
--echo #
|
--echo #
|
||||||
select @@optimizer_switch;
|
select @@optimizer_switch;
|
||||||
|
|
||||||
@ -40,39 +80,39 @@ from t0 A, t0 B, t0 C;
|
|||||||
explain select * from t1 where a=1 or b=1;
|
explain select * from t1 where a=1 or b=1;
|
||||||
|
|
||||||
--echo This should use ALL:
|
--echo This should use ALL:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a=1 or b=1;
|
explain select * from t1 where a=1 or b=1;
|
||||||
|
|
||||||
--echo This should use sort-union:
|
--echo This should use sort-union:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=1 or b=1;
|
explain select * from t1 where a=1 or b=1;
|
||||||
|
|
||||||
--echo This will use sort-union:
|
--echo This will use sort-union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
|
|
||||||
--echo This should use ALL:
|
--echo This should use ALL:
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
|
|
||||||
|
|
||||||
--echo This should use ALL:
|
--echo This should use ALL:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
|
|
||||||
--echo This will use sort-union:
|
--echo This will use sort-union:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a<1 or b <1;
|
explain select * from t1 where a<1 or b <1;
|
||||||
|
|
||||||
alter table t1 add d int, add key(d);
|
alter table t1 add d int, add key(d);
|
||||||
update t1 set d=a;
|
update t1 set d=a;
|
||||||
|
|
||||||
--echo This will use sort_union:
|
--echo This will use sort_union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
||||||
|
|
||||||
--echo And if we disable sort_union, union:
|
--echo And if we disable sort_union, union:
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
explain select * from t1 where (a=3 or b in (1,2)) and (c=3 or d=4);
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -89,40 +129,41 @@ select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a, 'foo', 'bar'
|
|||||||
from t0 A, t0 B, t0 C, t0 D where D.a<5;
|
from t0 A, t0 B, t0 C, t0 D where D.a<5;
|
||||||
|
|
||||||
--echo This should be intersect:
|
--echo This should be intersect:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
|
|
||||||
--echo No intersect when index_merge is disabled:
|
--echo No intersect when index_merge is disabled:
|
||||||
set optimizer_switch='no_index_merge';
|
set optimizer_switch='default,index_merge=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
|
|
||||||
--echo No intersect if it is disabled:
|
--echo No intersect if it is disabled:
|
||||||
set optimizer_switch='no_index_merge_intersection';
|
set optimizer_switch='default,index_merge_intersection=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
|
|
||||||
--echo Do intersect when union was disabled
|
--echo Do intersect when union was disabled
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
|
|
||||||
--echo Do intersect when sort_union was disabled
|
--echo Do intersect when sort_union was disabled
|
||||||
set optimizer_switch='no_index_merge_sort_union';
|
set optimizer_switch='default,index_merge_sort_union=off';
|
||||||
explain select * from t1 where a=10 and b=10;
|
explain select * from t1 where a=10 and b=10;
|
||||||
|
|
||||||
# Now take union-of-intersection and see how we can disable parts of it
|
# Now take union-of-intersection and see how we can disable parts of it
|
||||||
--echo This will use intersection inside a union:
|
--echo This will use intersection inside a union:
|
||||||
set optimizer_switch='';
|
set optimizer_switch=default;
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
|
|
||||||
--echo Should be only union left:
|
--echo Should be only union left:
|
||||||
set optimizer_switch='no_index_merge_intersection';
|
set optimizer_switch='default,index_merge_intersection=off';
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
|
|
||||||
--echo This will switch to sort-union (intersection will be gone, too,
|
--echo This will switch to sort-union (intersection will be gone, too,
|
||||||
--echo thats a known limitation:
|
--echo thats a known limitation:
|
||||||
set optimizer_switch='no_index_merge_union';
|
set optimizer_switch='default,index_merge_union=off';
|
||||||
explain select * from t1 where a=10 and b=10 or c=10;
|
explain select * from t1 where a=10 and b=10 or c=10;
|
||||||
|
|
||||||
set optimizer_switch=default;
|
set optimizer_switch=default;
|
||||||
show variables like 'optimizer_switch';
|
show variables like 'optimizer_switch';
|
||||||
|
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
|
||||||
|
@ -523,11 +523,18 @@ protected:
|
|||||||
#define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2)
|
#define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2)
|
||||||
#define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31)
|
#define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31)
|
||||||
|
|
||||||
/* @@optimizer_switch flags */
|
/* @@optimizer_switch flags. These must be in sync with optimizer_switch_typelib */
|
||||||
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE 1
|
#define OPTIMIZER_SWITCH_INDEX_MERGE 1
|
||||||
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION 2
|
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
|
||||||
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_SORT_UNION 4
|
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
|
||||||
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT 8
|
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
|
||||||
|
#define OPTIMIZER_SWITCH_LAST 16
|
||||||
|
|
||||||
|
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
||||||
|
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
||||||
|
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
|
||||||
|
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
|
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
|
||||||
@ -1831,6 +1838,10 @@ extern enum_field_types agg_field_type(Item **items, uint nitems);
|
|||||||
/* strfunc.cc */
|
/* strfunc.cc */
|
||||||
ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
|
ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
|
||||||
char **err_pos, uint *err_len, bool *set_warning);
|
char **err_pos, uint *err_len, bool *set_warning);
|
||||||
|
ulonglong find_set_from_flags(TYPELIB *lib, uint default_set,
|
||||||
|
ulonglong cur_set, ulonglong default_set,
|
||||||
|
const char *str, uint length, CHARSET_INFO *cs,
|
||||||
|
char **err_pos, uint *err_len, bool *set_warning);
|
||||||
uint find_type(const TYPELIB *lib, const char *find, uint length,
|
uint find_type(const TYPELIB *lib, const char *find, uint length,
|
||||||
bool part_match);
|
bool part_match);
|
||||||
uint find_type2(const TYPELIB *lib, const char *find, uint length,
|
uint find_type2(const TYPELIB *lib, const char *find, uint length,
|
||||||
|
@ -302,16 +302,17 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
|
|||||||
|
|
||||||
static const char *optimizer_switch_names[]=
|
static const char *optimizer_switch_names[]=
|
||||||
{
|
{
|
||||||
"no_index_merge","no_index_merge_union","no_index_merge_sort_union",
|
"index_merge","index_merge_union","index_merge_sort_union",
|
||||||
"no_index_merge_intersection", NullS
|
"index_merge_intersection", "default", NullS
|
||||||
};
|
};
|
||||||
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
|
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
|
||||||
static const unsigned int optimizer_switch_names_len[]=
|
static const unsigned int optimizer_switch_names_len[]=
|
||||||
{
|
{
|
||||||
sizeof("no_index_merge") - 1,
|
sizeof("index_merge") - 1,
|
||||||
sizeof("no_index_merge_union") - 1,
|
sizeof("index_merge_union") - 1,
|
||||||
sizeof("ni_index_merge_sort_union") - 1,
|
sizeof("index_merge_sort_union") - 1,
|
||||||
sizeof("no_index_merge_intersection") - 1
|
sizeof("index_merge_intersection") - 1,
|
||||||
|
sizeof("default") - 1
|
||||||
};
|
};
|
||||||
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
|
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
|
||||||
optimizer_switch_names,
|
optimizer_switch_names,
|
||||||
@ -7656,7 +7657,8 @@ static int mysql_init_variables(void)
|
|||||||
when collecting index statistics for MyISAM tables.
|
when collecting index statistics for MyISAM tables.
|
||||||
*/
|
*/
|
||||||
global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||||
|
|
||||||
|
global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
|
||||||
/* Variables that depends on compile options */
|
/* Variables that depends on compile options */
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
|
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
|
||||||
@ -8252,12 +8254,22 @@ mysqld_get_one_option(int optid,
|
|||||||
}
|
}
|
||||||
case OPT_OPTIMIZER_SWITCH:
|
case OPT_OPTIMIZER_SWITCH:
|
||||||
{
|
{
|
||||||
|
bool not_used;
|
||||||
|
char *error= 0;
|
||||||
|
uint error_len= 0;
|
||||||
optimizer_switch_str= argument;
|
optimizer_switch_str= argument;
|
||||||
global_system_variables.optimizer_switch=
|
global_system_variables.optimizer_switch=
|
||||||
find_bit_type_or_exit(argument, &optimizer_switch_typelib, opt->name,
|
(ulong)find_set_from_flags(&optimizer_switch_typelib,
|
||||||
&error);
|
optimizer_switch_typelib.count,
|
||||||
if (error)
|
global_system_variables.optimizer_switch,
|
||||||
return 1;
|
global_system_variables.optimizer_switch,
|
||||||
|
argument, strlen(argument), NULL,
|
||||||
|
&error, &error_len, ¬_used);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid optimizer_switch flag: %s\n", error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_ONE_THREAD:
|
case OPT_ONE_THREAD:
|
||||||
|
@ -2387,7 +2387,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||||||
table deletes.
|
table deletes.
|
||||||
*/
|
*/
|
||||||
if ((thd->lex->sql_command != SQLCOM_DELETE) &&
|
if ((thd->lex->sql_command != SQLCOM_DELETE) &&
|
||||||
!optimizer_flag(thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE))
|
optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Get best non-covering ROR-intersection plan and prepare data for
|
Get best non-covering ROR-intersection plan and prepare data for
|
||||||
@ -2411,7 +2411,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE))
|
if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
|
||||||
{
|
{
|
||||||
/* Try creating index_merge/ROR-union scan. */
|
/* Try creating index_merge/ROR-union scan. */
|
||||||
SEL_IMERGE *imerge;
|
SEL_IMERGE *imerge;
|
||||||
@ -3778,7 +3778,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
|||||||
disabled in @@optimizer_switch
|
disabled in @@optimizer_switch
|
||||||
*/
|
*/
|
||||||
if (all_scans_rors &&
|
if (all_scans_rors &&
|
||||||
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION))
|
optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
|
||||||
{
|
{
|
||||||
roru_read_plans= (TABLE_READ_PLAN**)range_scans;
|
roru_read_plans= (TABLE_READ_PLAN**)range_scans;
|
||||||
goto skip_to_ror_scan;
|
goto skip_to_ror_scan;
|
||||||
@ -3798,7 +3798,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
|||||||
DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
|
DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
|
||||||
imerge_cost));
|
imerge_cost));
|
||||||
if (imerge_cost > read_time ||
|
if (imerge_cost > read_time ||
|
||||||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_SORT_UNION))
|
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
|
||||||
{
|
{
|
||||||
goto build_ror_index_merge;
|
goto build_ror_index_merge;
|
||||||
}
|
}
|
||||||
@ -3839,7 +3839,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
|||||||
build_ror_index_merge:
|
build_ror_index_merge:
|
||||||
if (!all_scans_ror_able ||
|
if (!all_scans_ror_able ||
|
||||||
param->thd->lex->sql_command == SQLCOM_DELETE ||
|
param->thd->lex->sql_command == SQLCOM_DELETE ||
|
||||||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION))
|
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
|
||||||
DBUG_RETURN(imerge_trp);
|
DBUG_RETURN(imerge_trp);
|
||||||
|
|
||||||
/* Ok, it is possible to build a ROR-union, try it. */
|
/* Ok, it is possible to build a ROR-union, try it. */
|
||||||
@ -4513,7 +4513,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
|
|||||||
DBUG_ENTER("get_best_ror_intersect");
|
DBUG_ENTER("get_best_ror_intersect");
|
||||||
|
|
||||||
if ((tree->n_ror_scans < 2) || !param->table->file->stats.records ||
|
if ((tree->n_ror_scans < 2) || !param->table->file->stats.records ||
|
||||||
optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT))
|
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4703,7 +4703,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||||||
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
|
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
|
||||||
DBUG_ENTER("get_best_covering_ror_intersect");
|
DBUG_ENTER("get_best_covering_ror_intersect");
|
||||||
|
|
||||||
if (optimizer_flag(param->thd, OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT))
|
if (!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
|
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
|
||||||
|
@ -3926,17 +3926,17 @@ symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
|
|||||||
{
|
{
|
||||||
char buff[STRING_BUFFER_USUAL_SIZE*8];
|
char buff[STRING_BUFFER_USUAL_SIZE*8];
|
||||||
String tmp(buff, sizeof(buff), &my_charset_latin1);
|
String tmp(buff, sizeof(buff), &my_charset_latin1);
|
||||||
|
int i;
|
||||||
|
ulonglong bit;
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
|
|
||||||
for (uint i= 0; val; val>>= 1, i++)
|
for (i= 0, bit=1; bit != OPTIMIZER_SWITCH_LAST; i++, bit= bit << 1)
|
||||||
{
|
{
|
||||||
if (val & 1)
|
tmp.append(optimizer_switch_typelib.type_names[i],
|
||||||
{
|
optimizer_switch_typelib.type_lengths[i]);
|
||||||
tmp.append(optimizer_switch_typelib.type_names[i],
|
tmp.append('=');
|
||||||
optimizer_switch_typelib.type_lengths[i]);
|
tmp.append((val & bit)? "on":"off");
|
||||||
tmp.append(',');
|
tmp.append(',');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp.length())
|
if (tmp.length())
|
||||||
@ -3961,12 +3961,45 @@ uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
|
/*
|
||||||
|
Check (and actually parse) string representation of @@optimizer_switch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
if (type == OPT_GLOBAL)
|
bool not_used;
|
||||||
global_system_variables.*offset= 0;
|
char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
|
||||||
else
|
uint error_len= 0;
|
||||||
thd->variables.*offset= global_system_variables.*offset;
|
String str(buff, sizeof(buff), system_charset_info), *res;
|
||||||
|
|
||||||
|
if (!(res= var->value->val_str(&str)))
|
||||||
|
{
|
||||||
|
strmov(buff, "NULL");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res->length() == 0)
|
||||||
|
{
|
||||||
|
buff[0]= 0;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
var->save_result.ulong_value=
|
||||||
|
(ulong)find_set_from_flags(&optimizer_switch_typelib,
|
||||||
|
optimizer_switch_typelib.count,
|
||||||
|
thd->variables.optimizer_switch,
|
||||||
|
global_system_variables.optimizer_switch,
|
||||||
|
res->c_ptr(), res->length(), NULL,
|
||||||
|
&error, &error_len, ¬_used);
|
||||||
|
if (error_len)
|
||||||
|
{
|
||||||
|
strmake(buff, error, min(sizeof(buff) - 1, error_len));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
err:
|
||||||
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -539,11 +539,7 @@ public:
|
|||||||
ulong SV::*offset_arg)
|
ulong SV::*offset_arg)
|
||||||
:sys_var_thd_enum(chain, name_arg, offset_arg, &optimizer_switch_typelib)
|
:sys_var_thd_enum(chain, name_arg, offset_arg, &optimizer_switch_typelib)
|
||||||
{}
|
{}
|
||||||
bool check(THD *thd, set_var *var)
|
bool check(THD *thd, set_var *var);
|
||||||
{
|
|
||||||
return check_set(thd, var, enum_names);
|
|
||||||
}
|
|
||||||
void set_default(THD *thd, enum_var_type type);
|
|
||||||
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||||
static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
|
static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
|
||||||
LEX_STRING *rep);
|
LEX_STRING *rep);
|
||||||
|
182
sql/strfunc.cc
182
sql/strfunc.cc
@ -88,6 +88,188 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *on_off_default_names[]=
|
||||||
|
{
|
||||||
|
"off","on","default", NullS
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int on_off_default_names_len[]=
|
||||||
|
{
|
||||||
|
sizeof("off") - 1,
|
||||||
|
sizeof("on") - 1,
|
||||||
|
sizeof("default") - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
|
||||||
|
"", on_off_default_names,
|
||||||
|
(unsigned int *)on_off_default_names_len};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Given a string, find the first field_separator char, minding the charset
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint parse_name(TYPELIB *lib, const char **strpos, const char *end,
|
||||||
|
CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
const char *pos= *strpos;
|
||||||
|
const char *start= pos;
|
||||||
|
|
||||||
|
/* Find the length */
|
||||||
|
if (cs && cs->mbminlen > 1)
|
||||||
|
{
|
||||||
|
int mblen= 0;
|
||||||
|
for ( ; pos < end; pos+= mblen)
|
||||||
|
{
|
||||||
|
my_wc_t wc;
|
||||||
|
if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) pos,
|
||||||
|
(const uchar *) end)) < 1)
|
||||||
|
mblen= 1; // Not to hang on a wrong multibyte sequence
|
||||||
|
if (wc == (my_wc_t) '=' || wc == (my_wc_t) ',')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
|
||||||
|
|
||||||
|
uint var_len= (uint) (pos - start);
|
||||||
|
/* Determine which flag it is*/
|
||||||
|
uint find= cs ? find_type2(lib, start, var_len, cs) :
|
||||||
|
find_type(lib, start, var_len, (bool) 0);
|
||||||
|
*strpos= pos;
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read next character from the buffer in a charset-aware way */
|
||||||
|
|
||||||
|
static my_wc_t get_next_char(const char **pos, const char *end, CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
my_wc_t wc;
|
||||||
|
if (*pos == end)
|
||||||
|
return (my_wc_t)-1;
|
||||||
|
|
||||||
|
if (cs && cs->mbminlen > 1)
|
||||||
|
{
|
||||||
|
int mblen;
|
||||||
|
if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) *pos,
|
||||||
|
(const uchar *) end)) < 1)
|
||||||
|
mblen= 1; // Not to hang on a wrong multibyte sequence
|
||||||
|
*pos += mblen;
|
||||||
|
return wc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return *((*pos)++);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse a string representation of set of flags
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_set_from_flags()
|
||||||
|
lib Flag names
|
||||||
|
default_name Number of "default" in the typelib
|
||||||
|
cur_set Current set of flags (start from this state)
|
||||||
|
default_set Default set of flags (use this for assign-default
|
||||||
|
keyword and flag=default assignments)
|
||||||
|
str String representation (see below)
|
||||||
|
length Length of the above
|
||||||
|
cs Charset used for the string
|
||||||
|
err_pos OUT If error, set to point to start of wrong set string
|
||||||
|
err_len OUT If error, set to the length of wrong set string
|
||||||
|
set_warning OUT TRUE <=> Some string in set couldn't be used
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Parse a set of flag assignments, that is, parse a string in form:
|
||||||
|
|
||||||
|
param_name1=value1,param_name2=value2,...
|
||||||
|
|
||||||
|
where the names are specified in the TYPELIB, and each value can be
|
||||||
|
either 'on','off', or 'default'. Besides param=val assignments, we
|
||||||
|
support "default" keyword (keyword #default_name in the typelib) which
|
||||||
|
means assign everything the default.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE Ok
|
||||||
|
TRUE Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
|
||||||
|
ulonglong cur_set, ulonglong default_set,
|
||||||
|
const char *str, uint length, CHARSET_INFO *cs,
|
||||||
|
char **err_pos, uint *err_len, bool *set_warning)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
|
||||||
|
const char *end= str + strip->cset->lengthsp(strip, str, length);
|
||||||
|
ulonglong flags= cur_set;
|
||||||
|
*err_pos= 0; // No error yet
|
||||||
|
if (str != end)
|
||||||
|
{
|
||||||
|
const char *start= str;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
my_wc_t chr;
|
||||||
|
const char *pos= start;
|
||||||
|
uint flag, value;
|
||||||
|
|
||||||
|
if (!(flag= parse_name(lib, &pos, end, cs)))
|
||||||
|
{
|
||||||
|
*err_pos= (char*) start;
|
||||||
|
*err_len= pos - start;
|
||||||
|
*set_warning= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == default_name)
|
||||||
|
{
|
||||||
|
flags= default_set;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((chr= get_next_char(&pos, end, cs)) != '=')
|
||||||
|
{
|
||||||
|
*err_pos= (char*)start;
|
||||||
|
*err_len= pos - start;
|
||||||
|
*set_warning= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(value= parse_name(&on_off_default_typelib, &pos, end, cs)))
|
||||||
|
{
|
||||||
|
*err_pos= (char*) start;
|
||||||
|
*err_len= pos - start;
|
||||||
|
*set_warning= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulonglong bit= ((longlong) 1 << (flag - 1));
|
||||||
|
if (value == 1) // this is 'xxx=off'
|
||||||
|
flags &= ~bit;
|
||||||
|
else if (value == 2) // this is 'xxx=on'
|
||||||
|
flags |= bit;
|
||||||
|
else // this is 'xxx=default'
|
||||||
|
{
|
||||||
|
bit= default_set & bit;
|
||||||
|
flags= (flags & ~bit) | bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos >= end)
|
||||||
|
break;
|
||||||
|
if ((chr= get_next_char(&pos, end, cs)) != ',')
|
||||||
|
{
|
||||||
|
*err_pos= (char*)start;
|
||||||
|
*err_len= pos - start;
|
||||||
|
*set_warning= 1;
|
||||||
|
}
|
||||||
|
start=pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function to find a string in a TYPELIB
|
Function to find a string in a TYPELIB
|
||||||
(Same format as mysys/typelib.c)
|
(Same format as mysys/typelib.c)
|
||||||
|
Reference in New Issue
Block a user