MySQL  8.0.27
Source Code Documentation
opt_explain.h File Reference

EXPLAIN <command>. More...

#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_opt_exec_shared.h"
#include "sys/types.h"

Go to the source code of this file.

Classes

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, Query_block *query_block, 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, Query_block *select)
 EXPLAIN handling for single-table UPDATE and DELETE queries. More...
 
bool explain_query (THD *explain_thd, const THD *query_thd, Query_expression *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, Query_block *query_block, enum_parsing_context ctx)
 Explain query_block's join. More...
 

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_query_expression().

(2) explain_query_expression()

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

(3) explain_query_specification()

Is for a single Query_block (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 Query_block), by calling explain_query_expression() for each of them.

Function Documentation

◆ explain_no_table()

bool explain_no_table ( THD explain_thd,
const THD query_thd,
Query_block query_block,
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
query_blockquery_block 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,
Query_expression 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 Query_expression or Query_block) 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.
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,
Query_block query_block,
enum_parsing_context  ctx 
)

Explain query_block's join.

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

◆ explain_single_table_modification()

bool explain_single_table_modification ( THD explain_thd,
const THD query_thd,
const Modification_plan plan,
Query_block 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_query_expression() directly, thus we deal with this single table in a special way and then call explain_query_expression() 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 Query_block::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.

Variable Documentation

◆ join_type_str

const char* join_type_str[]
extern