MySQL  8.0.18
Source Code Documentation
opt_explain.h File Reference


EXPLAIN <command>. More...

#include <string>
#include <vector>
#include "my_base.h"
#include "my_sqlcommand.h"
#include "my_thread_local.h"
#include "sql/opt_explain_format.h"
#include "sql/parse_tree_node_base.h"
#include "sql/query_result.h"
#include "sql/row_iterator.h"
#include "sql/sql_cmd.h"
#include "sql/sql_lex.h"
#include "sys/types.h"
#include <functional>

Go to the source code of this file.

Classes

class  List< T >
 
class  Modification_plan
 Table modification plan for JOIN-less statements (update/delete) More...
 
class  Query_result_explain
 EXPLAIN functionality for Query_result_insert, Query_result_update and Query_result_delete. More...
 
class  Sql_cmd_explain_other_thread
 

Functions

bool explain_no_table (THD *explain_thd, const THD *query_thd, SELECT_LEX *select_lex, const char *message, enum_parsing_context ctx)
 Send a message as an "extra" column value. More...
 
bool explain_single_table_modification (THD *explain_thd, const THD *query_thd, const Modification_plan *plan, SELECT_LEX *select)
 EXPLAIN handling for single-table UPDATE and DELETE queries. More...
 
bool explain_query (THD *explain_thd, const THD *query_thd, SELECT_LEX_UNIT *unit)
 EXPLAIN handling for SELECT, INSERT/REPLACE SELECT, and multi-table UPDATE/DELETE queries. More...
 
bool explain_query_specification (THD *explain_thd, const THD *query_thd, SELECT_LEX *select_lex, enum_parsing_context ctx)
 Explain select_lex's join. More...
 
std::string PrintQueryPlan (int level, RowIterator *iterator)
 
void ForEachSubselect (Item *parent_item, const std::function< void(int select_number, bool is_dependent, bool is_cacheable, RowIterator *iterator)> &callback)
 
std::vector< RowIterator::ChildGetIteratorsFromSelectList (JOIN *join)
 

Variables

const char * join_type_str []
 

Detailed Description


EXPLAIN <command>.

Single table UPDATE/DELETE commands are explained by the explain_single_table_modification() function.

A query expression (complete SELECT query possibly including subqueries and unions), INSERT...SELECT and multitable UPDATE/DELETE commands are explained like this:

(1) explain_query_expression()

Is the entry point. Forwards the job to explain_unit().

(2) explain_unit()

Is for a SELECT_LEX_UNIT, prepares, optimizes, explains one JOIN for each "top-level" SELECT_LEXs of the unit (like: all SELECTs of a UNION; but not subqueries), and one JOIN for the fake SELECT_LEX of UNION); each JOIN explain (JOIN::exec()) calls explain_query_specification()

(3) explain_query_specification()

Is for a single SELECT_LEX (fake or not). It needs a prepared and optimized JOIN, for which it builds the EXPLAIN rows. But it also launches the EXPLAIN process for "inner units" (==subqueries of this SELECT_LEX), by calling explain_unit() for each of them.

Function Documentation

◆ explain_no_table()

bool explain_no_table ( THD explain_thd,
const THD query_thd,
SELECT_LEX select_lex,
const char *  message,
enum_parsing_context  ctx 
)

Send a message as an "extra" column value.

This function forms the 1st row of the QEP output with a simple text message. This is useful to explain such trivial cases as "No tables used" etc.

Note
Also this function explains the rest of QEP (subqueries or joined tables if any).
Parameters
explain_thdthread handle for the connection doing explain
query_thdthread handle for the connection being explained
select_lexselect_lex to explain
messagetext message for the "extra" column.
ctxcurrent query context, CTX_JOIN in most cases.
Returns
false if success, true if error

◆ explain_query()

bool explain_query ( THD explain_thd,
const THD query_thd,
SELECT_LEX_UNIT unit 
)

EXPLAIN handling for SELECT, INSERT/REPLACE SELECT, and multi-table UPDATE/DELETE queries.

Send to the client a QEP data set for any DML statement that has a QEP represented completely by JOIN object(s).

This function uses a specific Query_result object for sending explain output to the client.

When explaining own query, the existing Query_result object (found in outermost SELECT_LEX_UNIT or SELECT_LEX) is used. However, if the Query_result is unsuitable for explanation (need_explain_interceptor() returns true), wrap the Query_result inside an Query_result_explain object.

When explaining other query, create a Query_result_send object and prepare it as if it was a regular SELECT query.

Note
see explain_single_table_modification() for single-table UPDATE/DELETE EXPLAIN handling.
Unlike handle_query(), explain_query() calls abort_result_set() itself in the case of failure (OOM etc.) since it may use an internally created Query_result object that has to be deleted before exiting the function.
Parameters
explain_thdthread handle for the connection doing explain
query_thdthread handle for the connection being explained
unitquery tree to explain
Returns
false if success, true if error

For DML statements use QT_NO_DATA_EXPANSION to avoid over-simplification.

◆ explain_query_specification()

bool explain_query_specification ( THD explain_thd,
const THD query_thd,
SELECT_LEX select_lex,
enum_parsing_context  ctx 
)

Explain select_lex's join.

Parameters
explain_thdthread handle for the connection doing explain
query_thdthread handle for the connection being explained
select_lexexplain join attached to given select_lex
ctxcurrent explain context

◆ explain_single_table_modification()

bool explain_single_table_modification ( THD explain_thd,
const THD query_thd,
const Modification_plan plan,
SELECT_LEX select 
)

EXPLAIN handling for single-table UPDATE and DELETE queries.

Send to the client a QEP data set for single-table EXPLAIN UPDATE/DELETE queries. As far as single-table UPDATE/DELETE are implemented without the regular JOIN tree, we can't reuse explain_unit() directly, thus we deal with this single table in a special way and then call explain_unit() for subqueries (if any).

Parameters
explain_thdthread handle for the connection doing explain
query_thdthread handle for the connection being explained
plantable modification plan
selectQuery's select lex
Returns
false if success, true if error

Prepare the self-allocated result object

For queries with top-level JOIN the caller provides pre-allocated Query_result_send object. Then that JOIN object prepares the Query_result_send object calling result->prepare() in SELECT_LEX::prepare(), result->optimize() in JOIN::optimize() and result->start_execution() in JOIN::exec(). However without the presence of the top-level JOIN we have to prepare/initialize Query_result_send object manually.

◆ ForEachSubselect()

void ForEachSubselect ( Item parent_item,
const std::function< void(int select_number, bool is_dependent, bool is_cacheable, RowIterator *iterator)> &  callback 
)

◆ GetIteratorsFromSelectList()

std::vector<RowIterator::Child> GetIteratorsFromSelectList ( JOIN join)

◆ PrintQueryPlan()

std::string PrintQueryPlan ( int  level,
RowIterator iterator 
)

Variable Documentation

◆ join_type_str

const char* join_type_str[]