MySQL 8.4.3
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/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  Query_result_explain_into_var
 Wrapper class for writing EXPLAIN output to a user variable. More...
 
class  Sql_cmd_explain_other_thread
 

Functions

bool explain_single_table_modification (THD *explain_thd, const THD *query_thd, const Modification_plan *plan, Query_block *select)
 EXPLAIN handling for single-table INSERT VALUES, 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_term *query_term, enum_parsing_context ctx)
 Explain query_block's join. More...
 
void print_query_for_explain (const THD *query_thd, Query_expression *unit, String *str)
 This code which prints the extended description is not robust against malformed queries, so skip calling this function if we have an error or if explaining other thread (see Explain::can_print_clauses()). 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 or more JOIN for the post processing block Query_block of set operations (e.g. UNION), see query_term.h; each JOIN explain (JOIN::exec()) calls explain_query_specification()

(3) explain_query_specification()

Is for a single Query_block (post processing or not, see query_term.h). 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_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

◆ explain_query_specification()

bool explain_query_specification ( THD explain_thd,
const THD query_thd,
Query_term query_term,
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_termexplain join attached to given term's 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 INSERT VALUES, UPDATE, and DELETE queries.

Send to the client a QEP data set for single-table EXPLAIN INSERT VALUES/UPDATE/DELETE queries. As far as single-table INSERT VALUES/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.

◆ print_query_for_explain()

void print_query_for_explain ( const THD query_thd,
Query_expression unit,
String str 
)

This code which prints the extended description is not robust against malformed queries, so skip calling this function if we have an error or if explaining other thread (see Explain::can_print_clauses()).

For DML statements use QT_NO_DATA_EXPANSION to avoid over-simplification.

Variable Documentation

◆ join_type_str

const char* join_type_str[]
extern