Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
7877de39
Commit
7877de39
authored
Mar 11, 2009
by
Sergey Petrunia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change optimizer_switch from no_xxx to xxx=on/xx=off.
parent
4961e008
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
388 additions
and
78 deletions
+388
-78
mysql-test/r/index_merge_myisam.result
mysql-test/r/index_merge_myisam.result
+54
-19
mysql-test/t/index_merge_myisam.test
mysql-test/t/index_merge_myisam.test
+58
-17
sql/mysql_priv.h
sql/mysql_priv.h
+16
-5
sql/mysqld.cc
sql/mysqld.cc
+23
-11
sql/opt_range.cc
sql/opt_range.cc
+7
-7
sql/set_var.cc
sql/set_var.cc
+47
-14
sql/set_var.h
sql/set_var.h
+1
-5
sql/strfunc.cc
sql/strfunc.cc
+182
-0
No files found.
mysql-test/r/index_merge_myisam.result
View file @
7877de39
...
...
@@ -1392,11 +1392,46 @@ WHERE
`TESTID`='' AND `UCCHECK`='';
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;
@@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);
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),
...
...
@@ -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
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 2 Using union(a,b); Using where
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;
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
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;
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
This will use sort-union:
set optimizer_switch=
''
;
set optimizer_switch=
default
;
explain select * from t1 where a<1 or b <1;
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
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;
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
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;
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
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;
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
alter table t1 add d int, add key(d);
update t1 set d=a;
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);
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
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);
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
...
...
@@ -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'
from t0 A, t0 B, t0 C, t0 D where D.a<5;
This should be intersect:
set optimizer_switch=
''
;
set optimizer_switch=
default
;
explain select * from t1 where a=10 and b=10;
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
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;
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
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;
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
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;
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
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;
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
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;
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
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;
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
This will switch to sort-union (intersection will be gone, too,
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;
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
set optimizer_switch=default;
show variables like 'optimizer_switch';
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;
mysql-test/t/index_merge_myisam.test
View file @
7877de39
...
...
@@ -21,7 +21,47 @@ let $merge_table_support= 1;
--
source
include
/
index_merge_ror_cpk
.
inc
--
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
#
select
@@
optimizer_switch
;
...
...
@@ -40,39 +80,39 @@ from t0 A, t0 B, t0 C;
explain select * from t1 where a=1 or b=1
;
--
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
;
--
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
;
--
echo
This
will
use
sort
-union:
set optimizer_switch=
''
;
set optimizer_switch=
default
;
explain
select
*
from
t1
where
a
<
1
or
b
<
1
;
--
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
;
--
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
;
--
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
;
alter
table
t1
add
d
int
,
add
key
(
d
);
update
t1
set
d
=
a
;
--
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
);
--
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
);
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
;
--
echo
This
should
be
intersect
:
set
optimizer_switch
=
''
;
set
optimizer_switch
=
default
;
explain
select
*
from
t1
where
a
=
10
and
b
=
10
;
--
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
;
--
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
;
--
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
;
--
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
;
# Now take union-of-intersection and see how we can disable parts of it
--
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
;
--
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
;
--
echo
This
will
switch
to
sort
-
union
(
intersection
will
be
gone
,
too
,
--
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
;
set
optimizer_switch
=
default
;
show
variables
like
'optimizer_switch'
;
drop
table
t0
,
t1
;
sql/mysql_priv.h
View file @
7877de39
...
...
@@ -523,11 +523,18 @@ class Default_object_creation_ctx : public Object_creation_ctx
#define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2)
#define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31)
/* @@optimizer_switch flags */
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE 1
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_SORT_UNION 4
#define OPTIMIZER_SWITCH_NO_INDEX_MERGE_INTERSECT 8
/* @@optimizer_switch flags. These must be in sync with optimizer_switch_typelib */
#define OPTIMIZER_SWITCH_INDEX_MERGE 1
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
#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
...
...
@@ -1831,6 +1838,10 @@ extern enum_field_types agg_field_type(Item **items, uint nitems);
/* strfunc.cc */
ulonglong
find_set
(
TYPELIB
*
lib
,
const
char
*
x
,
uint
length
,
CHARSET_INFO
*
cs
,
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
,
bool
part_match
);
uint
find_type2
(
const
TYPELIB
*
lib
,
const
char
*
find
,
uint
length
,
...
...
sql/mysqld.cc
View file @
7877de39
...
...
@@ -302,16 +302,17 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
static
const
char
*
optimizer_switch_names
[]
=
{
"
no_index_merge"
,
"no_index_merge_union"
,
"no_
index_merge_sort_union"
,
"
no_index_merge_intersection
"
,
NullS
"
index_merge"
,
"index_merge_union"
,
"
index_merge_sort_union"
,
"
index_merge_intersection"
,
"default
"
,
NullS
};
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
static
const
unsigned
int
optimizer_switch_names_len
[]
=
{
sizeof
(
"no_index_merge"
)
-
1
,
sizeof
(
"no_index_merge_union"
)
-
1
,
sizeof
(
"ni_index_merge_sort_union"
)
-
1
,
sizeof
(
"no_index_merge_intersection"
)
-
1
sizeof
(
"index_merge"
)
-
1
,
sizeof
(
"index_merge_union"
)
-
1
,
sizeof
(
"index_merge_sort_union"
)
-
1
,
sizeof
(
"index_merge_intersection"
)
-
1
,
sizeof
(
"default"
)
-
1
};
TYPELIB
optimizer_switch_typelib
=
{
array_elements
(
optimizer_switch_names
)
-
1
,
""
,
optimizer_switch_names
,
...
...
@@ -7656,7 +7657,8 @@ static int mysql_init_variables(void)
when collecting index statistics for MyISAM tables.
*/
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 */
#ifndef DBUG_OFF
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
:
{
bool
not_used
;
char
*
error
=
0
;
uint
error_len
=
0
;
optimizer_switch_str
=
argument
;
global_system_variables
.
optimizer_switch
=
find_bit_type_or_exit
(
argument
,
&
optimizer_switch_typelib
,
opt
->
name
,
&
error
);
if
(
error
)
return
1
;
(
ulong
)
find_set_from_flags
(
&
optimizer_switch_typelib
,
optimizer_switch_typelib
.
count
,
global_system_variables
.
optimizer_switch
,
global_system_variables
.
optimizer_switch
,
argument
,
strlen
(
argument
),
NULL
,
&
error
,
&
error_len
,
&
not_used
);
if
(
error
)
{
fprintf
(
stderr
,
"Invalid optimizer_switch flag: %s
\n
"
,
error
);
return
1
;
}
break
;
}
case
OPT_ONE_THREAD
:
...
...
sql/opt_range.cc
View file @
7877de39
...
...
@@ -2387,7 +2387,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table deletes.
*/
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
...
...
@@ -2411,7 +2411,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
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. */
SEL_IMERGE
*
imerge
;
...
...
@@ -3778,7 +3778,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
disabled in @@optimizer_switch
*/
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
;
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"
,
imerge_cost
));
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
;
}
...
...
@@ -3839,7 +3839,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
build_ror_index_merge:
if
(
!
all_scans_ror_able
||
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
);
/* 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"
);
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
);
/*
...
...
@@ -4703,7 +4703,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
ROR_SCAN_INFO
**
ror_scans_end
=
tree
->
ror_scans_end
;
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
);
for
(
ROR_SCAN_INFO
**
scan
=
tree
->
ror_scans
;
scan
!=
ror_scans_end
;
++
scan
)
...
...
sql/set_var.cc
View file @
7877de39
...
...
@@ -3926,17 +3926,17 @@ symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
{
char
buff
[
STRING_BUFFER_USUAL_SIZE
*
8
];
String
tmp
(
buff
,
sizeof
(
buff
),
&
my_charset_latin1
);
int
i
;
ulonglong
bit
;
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
(
','
);
}
tmp
.
append
(
optimizer_switch_typelib
.
type_names
[
i
],
optimizer_switch_typelib
.
type_lengths
[
i
]);
tmp
.
append
(
'='
);
tmp
.
append
((
val
&
bit
)
?
"on"
:
"off"
);
tmp
.
append
(
','
);
}
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
)
global_system_variables
.
*
offset
=
0
;
else
thd
->
variables
.
*
offset
=
global_system_variables
.
*
offset
;
bool
not_used
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
],
*
error
=
0
;
uint
error_len
=
0
;
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
,
&
not_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
;
}
...
...
sql/set_var.h
View file @
7877de39
...
...
@@ -539,11 +539,7 @@ class sys_var_thd_optimizer_switch :public sys_var_thd_enum
ulong
SV
::*
offset_arg
)
:
sys_var_thd_enum
(
chain
,
name_arg
,
offset_arg
,
&
optimizer_switch_typelib
)
{}
bool
check
(
THD
*
thd
,
set_var
*
var
)
{
return
check_set
(
thd
,
var
,
enum_names
);
}
void
set_default
(
THD
*
thd
,
enum_var_type
type
);
bool
check
(
THD
*
thd
,
set_var
*
var
);
uchar
*
value_ptr
(
THD
*
thd
,
enum_var_type
type
,
LEX_STRING
*
base
);
static
bool
symbolic_mode_representation
(
THD
*
thd
,
ulonglong
sql_mode
,
LEX_STRING
*
rep
);
...
...
sql/strfunc.cc
View file @
7877de39
...
...
@@ -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
(Same format as mysys/typelib.c)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment