MySQL 9.0.0
Source Code Documentation
|
"EXPLAIN <command>" implementation. More...
#include "sql/opt_explain.h"
#include <sys/types.h>
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <string>
#include <vector>
#include "ft_global.h"
#include "lex_string.h"
#include "m_string.h"
#include "mem_root_deque.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/strings/int2str.h"
#include "mysql/strings/m_ctype.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/access_path.h"
#include "sql/join_optimizer/bit_utils.h"
#include "sql/join_optimizer/explain_access_path.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/parse_tree_node_base.h"
#include "sql/protocol.h"
#include "sql/query_term.h"
#include "sql/range_optimizer/group_index_skip_scan_plan.h"
#include "sql/range_optimizer/path_helpers.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/visible_fields.h"
#include "sql_string.h"
#include "string_with_len.h"
#include "template_utils.h"
Classes | |
class | anonymous_namespace{opt_explain.cc}::Explain |
A base for all Explain_* classes. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain::Lazy_condition |
class | anonymous_namespace{opt_explain.cc}::Explain_no_table |
Explain_no_table class outputs a trivial EXPLAIN row with "extra" column. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain_setop_result |
Explain_union_result class outputs EXPLAIN row for UNION. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain_table_base |
Common base class for Explain_join and Explain_table. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain_join |
Explain_join class produces EXPLAIN output for JOINs. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain_table |
Explain_table class produce EXPLAIN output for queries without top-level JOIN. More... | |
class | anonymous_namespace{opt_explain.cc}::Explain_secondary_engine |
This class outputs an empty plan for queries that use a secondary engine. 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... | |
Namespaces | |
namespace | anonymous_namespace{opt_explain.cc} |
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_ref *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... | |
static 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_ref *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 INSERT VALUES, UPDATE, and 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... | |
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... | |
"EXPLAIN <command>" implementation.
typedef qep_row::extra extra |
|
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:
table_list | table to start with, usually lex->query_tables |
|
static |
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.
explain_thd | thread handle for the connection doing explain |
query_thd | thread handle for the connection being explained |
query_block | query_block to explain |
message | text message for the "extra" column. |
ctx | current query context, CTX_JOIN in most cases. |
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.
explain_thd | thread handle for the connection doing explain |
query_thd | thread handle for the connection being explained |
unit | query tree to explain |
bool explain_query_specification | ( | THD * | explain_thd, |
const THD * | query_thd, | ||
Query_term * | query_term, | ||
enum_parsing_context | ctx | ||
) |
Explain query_block's join.
explain_thd | thread handle for the connection doing explain |
query_thd | thread handle for the connection being explained |
query_term | explain join attached to given term's query_block |
ctx | current explain context |
|
static |
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).
explain_thd | thread handle for the connection doing explain |
query_thd | thread handle for the connection being explained |
plan | table modification plan |
select | Query's select lex |
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.
|
static |
|
static |
Explain UNION or subqueries of the unit.
If the unit is a UNION, explain it as a UNION. Otherwise explain nested subselects.
explain_thd | thread handle for the connection doing explain |
query_thd | thread handle for the connection being explained |
unit | unit object, might not belong to ethd |
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.
|
static |
Generates either usual table name or <derived::N>, and passes it to any given function for showing to the user.
tr | Table reference |
fmt | EXPLAIN's format |
func | Function receiving the name |
|
static |
const char* join_type_str[] |
|
static |
First string: for regular EXPLAIN; second: for EXPLAIN CONNECTION.