MySQL  8.0.27
Source Code Documentation
opt_explain.cc File Reference

"EXPLAIN <command>" implementation. More...

#include "sql/opt_explain.h"
#include <sys/types.h>
#include <algorithm>
#include <atomic>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include "ft_global.h"
#include "lex_string.h"
#include "m_ctype.h"
#include "m_string.h"
#include "my_alloc.h"
#include "my_base.h"
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_double2ulonglong.h"
#include "my_inttypes.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "my_thread_local.h"
#include "mysql/psi/mysql_mutex.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/current_thd.h"
#include "sql/debug_sync.h"
#include "sql/derror.h"
#include "sql/enum_query_type.h"
#include "sql/field.h"
#include "sql/handler.h"
#include "sql/item.h"
#include "sql/item_func.h"
#include "sql/item_subselect.h"
#include "sql/join_optimizer/bit_utils.h"
#include "sql/join_optimizer/explain_access_path.h"
#include "sql/join_optimizer/join_optimizer.h"
#include "sql/key.h"
#include "sql/mysqld.h"
#include "sql/mysqld_thd_manager.h"
#include "sql/opt_costmodel.h"
#include "sql/opt_explain_format.h"
#include "sql/opt_trace.h"
#include "sql/protocol.h"
#include "sql/range_optimizer/group_min_max.h"
#include "sql/range_optimizer/range_optimizer.h"
#include "sql/range_optimizer/rowid_ordered_retrieval.h"
#include "sql/row_iterator.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_class.h"
#include "sql/sql_cmd.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_executor.h"
#include "sql/sql_lex.h"
#include "sql/sql_list.h"
#include "sql/sql_opt_exec_shared.h"
#include "sql/sql_optimizer.h"
#include "sql/sql_parse.h"
#include "sql/sql_partition.h"
#include "sql/sql_select.h"
#include "sql/table.h"
#include "sql/table_function.h"
#include "sql/temp_table_param.h"
#include "sql_string.h"
#include "template_utils.h"

Classes

class  Explain
 A base for all Explain_* classes. More...
 
class  Explain::Lazy_condition
 
class  Explain_no_table
 Explain_no_table class outputs a trivial EXPLAIN row with "extra" column. More...
 
class  Explain_union_result
 Explain_union_result class outputs EXPLAIN row for UNION. More...
 
class  Explain_table_base
 Common base class for Explain_join and Explain_table. More...
 
class  Explain_join
 Explain_join class produces EXPLAIN output for JOINs. More...
 
class  Explain_table
 Explain_table class produce EXPLAIN output for queries without top-level JOIN. More...
 
class  Query_result_null
 A query result handler that outputs nothing. More...
 
class  Find_thd_query_lock
 Callback function used by Sql_cmd_explain_other_thread::execute() to find thd based on the thread id. More...
 

Typedefs

typedef qep_row::extra extra
 

Functions

static bool mysql_explain_query_expression (THD *explain_thd, const THD *query_thd, Query_expression *unit)
 Explain UNION or subqueries of the unit. More...
 
static bool ExplainIterator (THD *ethd, const THD *query_thd, Query_expression *unit)
 
static bool explain_ref_key (Explain_format *fmt, uint key_parts, store_key *key_copy[])
 
static bool store_table_name (TABLE_LIST *tr, Explain_format *fmt, std::function< bool(const char *name, size_t len)> func)
 Generates either usual table name or <derived::N>, and passes it to any given function for showing to the user. More...
 
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...
 
static bool check_acl_for_explain (const TABLE_LIST *table_list)
 Check that we are allowed to explain all views in list. 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_specification (THD *explain_thd, const THD *query_thd, Query_block *query_block, enum_parsing_context ctx)
 Explain query_block's join. More...
 
static string FindUpdatedTables (JOIN *join)
 
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...
 

Variables

const char * join_type_str []
 
static const enum_query_type cond_print_flags
 
static const char * plan_not_ready []
 First string: for regular EXPLAIN; second: for EXPLAIN CONNECTION. More...
 

Detailed Description

"EXPLAIN <command>" implementation.

Typedef Documentation

◆ extra

Function Documentation

◆ check_acl_for_explain()

static bool check_acl_for_explain ( const TABLE_LIST table_list)
static

Check that we are allowed to explain all views in list.

Because this function is called only when we have a complete plan, we know that:

  • views contained in merge-able views have been merged and brought up in the top list of tables, so we only need to scan this list
  • table_list is not changing while we are reading it. If we don't have a complete plan, EXPLAIN output does not contain table names, so we don't need to check views.
Parameters
table_listtable to start with, usually lex->query_tables
Returns
true Caller can't EXPLAIN query due to lack of rights on a view in the query false Caller can EXPLAIN query

◆ 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_ref_key()

static bool explain_ref_key ( Explain_format fmt,
uint  key_parts,
store_key key_copy[] 
)
static

◆ 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.

◆ ExplainIterator()

static bool ExplainIterator ( THD ethd,
const THD query_thd,
Query_expression unit 
)
static

◆ FindUpdatedTables()

static string FindUpdatedTables ( JOIN join)
static
Returns
a comma-separated list of all tables that are touched by UPDATE or DELETE, with a mention of whether a temporary table is used for each.

◆ mysql_explain_query_expression()

bool mysql_explain_query_expression ( THD explain_thd,
const THD query_thd,
Query_expression unit 
)
static

Explain UNION or subqueries of the unit.

If the unit is a UNION, explain it as a UNION. Otherwise explain nested subselects.

Parameters
explain_thdthread handle for the connection doing explain
query_thdthread handle for the connection being explained
unitunit object, might not belong to ethd
Returns
false if success, true if error

◆ store_table_name()

static bool store_table_name ( TABLE_LIST tr,
Explain_format fmt,
std::function< bool(const char *name, size_t len)>  func 
)
static

Generates either usual table name or <derived::N>, and passes it to any given function for showing to the user.

Parameters
trTable reference
fmtEXPLAIN's format
funcFunction receiving the name
Returns
true if error.

Variable Documentation

◆ cond_print_flags

const enum_query_type cond_print_flags
static
Initial value:
=
enum_query_type
Query type constants (usable as bitmap flags).
Definition: enum_query_type.h:30
@ QT_ORDINARY
Nothing specific, ordinary SQL query.
Definition: enum_query_type.h:32
@ QT_SHOW_SELECT_NUMBER
When printing a SELECT, add its number (query_block->number).
Definition: enum_query_type.h:47

◆ join_type_str

const char* join_type_str[]
Initial value:
= {
"UNKNOWN", "system", "const", "eq_ref", "ref", "ALL",
"range", "index", "fulltext", "ref_or_null", "index_merge"}

◆ plan_not_ready

const char* plan_not_ready[]
static
Initial value:
= {"Not optimized, outer query is empty",
"Plan isn't ready yet"}

First string: for regular EXPLAIN; second: for EXPLAIN CONNECTION.