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
ce18ab4b
Commit
ce18ab4b
authored
Sep 11, 2024
by
Oleg Smirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-34888 Implement SEMIJOIN() and SUBQUERY() hints
parent
c8ce9fbb
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1171 additions
and
56 deletions
+1171
-56
mysql-test/main/opt_hints_subquery.result
mysql-test/main/opt_hints_subquery.result
+298
-0
mysql-test/main/opt_hints_subquery.test
mysql-test/main/opt_hints_subquery.test
+99
-0
sql/opt_hints.cc
sql/opt_hints.cc
+354
-16
sql/opt_hints.h
sql/opt_hints.h
+30
-2
sql/opt_hints_parser.cc
sql/opt_hints_parser.cc
+44
-0
sql/opt_hints_parser.h
sql/opt_hints_parser.h
+224
-9
sql/simple_parser.h
sql/simple_parser.h
+86
-0
sql/sql_priv.h
sql/sql_priv.h
+35
-28
sql/sys_vars.cc
sql/sys_vars.cc
+1
-1
No files found.
mysql-test/main/opt_hints_subquery.result
0 → 100644
View file @
ce18ab4b
This diff is collapsed.
Click to expand it.
mysql-test/main/opt_hints_subquery.test
0 → 100644
View file @
ce18ab4b
CREATE
TABLE
t1
(
a
INTEGER
NOT
NULL
,
b
INT
,
PRIMARY
KEY
(
a
));
CREATE
TABLE
t2
(
a
INTEGER
NOT
NULL
,
KEY
(
a
));
CREATE
TABLE
t3
(
a
INTEGER
NOT
NULL
,
b
INT
,
KEY
(
a
));
INSERT
INTO
t1
VALUES
(
1
,
10
),
(
2
,
20
),
(
3
,
30
),
(
4
,
40
);
INSERT
INTO
t2
VALUES
(
2
),
(
3
),
(
4
),
(
5
);
INSERT
INTO
t3
VALUES
(
10
,
3
),
(
20
,
4
),
(
30
,
5
);
ANALYZE
TABLE
t1
,
t2
,
t3
;
--
echo
# WIP:
--
echo
# Parser tests
--
echo
# Correct hints (no warnings):
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN() */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) SEMIJOIN(@qb1) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) NO_SEMIJOIN(@qb1 firstmatch) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) SEMIJOIN( @qb1 firstmatch, dupsweedout ) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ NO_SEMIJOIN( FIRSTMATCH, LOOSESCAN,materialization, DUPSWEEDOUT ) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb2) NO_SEMIJOIN(@qb2 FIRSTMATCH,LOOSESCAN, materialization, DUPSWEEDOUT) */
a
FROM
t1
;
set
optimizer_switch
=
'derived_merge=off'
;
--
echo
# Correct 'cause hints refer to different query blocks:
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN(@qb1) SEMIJOIN(loosescan)*/
a
FROM
(
SELECT
/*+ QB_NAME(qb1)*/
*
FROM
t2
)
AS
tt
;
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN()*/
a
FROM
(
SELECT
/*+ SEMIJOIN(loosescan)*/
*
FROM
t2
)
AS
tt
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY(materialization) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY( INTOEXISTS ) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME (qb1) SUBQUERY(@qb1 materialization) */
a
FROM
t1
;
--
echo
# Incorrect hints (warnings)
SELECT
/*+ SEMIJOIN(loosescan @qb1) */
a
FROM
t1
;
SELECT
/*+ SEMIJOIN(@qb1 @qb2) */
a
FROM
t1
;
SELECT
/*+ SEMIJOIN(@qb1 LOOSESCAN,materialization, unknown_strategy) */
a
FROM
t1
;
SELECT
/*+ NO_SEMIJOIN(@qb1, @qb2) */
a
FROM
t1
;
SELECT
/*+ NO_SEMIJOIN(FIRSTMATCH, ,LOOSESCAN, materialization) */
a
FROM
t1
;
SELECT
/*+ NO_SEMIJOIN(FIRSTMATCH, @qb2,LOOSESCAN) */
a
FROM
t1
;
SELECT
/*+ SUBQUERY(wrong_strat) */
a
FROM
t1
;
SELECT
/*+ SUBQUERY(materialization, intoexists) */
a
FROM
t1
;
SELECT
/*+ SUBQUERY(@qb1 materialization) */
a
FROM
t1
;
SELECT
/*+ SUBQUERY() */
a
FROM
t1
;
--
echo
# Mix of correct and incorrect hints:
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN(firstmatch ) SEMIJOIN(loosescan @qb1) */
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ NO_SEMIJOIN(@qb1, @qb2) SEMIJOIN()*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ NO_SEMIJOIN() NO_SEMIJOIN(FIRSTMATCH, @qb2,LOOSESCAN) */
a
FROM
t1
;
--
echo
# Conflicting hints:
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN() SEMIJOIN(dupsweedout) NO_SEMIJOIN(firstmatch)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN(loosescan,materialization) SEMIJOIN(dupsweedout)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ NO_SEMIJOIN(firstmatch,loosescan,materialization) SEMIJOIN() NO_SEMIJOIN()*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) SEMIJOIN(@qb1) SEMIJOIN(loosescan) NO_SEMIJOIN(@qb1 dupsweedout)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN(firstmatch) NO_SEMIJOIN()*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY(materialization) SUBQUERY(intoexists)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN() SUBQUERY(materialization) SUBQUERY(intoexists)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY(materialization) SUBQUERY(intoexists)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY(materialization) SUBQUERY(intoexists) SUBQUERY(materialization)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ SUBQUERY(materialization) SEMIJOIN(firstmatch) SUBQUERY(intoexists)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) SEMIJOIN(@qb1) SUBQUERY(@qb1 materialization) SUBQUERY(intoexists)*/
a
FROM
t1
;
EXPLAIN
EXTENDED
SELECT
/*+ QB_NAME(qb1) SUBQUERY(@qb1 materialization) SEMIJOIN(@qb1 firstmatch) SUBQUERY(intoexists)*/
a
FROM
t1
;
set
optimizer_switch
=
'derived_merge=off'
;
EXPLAIN
EXTENDED
SELECT
/*+ SEMIJOIN(@qb1) SEMIJOIN(loosescan) NO_SEMIJOIN(@qb1 dupsweedout)*/
a
FROM
(
SELECT
/*+ QB_NAME(qb1)*/
*
FROM
t2
)
AS
tt
;
DROP
TABLE
t1
,
t2
,
t3
;
sql/opt_hints.cc
View file @
ce18ab4b
This diff is collapsed.
Click to expand it.
sql/opt_hints.h
View file @
ce18ab4b
...
...
@@ -30,6 +30,7 @@
#include "sql_bitmap.h"
#include "sql_show.h"
#include "mysqld_error.h"
#include "opt_hints_parser.h"
struct
LEX
;
...
...
@@ -48,7 +49,9 @@ enum opt_hints_enum
MRR_HINT_ENUM
,
NO_RANGE_HINT_ENUM
,
QB_NAME_HINT_ENUM
,
MAX_HINT_ENUM
SEMIJOIN_HINT_ENUM
,
SUBQUERY_HINT_ENUM
,
MAX_HINT_ENUM
// This one must be the last in the list
};
...
...
@@ -261,6 +264,13 @@ class Opt_hints : public Sql_alloc
void
check_unresolved
(
THD
*
thd
);
virtual
void
append_name
(
THD
*
thd
,
String
*
str
)
=
0
;
/**
Append additional hint arguments to the printed string if they exist.
For example, SEMIJOIN and SUBQUERY hints may have a list of strategies
as additional arguments
*/
virtual
void
append_args
(
THD
*
thd
,
String
*
str
)
const
{}
virtual
~
Opt_hints
()
{}
private:
...
...
@@ -316,7 +326,6 @@ class Opt_hints_qb : public Opt_hints
char
buff
[
32
];
// Buffer to hold sys name
public:
Opt_hints_qb
(
Opt_hints
*
opt_hints_arg
,
MEM_ROOT
*
mem_root_arg
,
uint
select_number_arg
);
...
...
@@ -354,6 +363,14 @@ class Opt_hints_qb : public Opt_hints
append_identifier
(
thd
,
str
,
&
print_name
);
}
virtual
void
append_args
(
THD
*
thd
,
String
*
str
)
const
override
{
if
(
semijoin_hint
)
semijoin_hint
->
append_args
(
thd
,
str
);
if
(
subquery_hint
)
subquery_hint
->
append_args
(
thd
,
str
);
}
/**
Function finds Opt_hints_table object corresponding to
table alias in the query block and attaches corresponding
...
...
@@ -367,6 +384,17 @@ class Opt_hints_qb : public Opt_hints
*/
Opt_hints_table
*
adjust_table_hints
(
TABLE
*
table
,
const
Lex_ident_table
&
alias
);
const
Optimizer_hint_parser
::
Semijoin_hint
*
semijoin_hint
=
nullptr
;
/*
Bitmap of strategies listed in the SEMIJOIN/NO_SEMIJOIN hint body, e.g.
FIRSTMATCH | LOOSESCAN
*/
uint
semijoin_strategies_map
=
0
;
const
Optimizer_hint_parser
::
Subquery_hint
*
subquery_hint
=
nullptr
;
uint
subquery_strategy
=
0
;
};
...
...
sql/opt_hints_parser.cc
View file @
ce18ab4b
...
...
@@ -57,6 +57,37 @@ Optimizer_hint_tokenizer::find_keyword(const LEX_CSTRING &str)
return
TokenID
::
keyword_QB_NAME
;
break
;
case
8
:
if
(
"SEMIJOIN"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_SEMIJOIN
;
else
if
(
"SUBQUERY"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_SUBQUERY
;
break
;
case
9
:
if
(
"LOOSESCAN"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_LOOSESCAN
;
break
;
case
10
:
if
(
"FIRSTMATCH"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_FIRSTMATCH
;
else
if
(
"INTOEXISTS"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_INTOEXISTS
;
break
;
case
11
:
if
(
"NO_SEMIJOIN"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_NO_SEMIJOIN
;
else
if
(
"DUPSWEEDOUT"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_DUPSWEEDOUT
;
break
;
case
15
:
if
(
"MATERIALIZATION"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_MATERIALIZATION
;
break
;
case
21
:
if
(
"NO_RANGE_OPTIMIZATION"
_Lex_ident_column
.
streq
(
str
))
return
TokenID
::
keyword_NO_RANGE_OPTIMIZATION
;
...
...
@@ -201,3 +232,16 @@ Optimizer_hint_parser::
*
pe
=
std
::
move
(
elem
);
return
push_back
(
pe
,
p
->
m_thd
->
mem_root
);
}
bool
Optimizer_hint_parser
::
Semijoin_strategy_list_container
::
add
(
Optimizer_hint_parser
*
p
,
Semijoin_strategy
&&
elem
)
{
Semijoin_strategy
*
pe
=
(
Semijoin_strategy
*
)
p
->
m_thd
->
alloc
(
sizeof
(
*
pe
));
if
(
!
pe
)
return
true
;
*
pe
=
std
::
move
(
elem
);
return
push_back
(
pe
,
p
->
m_thd
->
mem_root
);
}
sql/opt_hints_parser.h
View file @
ce18ab4b
...
...
@@ -25,6 +25,7 @@
#include "simple_parser.h"
class
st_select_lex
;
class
Opt_hints_qb
;
/**
Environment data for the name resolution phase
...
...
@@ -72,6 +73,14 @@ class Optimizer_hint_tokenizer: public Extended_string_tokenizer
keyword_NO_RANGE_OPTIMIZATION
,
keyword_MRR
,
keyword_QB_NAME
,
keyword_SEMIJOIN
,
keyword_NO_SEMIJOIN
,
keyword_SUBQUERY
,
keyword_MATERIALIZATION
,
keyword_FIRSTMATCH
,
keyword_LOOSESCAN
,
keyword_DUPSWEEDOUT
,
keyword_INTOEXISTS
,
// Other token types
tIDENT
...
...
@@ -240,6 +249,12 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
using
TOKEN
::
TOKEN
;
};
class
Keyword_SUBQUERY
:
public
TOKEN
<
PARSER
,
TokenID
::
keyword_SUBQUERY
>
{
public:
using
TOKEN
::
TOKEN
;
};
class
Identifier
:
public
TOKEN
<
PARSER
,
TokenID
::
tIDENT
>
{
public:
...
...
@@ -312,10 +327,8 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
using
TokenChoice
::
TokenChoice
;
};
// Identifiers of various kinds
// query_block_name ::= identifier
class
Query_block_name
:
public
Identifier
{
...
...
@@ -554,21 +567,224 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
};
// semijoin_hint_type ::= SEMIJOIN | NO_SEMIJOIN
class
Semijoin_hint_type_cond
{
public:
static
bool
allowed_token_id
(
TokenID
id
)
{
return
id
==
TokenID
::
keyword_SEMIJOIN
||
id
==
TokenID
::
keyword_NO_SEMIJOIN
;
}
};
class
Semijoin_hint_type
:
public
TokenChoice
<
PARSER
,
Semijoin_hint_type_cond
>
{
public:
using
TokenChoice
::
TokenChoice
;
};
// semijoin_strategy ::= MATERIALIZATION | FIRSTMATCH | LOOSESCAN | DUPSWEEDOUT
class
Semijoin_strategy_cond
{
public:
static
bool
allowed_token_id
(
TokenID
id
)
{
return
id
==
TokenID
::
keyword_MATERIALIZATION
||
id
==
TokenID
::
keyword_FIRSTMATCH
||
id
==
TokenID
::
keyword_LOOSESCAN
||
id
==
TokenID
::
keyword_DUPSWEEDOUT
;
}
};
class
Semijoin_strategy
:
public
TokenChoice
<
PARSER
,
Semijoin_strategy_cond
>
{
public:
using
TokenChoice
::
TokenChoice
;
};
/*
strategy_list ::= strategy_name [ {, strategy_name }... ]
opt_strategy_list ::= [ strategy_list ]
*/
class
Semijoin_strategy_list_container
:
public
List
<
Semijoin_strategy
>
{
public:
Semijoin_strategy_list_container
()
{
}
bool
add
(
Optimizer_hint_parser
*
p
,
Semijoin_strategy
&&
strategy
);
size_t
count
()
const
{
return
elements
;
}
};
class
Opt_sj_strategy_list
:
public
LIST
<
PARSER
,
Semijoin_strategy_list_container
,
Semijoin_strategy
,
TokenID
::
tCOMMA
,
0
>
{
public:
using
LIST
::
LIST
;
};
class
Hint_param_opt_sj_strategy_list
:
public
LIST
<
PARSER
,
Semijoin_strategy_list_container
,
Semijoin_strategy
,
TokenID
::
tCOMMA
,
0
>
{
public:
using
LIST
::
LIST
;
};
/*
at_query_block_name_opt_strategies_list ::=
@ query_block_name opt_strategies_list
*/
class
At_query_block_name_opt_strategy_list
:
public
AND2
<
PARSER
,
At_query_block_name
,
Opt_sj_strategy_list
>
{
public:
using
AND2
::
AND2
;
};
/*
semijoin_hint_body: @ query_block_name opt_sj_strategy_list
| opt_sj_strategy_list
*/
class
Semijoin_hint_body
:
public
OR2
<
PARSER
,
At_query_block_name_opt_strategy_list
,
Hint_param_opt_sj_strategy_list
>
{
public:
using
OR2
::
OR2
;
};
public:
/*
semijoin_hint ::= semijoin_hint_type ( semijoin_hint_body )
*/
class
Semijoin_hint
:
public
AND4
<
PARSER
,
Semijoin_hint_type
,
LParen
,
Semijoin_hint_body
,
RParen
>
{
public:
using
AND4
::
AND4
;
bool
resolve
(
Parse_context
*
pc
)
const
;
void
append_args
(
THD
*
thd
,
String
*
str
)
const
;
private:
void
fill_strategies_map
(
Opt_hints_qb
*
qb
)
const
;
void
add_strategy_to_map
(
TokenID
token_id
,
Opt_hints_qb
*
qb
)
const
;
void
append_strategy_name
(
TokenID
token_id
,
String
*
str
,
int
&
appended_count
)
const
;
};
private:
// subquery_strategy ::= MATERIALIZATION | INTOEXISTS
class
Subquery_strategy_cond
{
public:
static
bool
allowed_token_id
(
TokenID
id
)
{
return
id
==
TokenID
::
keyword_MATERIALIZATION
||
id
==
TokenID
::
keyword_INTOEXISTS
;
}
};
class
Subquery_strategy
:
public
TokenChoice
<
PARSER
,
Subquery_strategy_cond
>
{
public:
using
TokenChoice
::
TokenChoice
;
};
class
Hint_param_subquery_strategy
:
public
TokenChoice
<
PARSER
,
Subquery_strategy_cond
>
{
public:
using
TokenChoice
::
TokenChoice
;
};
/*
at_query_block_name_subquery_strategy ::=
@ query_block_name subquery_strategy
*/
class
At_query_block_name_subquery_strategy
:
public
AND2
<
PARSER
,
At_query_block_name
,
Subquery_strategy
>
{
public:
using
AND2
::
AND2
;
};
/*
subquery_hint_body: @ query_block_name subquery_strategy
| subquery_strategy
*/
class
Subquery_hint_body
:
public
OR2
<
PARSER
,
At_query_block_name_subquery_strategy
,
Hint_param_subquery_strategy
>
{
public:
using
OR2
::
OR2
;
};
public:
// subquery_hint ::= SUBQUERY( subquery_hint_body )
class
Subquery_hint
:
public
AND4
<
PARSER
,
Keyword_SUBQUERY
,
LParen
,
Subquery_hint_body
,
RParen
>
{
public:
using
AND4
::
AND4
;
bool
resolve
(
Parse_context
*
pc
)
const
;
void
append_args
(
THD
*
thd
,
String
*
str
)
const
;
private:
void
set_subquery_strategy
(
TokenID
token_id
,
Opt_hints_qb
*
qb
)
const
;
};
/*
hint ::= index_level_hint
| table_level_hint
| qb_name_hint
| qb_level_hint
*/
class
Hint
:
public
OR
3
<
PARSER
,
class
Hint
:
public
OR
5
<
PARSER
,
Index_level_hint
,
Table_level_hint
,
Qb_name_hint
>
Qb_name_hint
,
Semijoin_hint
,
Subquery_hint
>
{
public:
using
OR3
::
OR3
;
};
using
OR5
::
OR5
;
/**
Append additional hint arguments to the printed string.
Implement this method in Hint specifications if needed:
Table_level_hint, Semijoin_hint, etc
@param thd Pointer to THD object
@param str Pointer to String object
*/
void
append_args
(
THD
*
thd
,
String
*
str
)
const
{}
};
private:
// hint_list ::= hint [ hint... ]
class
Hint_list_container
:
public
List
<
Hint
>
{
...
...
@@ -579,6 +795,7 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
size_t
count
()
const
{
return
elements
;
}
};
class
Hint_list
:
public
LIST
<
PARSER
,
Hint_list_container
,
Hint
,
TokenID
::
tNULL
/*not separated list*/
,
1
>
{
...
...
@@ -598,12 +815,11 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
public:
using
AND2
::
AND2
;
};
};
/*
Th
is wrapper class is needed to use a forward declaration
in sql_lex.h
Th
ese wrapper class is needed to use a forward declarations
in sql_lex.h
instead of including the entire opt_hints_parser.h.
(forward declarations of qualified nested classes are not possible in C++)
*/
...
...
@@ -613,5 +829,4 @@ class Optimizer_hint_parser_output: public Optimizer_hint_parser::Hints
using
Hints
::
Hints
;
};
#endif // OPT_HINTS_PARSER
sql/simple_parser.h
View file @
ce18ab4b
...
...
@@ -442,6 +442,92 @@ class Parser_templates
};
/*
A rule consisting of a choice of four rules:
rule ::= rule1 | rule2 | rule3 | rule4
For the case when the four branches have incompatible storage
*/
template
<
class
PARSER
,
class
A
,
class
B
,
class
C
,
class
D
>
class
OR4
:
public
A
,
public
B
,
public
C
,
public
D
{
public:
OR4
()
{
}
OR4
(
OR4
&&
rhs
)
:
A
(
std
::
move
(
static_cast
<
A
&&>
(
rhs
))),
B
(
std
::
move
(
static_cast
<
B
&&>
(
rhs
))),
C
(
std
::
move
(
static_cast
<
C
&&>
(
rhs
))),
D
(
std
::
move
(
static_cast
<
D
&&>
(
rhs
)))
{
}
OR4
&
operator
=
(
OR4
&&
rhs
)
{
A
::
operator
=
(
std
::
move
(
static_cast
<
A
&&>
(
rhs
)));
B
::
operator
=
(
std
::
move
(
static_cast
<
B
&&>
(
rhs
)));
C
::
operator
=
(
std
::
move
(
static_cast
<
C
&&>
(
rhs
)));
D
::
operator
=
(
std
::
move
(
static_cast
<
D
&&>
(
rhs
)));
return
*
this
;
}
OR4
(
PARSER
*
p
)
:
A
(
p
),
B
(
A
::
operator
bool
()
?
B
()
:
B
(
p
)),
C
(
A
::
operator
bool
()
||
B
::
operator
bool
()
?
C
()
:
C
(
p
)),
D
(
A
::
operator
bool
()
||
B
::
operator
bool
()
||
C
::
operator
bool
()
?
D
()
:
D
(
p
))
{
DBUG_ASSERT
(
!
operator
bool
()
||
!
p
->
is_error
());
}
operator
bool
()
const
{
return
A
::
operator
bool
()
||
B
::
operator
bool
()
||
C
::
operator
bool
()
||
D
::
operator
bool
();
}
};
/*
A rule consisting of a choice of five rules:
rule ::= rule1 | rule2 | rule3 | rule4 | rule5
*/
template
<
class
PARSER
,
class
A
,
class
B
,
class
C
,
class
D
,
class
E
>
class
OR5
:
public
A
,
public
B
,
public
C
,
public
D
,
public
E
{
public:
OR5
()
{
}
OR5
(
OR5
&&
rhs
)
:
A
(
std
::
move
(
static_cast
<
A
&&>
(
rhs
))),
B
(
std
::
move
(
static_cast
<
B
&&>
(
rhs
))),
C
(
std
::
move
(
static_cast
<
C
&&>
(
rhs
))),
D
(
std
::
move
(
static_cast
<
D
&&>
(
rhs
))),
E
(
std
::
move
(
static_cast
<
E
&&>
(
rhs
)))
{
}
OR5
&
operator
=
(
OR5
&&
rhs
)
{
A
::
operator
=
(
std
::
move
(
static_cast
<
A
&&>
(
rhs
)));
B
::
operator
=
(
std
::
move
(
static_cast
<
B
&&>
(
rhs
)));
C
::
operator
=
(
std
::
move
(
static_cast
<
C
&&>
(
rhs
)));
D
::
operator
=
(
std
::
move
(
static_cast
<
D
&&>
(
rhs
)));
E
::
operator
=
(
std
::
move
(
static_cast
<
E
&&>
(
rhs
)));
return
*
this
;
}
OR5
(
PARSER
*
p
)
:
A
(
p
),
B
(
A
::
operator
bool
()
?
B
()
:
B
(
p
)),
C
(
A
::
operator
bool
()
||
B
::
operator
bool
()
?
C
()
:
C
(
p
)),
D
(
A
::
operator
bool
()
||
B
::
operator
bool
()
||
C
::
operator
bool
()
?
D
()
:
D
(
p
)),
E
(
A
::
operator
bool
()
||
B
::
operator
bool
()
||
C
::
operator
bool
()
||
D
::
operator
bool
()
?
E
()
:
E
(
p
))
{
DBUG_ASSERT
(
!
operator
bool
()
||
!
p
->
is_error
());
}
operator
bool
()
const
{
return
A
::
operator
bool
()
||
B
::
operator
bool
()
||
C
::
operator
bool
()
||
D
::
operator
bool
()
||
E
::
operator
bool
();
}
};
/*
A list with at least MIN_COUNT elements (typlically 0 or 1),
with or without a token separator between elements:
...
...
sql/sql_priv.h
View file @
ce18ab4b
...
...
@@ -140,41 +140,47 @@
#define OPTIMIZER_SWITCH_DERIVED_WITH_KEYS (1ULL << 7)
#define OPTIMIZER_SWITCH_FIRSTMATCH (1ULL << 8)
#define OPTIMIZER_SWITCH_LOOSE_SCAN (1ULL << 9)
#define OPTIMIZER_SWITCH_MATERIALIZATION (1ULL << 10)
#define OPTIMIZER_SWITCH_IN_TO_EXISTS (1ULL << 11)
#define OPTIMIZER_SWITCH_SEMIJOIN (1ULL << 12)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE (1ULL << 13)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN (1ULL << 14)
#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1ULL << 15)
/*
The following switch is not controlled by optimizer_switch variable,
it is used internally for processing of SEMIJOIN() and NO_SEMIJOIN() hints
OLEGS: actually it's possible to set at optimizer_switch
*/
#define OPTIMIZER_SWITCH_DUPSWEEDOUT (1ULL << 10)
#define OPTIMIZER_SWITCH_MATERIALIZATION (1ULL << 11)
#define OPTIMIZER_SWITCH_IN_TO_EXISTS (1ULL << 12)
#define OPTIMIZER_SWITCH_SEMIJOIN (1ULL << 13)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE (1ULL << 14)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN (1ULL << 15)
#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1ULL << 16)
/** If this is off, MRR is never used. */
#define OPTIMIZER_SWITCH_MRR (1ULL << 1
6
)
#define OPTIMIZER_SWITCH_MRR (1ULL << 1
7
)
/**
If OPTIMIZER_SWITCH_MRR is on and this is on, MRR is used depending on a
cost-based choice ("automatic"). If OPTIMIZER_SWITCH_MRR is on and this is
off, MRR is "forced" (i.e. used as long as the storage engine is capable of
doing it).
*/
#define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 1
7
)
#define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1ULL << 1
8
)
#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1ULL <<
19
)
#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1ULL << 2
0
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1ULL << 2
1
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 2
2
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 2
3
)
#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 2
4
)
#define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 2
5
)
#define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 2
6
)
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 2
7
)
#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP (1ULL << 2
8
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL <<
29
)
#define OPTIMIZER_SWITCH_SPLIT_MATERIALIZED (1ULL << 3
0
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY (1ULL << 3
1
)
#define OPTIMIZER_SWITCH_USE_ROWID_FILTER (1ULL << 3
2
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FROM_HAVING (1ULL << 3
3
)
#define OPTIMIZER_SWITCH_NOT_NULL_RANGE_SCAN (1ULL << 3
4
)
#define OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY (1ULL << 3
5
)
#define OPTIMIZER_SWITCH_CSET_NARROWING (1ULL << 3
6
)
#define OPTIMIZER_SWITCH_SARGABLE_CASEFOLD (1ULL << 3
7
)
#define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 1
8
)
#define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1ULL << 1
9
)
#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1ULL <<
20
)
#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1ULL << 2
1
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1ULL << 2
2
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 2
3
)
#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 2
4
)
#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 2
5
)
#define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 2
6
)
#define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 2
7
)
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 2
8
)
#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP (1ULL << 2
9
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL <<
30
)
#define OPTIMIZER_SWITCH_SPLIT_MATERIALIZED (1ULL << 3
1
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY (1ULL << 3
2
)
#define OPTIMIZER_SWITCH_USE_ROWID_FILTER (1ULL << 3
3
)
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FROM_HAVING (1ULL << 3
4
)
#define OPTIMIZER_SWITCH_NOT_NULL_RANGE_SCAN (1ULL << 3
5
)
#define OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY (1ULL << 3
6
)
#define OPTIMIZER_SWITCH_CSET_NARROWING (1ULL << 3
7
)
#define OPTIMIZER_SWITCH_SARGABLE_CASEFOLD (1ULL << 3
8
)
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
...
...
@@ -198,6 +204,7 @@
OPTIMIZER_SWITCH_SEMIJOIN | \
OPTIMIZER_SWITCH_FIRSTMATCH | \
OPTIMIZER_SWITCH_LOOSE_SCAN | \
OPTIMIZER_SWITCH_DUPSWEEDOUT | \
OPTIMIZER_SWITCH_EXISTS_TO_IN | \
OPTIMIZER_SWITCH_ORDERBY_EQ_PROP | \
OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED | \
...
...
sql/sys_vars.cc
View file @
ce18ab4b
...
...
@@ -2936,7 +2936,7 @@ export const char *optimizer_switch_names[]=
"index_merge_intersection"
,
"index_merge_sort_intersection"
,
"index_condition_pushdown"
,
"derived_merge"
,
"derived_with_keys"
,
"firstmatch"
,
"loosescan"
,
"materialization"
,
"in_to_exists"
,
"semijoin"
,
"firstmatch"
,
"loosescan"
,
"
dupsweedout"
,
"
materialization"
,
"in_to_exists"
,
"semijoin"
,
"partial_match_rowid_merge"
,
"partial_match_table_scan"
,
"subquery_cache"
,
...
...
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