MySQL  8.0.19
Source Code Documentation
opt_explain.cc File Reference
#include "sql/opt_explain.h"
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <algorithm>
#include <atomic>
#include <limits>
#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_inttypes.h"
#include "my_macros.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "my_table_map.h"
#include "my_thread_local.h"
#include "mysql/psi/mysql_mutex.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "scope_guard.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/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_range.h"
#include "sql/opt_trace.h"
#include "sql/protocol.h"
#include "sql/row_iterator.h"
#include "sql/sql_base.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_join_buffer.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/timing_iterator.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_unit (THD *explain_thd, const THD *query_thd, SELECT_LEX_UNIT *unit)
 Explain UNION or subqueries of the unit. More...
 
static bool ExplainIterator (THD *ethd, const THD *query_thd, SELECT_LEX_UNIT *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, SELECT_LEX *select_lex, 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, SELECT_LEX *select)
 EXPLAIN handling for single-table UPDATE and 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...
 
vector< string > FullDebugString (const THD *thd, const RowIterator &iterator)
 
std::string PrintQueryPlan (int level, RowIterator *iterator)
 
static string FindUpdatedTables (JOIN *join)
 
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...
 
void ForEachSubselect (Item *parent_item, const function< void(int select_number, bool is_dependent, bool is_cacheable, RowIterator *)> &callback)
 
vector< RowIterator::ChildGetIteratorsFromSelectList (JOIN *join)
 

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,
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_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,
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.

◆ ExplainIterator()

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

◆ FindUpdatedTables()

static string FindUpdatedTables ( JOIN join)
static

◆ ForEachSubselect()

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

◆ FullDebugString()

vector<string> FullDebugString ( const THD thd,
const RowIterator iterator 
)

◆ GetIteratorsFromSelectList()

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

◆ mysql_explain_unit()

bool mysql_explain_unit ( THD explain_thd,
const THD query_thd,
SELECT_LEX_UNIT 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

◆ PrintQueryPlan()

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

◆ 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

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

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