mysql源代码解析经典类——sql解析Lex类
LEX对象当前具有三个不同的用途:
- 它包含SQL命令的一些通用属性,例如sql_command,数据更改语句语法中是否存在IGNORE以及表列表(query_tables)。
- 它包含一些执行状态变量,例如m_exec_started(开始执行时设置为true),插件(语句使用的插件列表),insert_update_values_map(某些INSERT语句使用的对象的映射)等。
- 它包含许多对Sql_cmd的子类来说是本地的成员,例如purge_value_list(对于PURGE命令),kill_value_list(对于KILL命令)。
对于由Sql_cmd类表示的SQL命令,LEX对象严格是Sql_cmd类的一部分。对于其余的SQL命令,它是链接到当前THD的独立对象。
LEX对象的生命周期如下:
- LEX对象可以在执行mem_root(对于常规语句),Prepared_statement mem_root(对于预处理语句),SP mem_root(对于存储过程指令)上构造,或者在当前mem_root上创建以用于短期使用。
- 在使用之前,调用lex_start()初始化LEX对象。这将初始化对象的执行状态部分。它还调用LEX :: reset()以确保正确初始化所有成员。
- 使用LEX作为工作区来解析并解析该语句。
- 执行一个SQL命令:开始执行时(实际上是开始优化时)调用set_exec_started()。通常,调用is_exec_started()来区分SQL命令执行的准备阶段和优化/执行阶段。
- 执行完成后,调用clear_execution()。这将清除与SQL命令关联的所有执行状态,还包括调用LEX :: reset_exec_started()。
- 其继承派生关系如下图:
公共类型
typedef Prealloced_array< plugin_ref, INITIAL_LEX_PLUGIN_LIST_SIZE > Plugins_array
//#####继承自Query_tables_list的公共类型
enum { START_SROUTINES_HASH_SIZE = 16 }
//该特定语句中表的锁定状态。
enum enum_lock_tables_state { LTS_NOT_LOCKED = 0, LTS_LOCKED }
//所有类型的不安全声明
enum enum_binlog_stmt_unsafe {
BINLOG_STMT_UNSAFE_LIMIT = 0, BINLOG_STMT_UNSAFE_SYSTEM_TABLE, BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS, BINLOG_STMT_UNSAFE_UDF,
BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE, BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION, BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS, BINLOG_STMT_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE,
BINLOG_STMT_UNSAFE_MIXED_STATEMENT, BINLOG_STMT_UNSAFE_INSERT_IGNORE_SELECT, BINLOG_STMT_UNSAFE_INSERT_SELECT_UPDATE, BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT,
BINLOG_STMT_UNSAFE_REPLACE_SELECT, BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT, BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT, BINLOG_STMT_UNSAFE_CREATE_SELECT_AUTOINC,
BINLOG_STMT_UNSAFE_UPDATE_IGNORE, BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS, BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST, BINLOG_STMT_UNSAFE_FULLTEXT_PLUGIN,
BINLOG_STMT_UNSAFE_SKIP_LOCKED, BINLOG_STMT_UNSAFE_NOWAIT, BINLOG_STMT_UNSAFE_XA, BINLOG_STMT_UNSAFE_DEFAULT_EXPRESSION_IN_SUBSTATEMENT,
BINLOG_STMT_UNSAFE_ACL_TABLE_READ_IN_DML_DDL, BINLOG_STMT_UNSAFE_COUNT
}
enum enum_stmt_accessed_table {
STMT_READS_TRANS_TABLE = 0, STMT_READS_NON_TRANS_TABLE, STMT_READS_TEMP_TRANS_TABLE, STMT_READS_TEMP_NON_TRANS_TABLE,
STMT_WRITES_TRANS_TABLE, STMT_WRITES_NON_TRANS_TABLE, STMT_WRITES_TEMP_TRANS_TABLE, STMT_WRITES_TEMP_NON_TRANS_TABLE,
STMT_ACCESS_TABLE_COUNT
}
公共成员函数
SELECT_LEX * current_select () const
void assert_ok_set_current_select ()
void set_current_select (SELECT_LEX *select)
bool is_explain () const
//在语句内找到具有给定名称的用户变量的赋值
bool locate_var_assignment (const Name_string &name)
void insert_values_map (Item_field *f1, Field *f2)
void destroy_values_map ()
void clear_values_map ()
bool has_values_map () const
std::map< Item_field *, Field * >::iterator begin_values_map ()
std::map< Item_field *, Field * >::iterator end_values_map ()
bool is_ignore () const
void set_ignore (bool ignore_param)
void set_has_udf ()
bool has_udf () const
//获取为此语句设置的选项
ulonglong statement_options ()
//将选项添加到m_statement_options的值
void add_statement_options (ulonglong options)
bool is_broken () const
//如果某些永久性转换(例如in2exists)失败,则可能会使LEX处于不一致状态。
void mark_broken (bool broken=true)
//检查准备好的语句的准备状态是否无效。
bool check_preparation_invalid (THD *thd)
void cleanup (THD *thd, bool full)
bool is_exec_started () const
void set_exec_started ()
void reset_exec_started ()
//检查该语句是否已执行(无论是否完成-成功还是错误)
bool is_exec_completed () const
void set_exec_completed ()
sp_pcontext * get_sp_current_parsing_ctx ()
void set_sp_current_parsing_ctx (sp_pcontext *ctx)
//检查当前语句是否使用元数据(使用表或存储的例程)。
bool is_metadata_used () const
LEX ()
virtual ~LEX ()
//销毁包含的对象,但不销毁LEX对象本身
void destroy ()
//将查询上下文重置为初始状态。
void reset ()
//在此LEX对象中创建一个空的查询块。
SELECT_LEX * new_empty_query_block ()
//创建包含一个查询块的查询表达式对象
SELECT_LEX * new_query (SELECT_LEX *curr_select)
//创建查询块并将其附加到当前查询表达式。
SELECT_LEX * new_union_query (SELECT_LEX *curr_select, bool distinct)
//是否创建顶级查询表达式和查询块。
bool new_top_level_query ()
//在现有内存对象中创建查询表达式和查询块
void new_static_query (SELECT_LEX_UNIT *sel_unit, SELECT_LEX *select)
//在current_select下创建查询表达式,并在新查询表达式下创建查询块。
SELECT_LEX_UNIT * create_query_expr_and_block (THD *thd, SELECT_LEX *current_select, Item *where_clause, Item *having_clause, enum_parsing_context ctx)
bool is_ps_or_view_context_analysis ()
bool is_view_context_analysis ()
//在准备或执行语句之后(再执行)之前,清除该语句的执行状态。
void clear_execution ()
//将当前查询设置为不可缓存。
void set_uncacheable (SELECT_LEX *curr_select, uint8 cause)
//在已使用表的列表中设置此TABLE_LIST对象的初始用途。
void set_trg_event_type_for_tables ()
TABLE_LIST * unlink_first_table (bool *link_to_local)
void link_first_table_back (TABLE_LIST *first, bool link_to_local)
void first_lists_tables_same ()
void restore_cmd_properties ()
void restore_properties_for_insert ()
bool save_cmd_properties (THD *thd)
//检查命令是否可以将VIEW与MERGE算法一起使用
bool can_use_merged ()
//检查命令是否在命令的任何部分都不能使用合并视图。
bool can_not_use_merged ()
bool need_correct_ident ()
bool which_check_option_applicable ()
void cleanup_after_one_table_open ()
bool push_context (Name_resolution_context *context)
void pop_context ()
//仅在解析期间应调用此方法。
bool copy_db_to (char const **p_db, size_t *p_db_length) const
bool copy_db_to (char **p_db, size_t *p_db_length) const
Name_resolution_context * current_context ()
void reset_n_backup_query_tables_list (Query_tables_list *backup)
void restore_backup_query_tables_list (Query_tables_list *backup)
bool table_or_sp_used ()
//检查该语句是否为单级联接
bool is_single_level_stmt ()
bool accept (Select_lex_visitor *visitor)
bool set_wild (LEX_STRING)
void clear_privileges ()
//使用parse_tree实例化Sql_cmd对象并将其分配给Lex
bool make_sql_cmd (Parse_tree_root *parse_tree)
//获取此语句的辅助引擎执行上下文。
Secondary_engine_execution_context * secondary_engine_execution_context () const
//设置此语句的辅助引擎执行上下文
void set_secondary_engine_execution_context (Secondary_engine_execution_context *context)
bool is_replication_deprecated_syntax_used ()
void set_replication_deprecated_syntax_used ()
//设置复制通道名称。
bool set_channel_name (LEX_CSTRING name={})
公有属性
//最外面的查询表达式
SELECT_LEX_UNIT * unit
//第一个查询块
SELECT_LEX * select_lex
//所有查询块列表
SELECT_LEX * all_selects_list
bool is_explain_analyze = false
LEX_STRING name
char * help_arg
char * to_log
const char * x509_subject
const char * x509_issuer
const char * ssl_cipher
String * wild
Query_result * result
//BINLOG事件语句的参数
LEX_STRING binlog_stmt_arg
LEX_STRING ident
LEX_USER * grant_user
LEX_ALTER alter_password
enum_alter_user_attribute alter_user_attribute
LEX_STRING alter_user_comment_text
LEX_GRANT_AS grant_as
THD * thd
Opt_hints_global * opt_hints_global
Plugins_array plugins
//将表插入(可能是视图)
TABLE_LIST * insert_table
//插入叶表(始终是基表)
TABLE_LIST * insert_table_leaf
//SELECT CREATE VIEW语句。
LEX_STRING create_view_select
partition_info * part_info
LEX_USER * definer
List< LEX_USER > users_list
List< LEX_COLUMN > columns
List< LEX_CSTRING > dynamic_privileges
List< LEX_USER > * default_roles
ulonglong bulk_insert_row_cnt
List< Item > purge_value_list
List< Item > kill_value_list
List< set_var_base > var_list
List< Item_func_set_user_var > set_var_list
//准备好的语句的参数的占位符('?')列表。
List< Item_param > param_list
List< Name_resolution_context > context_stack
Item_sum * in_sum_func
udf_func udf
HA_CHECK_OPT check_opt
HA_CREATE_INFO * create_info
KEY_CREATE_INFO key_create_info
LEX_MASTER_INFO mi
LEX_SLAVE_CONNECTION slave_connection
Server_options server_options
USER_RESOURCES mqh
LEX_RESET_SLAVE reset_slave_info
ulong type
//该字段在解析过程中用作工作字段,以验证聚合函数的使用
nesting_map allow_sum_func
//HAVING中不允许使用窗口函数(与组聚合相反),然后我们需要比allow_sum_func严格。
nesting_map m_deny_window_func
//如果为true:在准备过程中,我们进行了子查询转换(IN-to-EXISTS,SOME / ANY),该转换当前不适用于子查询到派生表转换。
bool m_subquery_to_derived_is_impossible
Sql_cmd * m_sql_cmd
bool expr_allows_subselect
//如果当前正在重新解析CTE的定义,则这是具有WITH子句的原始语句中该定义的偏移量(以字节为单位)。
uint reparse_common_table_expr_at
enum SSL_type ssl_type
enum enum_duplicates duplicates
enum enum_tx_isolation tx_isolation
enum enum_var_type option_type
enum_view_create_mode create_view_mode
//SHOW PROFILE的查询ID。
my_thread_id show_profile_query_id
uint profile_options
uint grant
uint grant_tot_col
bool grant_privilege
uint slave_thd_opt
uint start_transaction_opt
//查询块数(按EXPLAIN)
int select_number
uint8 create_view_algorithm
uint8 create_view_check
uint8 context_analysis_only
bool drop_if_exists
bool drop_temporary
bool autocommit
bool verbose
bool no_write_to_binlog
bool m_extended_show
enum enum_yes_no_unknown tx_chain tx_release
//给定不变的数据,此查询是否每次都会返回相同的答案。
bool safe_to_cache_query
st_parsing_options parsing_options
Alter_info * alter_info
LEX_CSTRING prepared_stmt_name
LEX_STRING prepared_stmt_code
bool prepared_stmt_code_is_varref
List< LEX_STRING > prepared_stmt_params
sp_head * sphead
sp_name * spname
bool sp_lex_in_use
bool all_privileges
bool contains_plaintext_password
enum_keep_diagnostics keep_diagnostics
uint32 next_binlog_file_nr
st_sp_chistics sp_chistics
Event_parse_data * event_parse_data
bool only_view
uint8 create_view_suid
//旨在在以下语句中指向DEFINER子句之后的下一个单词
const char * stmt_definition_begin
const char * stmt_definition_end
//在名称解析期间,仅在由Name_resolution_context :: first_name_resolution_table和Name_resolution_context :: last_name_resolution_table给出的表列表中搜索
bool use_only_table_context
bool is_lex_started
//解析ON DUPLICATE KEY UPDATE子句中的值时设置为true
bool in_update_value_clause
class Explain_format * explain_format
ulong max_execution_time
bool binlog_need_explicit_defaults_ts
//用于通知解析器是否应该上下文化解析树。
bool will_contextualize
//IS模式查询从SE读取一些动态表统计信息
dd::info_schema::Table_statistics m_IS_table_stats
dd::info_schema::Tablespace_statistics m_IS_tablespace_stats
私有属性
SELECT_LEX * m_current_select
std::map< Item_field *, Field * > * insert_update_values_map
//如果语句引用UDF函数,则为True
bool m_has_udf {false}
bool ignore
bool m_broken
//执行开始时设置为true(解析后,打开表并完成查询准备)
bool m_exec_started
//当执行完成(即优化已完成且执行成功或错误结束)时设置为true
bool m_exec_completed
//当前的SP解析上下文
sp_pcontext * sp_current_parsing_ctx
//SELECT_LEX :: make_active_options的语句上下文
ulonglong m_statement_options {0}
//辅助存储引擎用于优化和执行期间存储查询状态的上下文对象
Secondary_engine_execution_context * m_secondary_engine_context {nullptr}
bool m_is_replication_deprecated_syntax_used {false}
其他函数
//在要准备和执行的每个查询之前,请调用lex_start()。
bool lex_start (THD *thd)
static const char * stmt_accessed_table_string (enum_stmt_accessed_table accessed_table)
//设置了从0(含)到BINLOG_STMT_FLAG_COUNT(不含)的所有标志。
static const int BINLOG_STMT_UNSAFE_ALL_FLAGS
//将enum_binlog_stmt_unsafe的元素映射到错误代码
static const int binlog_stmt_unsafe_errcode [BINLOG_STMT_UNSAFE_COUNT]