当前位置: 首页 > news >正文

门户网站开发人员招聘信息移动网站视频主持人网

门户网站开发人员招聘信息,移动网站视频主持人网,自动发外链工具,上海前十名广告公司在 MySQL 8 的 C 源码中#xff0c;SQL 语句的解析过程涉及多个步骤#xff0c;包括词法分析、语法分析和抽象语法树#xff08;AST#xff09;的生成。以下是详细的解析过程和相关组件的描述#xff1a; 1. 词法分析器#xff08;Lexer#xff09; MySQL 使用一个称为…在 MySQL 8 的 C 源码中SQL 语句的解析过程涉及多个步骤包括词法分析、语法分析和抽象语法树AST的生成。以下是详细的解析过程和相关组件的描述 1. 词法分析器Lexer MySQL 使用一个称为 MYSQL_LEX 的类来进行词法分析。它负责将 SQL 查询字符串分解成一系列的标记tokens如关键字、标识符、操作符等。 在 dispatch_sql_command 函数中调用 parse_sql 函数开始解析过程这会触发词法分析器的工作。 2. 语法分析器Parser MySQL 的语法分析器基于 Bison 生成定义在 .y 文件中例如 sql_yacc.yy。这些文件定义了 SQL 语言的语法规则。 当词法分析器生成了一系列标记后语法分析器根据这些标记和预定义的语法规则构建抽象语法树AST。 3. 抽象语法树AST AST 是一种树形结构用于表示源代码的逻辑结构。在 MySQL 中AST 是由多个类组成的复杂数据结构主要由 LEX 和 Item 类家族来表示。 LEX 对象包含了整个查询的上下文信息包括但不限于表名、列名、表达式等。 Item 类及其子类用于表示查询中的各种元素如表达式、条件、值等。 解析流程 初始化 在 dispatch_sql_command 函数中首先调用了 lex_start(thd)这初始化了解析环境为接下来的词法和语法分析做好准备。 词法分析 调用 parse_sql(thd, parser_state, nullptr) 启动解析过程。这里parser_state 包含了当前解析状态的信息包括词法分析器的状态。 MYSQL_LEX 对象作为词法分析器的核心逐字符读取 SQL 查询并将其转换为标记序列。 语法分析 使用 Bison 生成的解析器根据词法分析器产生的标记序列按照 SQL 语法规则进行解析并构建出抽象语法树AST。 如果解析过程中遇到错误比如语法错误解析器会设置错误标志并返回相应的错误信息。 后续处理 解析完成后可能会对 AST 进行一些重写操作例如应用插件或执行特定的优化。 最终解析后的命令会被传递给查询执行引擎通过调用 mysql_execute_command来执行实际的操作。 关键代码行 触发词法和语法分析 cpp const bool mysql_parse_status thd-sql_parser(); 这行代码是关键点它触发了对输入 SQL 文本的解析过程其中包含了词法分析和语法分析两个阶段的工作。 调用解析器函数 cpp extern int my_sql_parser_parse(class THD *thd, class Parse_tree_root **root); 这行代码调用了由 YACC 从 sql_yacc.yy 生成的解析器函数 my_sql_parser_parse。这个函数负责执行 SQL 语句的词法分析和语法分析并构建出解析树parse tree。 总结 词法分析将 SQL 文本分割成标记识别出 SQL 语句中的各个组成部分。 语法分析根据 SQL 语言的语法规则检查这些标记并构造抽象语法树。 抽象语法树表示 SQL 查询的逻辑结构便于后续的查询优化和执行计划生成。 通过这些步骤MySQL 8 的 C 源码实现了从 SQL 文本到抽象语法树的转换为后续的查询优化和执行提供了基础。 ##词法分析器Lexer MySQL 8.0 源码中 词法分析器Lexer 的核心实现部分具体来说它是 my_sql_parser_lex 函数的实现。该函数是 MySQL 语法分析器由 Bison 生成的 词法分析接口负责从 SQL 语句中提取词法单元Token并将其传递给语法分析器。 以下是对这段代码的详细解析 1. 函数功能 my_sql_parser_lex 是 MySQL 语法分析器的词法分析接口它的主要功能是 从 SQL 语句中提取词法单元Token。 将词法单元的值和位置信息传递给语法分析器。 处理一些特殊情况如 WITH ROLLUP 语法。 2. 函数参数 cpp 复制 int my_sql_parser_lex(MY_SQL_PARSER_STYPE *yacc_yylval, POS *yylloc, THD *thd); yacc_yylval词法单元的值语义值传递给语法分析器。 yylloc词法单元的位置信息起始和结束位置。 thd当前线程的 THD 对象包含 SQL 语句的解析状态。 3. 代码解析 1初始化 cpp 复制 auto *yylval reinterpret_castLexer_yystype *(yacc_yylval); Lex_input_stream *lip thd-m_parser_state-m_lip; int token; yylval将 yacc_yylval 转换为 Lexer_yystype 类型用于存储词法单元的值。 lip获取当前 SQL 语句的输入流Lex_input_stream用于读取 SQL 语句。 token存储词法单元的类型Token 编号。 2错误处理 cpp 复制 if (thd-is_error()) {if (thd-get_parser_da()-has_sql_condition(ER_CAPACITY_EXCEEDED))return ABORT_SYM; } 如果当前线程thd存在错误并且错误是 ER_CAPACITY_EXCEEDED容量超出则返回 ABORT_SYM表示终止解析。 3处理预读的 Token cpp 复制 if (lip-lookahead_token 0) {token lip-lookahead_token;lip-lookahead_token -1;*yylval *(lip-lookahead_yylval);yylloc-cpp.start lip-get_cpp_tok_start();yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.start lip-get_tok_start();yylloc-raw.end lip-get_ptr();lip-lookahead_yylval nullptr;lip-add_digest_token(token, yylval);return token; } 如果存在预读的 Tokenlookahead_token 0则直接返回该 Token并清空预读状态。 lookahead_token用于处理需要预读的语法如 WITH ROLLUP。 4提取一个 Token cpp token lex_one_token(yylval, thd); yylloc-cpp.start lip-get_cpp_tok_start(); yylloc-raw.start lip-get_tok_start(); 调用 lex_one_token 函数从输入流中提取一个 Token。 记录 Token 的起始位置。 5处理特殊情况WITH ROLLUP cpp switch (token) {case WITH:token lex_one_token(yylval, thd);switch (token) {case ROLLUP_SYM:yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.end lip-get_ptr();lip-add_digest_token(WITH_ROLLUP_SYM, yylval);return WITH_ROLLUP_SYM;default:lip-lookahead_yylval lip-yylval;lip-yylval nullptr;lip-lookahead_token token;yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.end lip-get_ptr();lip-add_digest_token(WITH, yylval);return WITH;}break; } 如果当前 Token 是 WITH则需要预读下一个 Token 如果下一个 Token 是 ROLLUP_SYM则合并为 WITH_ROLLUP_SYM。 否则保存预读的 Token并返回 WITH。 6返回 Token cpp yylloc-cpp.end lip-get_cpp_ptr(); yylloc-raw.end lip-get_ptr(); if (!lip-skip_digest) lip-add_digest_token(token, yylval); lip-skip_digest false; return token; 记录 Token 的结束位置。 将 Token 添加到 SQL 语句的摘要Digest 中除非显式跳过。 返回提取的 Token。 4. 关键函数和数据结构 1lex_one_token 从输入流中提取一个 Token。 实现位于 sql/lex.cc 中。 2Lex_input_stream SQL 语句的输入流用于读取和解析 SQL 语句。 包含当前解析位置、Token 起始位置等信息。 3Lexer_yystype 词法单元的值类型用于存储 Token 的语义值。 4POS 词法单元的位置信息包括起始和结束位置。 5. 总结 my_sql_parser_lex 是 MySQL 词法分析器的核心函数负责从 SQL 语句中提取 Token 并传递给语法分析器。它的主要功能包括 提取 Token。 处理预读 Token。 处理特殊情况如 WITH ROLLUP。 记录 Token 的值和位置信息。 通过这种设计MySQL 能够高效地解析 SQL 语句并将其转换为语法分析器可以处理的 Token 流。 ##源码 /**Parse an SQL command from a text string and pass the resulting AST to thequery executor.param thd Current session.param parser_state Parser state. */void dispatch_sql_command(THD *thd, Parser_state *parser_state) {DBUG_TRACE;DBUG_PRINT(dispatch_sql_command, (query: %s, thd-query().str));statement_id_to_session(thd);DBUG_EXECUTE_IF(parser_debug, turn_parser_debug_on(););mysql_reset_thd_for_next_command(thd);// It is possible that rewritten query may not be empty (in case of// multiqueries). So reset it.thd-reset_rewritten_query();lex_start(thd);thd-m_parser_state parser_state;invoke_pre_parse_rewrite_plugins(thd);thd-m_parser_state nullptr;// we produce digest if its not explicitly turned off// by setting maximum digest length to zeroif (get_max_digest_length() ! 0)parser_state-m_input.m_compute_digest true;LEX *lex thd-lex;const char *found_semicolon nullptr;bool err thd-get_stmt_da()-is_error();size_t qlen 0;if (!err) {err parse_sql(thd, parser_state, nullptr);if (!err) err invoke_post_parse_rewrite_plugins(thd, false);found_semicolon parser_state-m_lip.found_semicolon;qlen found_semicolon ? (found_semicolon - thd-query().str): thd-query().length;/*We set thd-query_length correctly to not log several queries, when weexecute only first. We set it to not see the ; otherwise it would getinto binlog and Query_log_event::print() would give ;; output.*/if (!thd-is_error() found_semicolon (ulong)(qlen)) {thd-set_query(thd-query().str, qlen - 1);}}DEBUG_SYNC_C(sql_parse_before_rewrite);if (!err) {/*Rewrite the query for logging and for the Performance Schemastatement tables. (Raw logging happened earlier.)Sub-routines of mysql_rewrite_query() should try to only rewrite whennecessary (e.g. not do password obfuscation when query contains nopassword).If rewriting does not happen here, thd-m_rewritten_query is stillempty from being reset in alloc_query().*/if (thd-rewritten_query().length() 0) mysql_rewrite_query(thd);if (thd-rewritten_query().length()) {lex-safe_to_cache_query false; // see comments belowthd-set_query_for_display(thd-rewritten_query().ptr(),thd-rewritten_query().length());} else if (thd-slave_thread) {/*In the slave, we add the information to pfs.events_statements_history,but not to pfs.threads, as that is what the test suite expects.*/MYSQL_SET_STATEMENT_TEXT(thd-m_statement_psi, thd-query().str,thd-query().length);} else {thd-set_query_for_display(thd-query().str, thd-query().length);}if (!(opt_general_log_raw || thd-slave_thread)) {if (thd-rewritten_query().length())query_logger.general_log_write(thd, COM_QUERY,thd-rewritten_query().ptr(),thd-rewritten_query().length());else {query_logger.general_log_write(thd, COM_QUERY, thd-query().str, qlen);}}}const bool with_query_attributes (thd-bind_parameter_values_count 0);MYSQL_NOTIFY_STATEMENT_QUERY_ATTRIBUTES(thd-m_statement_psi,with_query_attributes);DEBUG_SYNC_C(sql_parse_after_rewrite);if (!err) {thd-m_statement_psi MYSQL_REFINE_STATEMENT(thd-m_statement_psi, sql_statement_info[thd-lex-sql_command].m_key);if (mqh_used thd-get_user_connect() check_mqh(thd, lex-sql_command)) {if (thd-is_classic_protocol())thd-get_protocol_classic()-get_net()-error NET_ERROR_UNSET;} else {if (!thd-is_error()) {/* Actually execute the query */if (found_semicolon) {lex-safe_to_cache_query false;thd-server_status | SERVER_MORE_RESULTS_EXISTS;}lex-set_trg_event_type_for_tables();int error [[maybe_unused]];if (unlikely((thd-security_context()-password_expired() ||thd-security_context()-is_in_registration_sandbox_mode()) lex-sql_command ! SQLCOM_SET_PASSWORD lex-sql_command ! SQLCOM_ALTER_USER)) {if (thd-security_context()-is_in_registration_sandbox_mode())my_error(ER_PLUGIN_REQUIRES_REGISTRATION, MYF(0));elsemy_error(ER_MUST_CHANGE_PASSWORD, MYF(0));error 1;} else {resourcegroups::Resource_group *src_res_grp nullptr;resourcegroups::Resource_group *dest_res_grp nullptr;MDL_ticket *ticket nullptr;MDL_ticket *cur_ticket nullptr;auto mgr_ptr resourcegroups::Resource_group_mgr::instance();const bool switched mgr_ptr-switch_resource_group_if_needed(thd, src_res_grp, dest_res_grp, ticket, cur_ticket);error mysql_execute_command(thd, true);if (switched)mgr_ptr-restore_original_resource_group(thd, src_res_grp,dest_res_grp);thd-resource_group_ctx()-m_switch_resource_group_str[0] \0;if (ticket ! nullptr)mgr_ptr-release_shared_mdl_for_resource_group(thd, ticket);if (cur_ticket ! nullptr)mgr_ptr-release_shared_mdl_for_resource_group(thd, cur_ticket);}}}} else {/*Log the failed raw query in the Performance Schema. This statement didnot parse, so there is no way to tell if it may contain a password of not.The tradeoff is:a) If we do log the query, a user typing by accident a broken querycontaining a password will have the password exposed. This is veryunlikely, and this behavior can be documented. Remediation is touse a new password when retyping the corrected query.b) If we do not log the query, finding broken queries in the clientapplication will be much more difficult. This is much more likely.Considering that broken queries can typically be generated by attempts atSQL injection, finding the source of the SQL injection is critical, so thedesign choice is to log the query text of broken queries (a).*/thd-set_query_for_display(thd-query().str, thd-query().length);/* Instrument this broken statement as statement/sql/error */thd-m_statement_psi MYSQL_REFINE_STATEMENT(thd-m_statement_psi, sql_statement_info[SQLCOM_END].m_key);assert(thd-is_error());DBUG_PRINT(info,(Command aborted. Fatal_error: %d, thd-is_fatal_error()));}THD_STAGE_INFO(thd, stage_freeing_items);sp_cache_enforce_limit(thd-sp_proc_cache, stored_program_cache_size);sp_cache_enforce_limit(thd-sp_func_cache, stored_program_cache_size);thd-lex-destroy();thd-end_statement();thd-cleanup_after_query();assert(thd-change_list.is_empty());DEBUG_SYNC(thd, query_rewritten); } ## /**Transform an SQL statement into an AST that is ready for resolving, using thesupplied parser state and object creation context.This is a wrapper() for THD::sql_parser() and should generally be used for ASTconstruction.The function may optionally generate a query digest, invoke this function asfollows:verbatimTHD *thd ...;const char *query_text ...;uint query_length ...;Object_creation_ctx *ctx ...;bool rc;Parser_state parser_state;if (parser_state.init(thd, query_text, query_length){... handle error}parser_state.m_input.m_has_digest true;parser_state.m_input.m_compute_digest true;rc parse_sql(the, parser_state, ctx);if (! rc){unsigned char md5[MD5_HASH_SIZE];char digest_text[1024];bool truncated;const sql_digest_storage *digest thd-m_digest-m_digest_storage;compute_digest_md5(digest, md5[0]);compute_digest_text(digest, digest_text[0], sizeof(digest_text), truncated);}endverbatimparam thd Thread context.param parser_state Parser state.param creation_ctx Object creation context.return Error status.retval false on success.retval true on parsing error. */bool parse_sql(THD *thd, Parser_state *parser_state,Object_creation_ctx *creation_ctx) {DBUG_TRACE;bool ret_value;assert(thd-m_parser_state nullptr);// TODO fix to allow parsing gcol exprs after main query.// assert(thd-lex-m_sql_cmd NULL);/* Backup creation context. */Object_creation_ctx *backup_ctx nullptr;if (creation_ctx) backup_ctx creation_ctx-set_n_backup(thd);/* Set parser state. */thd-m_parser_state parser_state;parser_state-m_digest_psi nullptr;parser_state-m_lip.m_digest nullptr;/*Partial parsers (GRAMMAR_SELECTOR_*) are not supposed to compute digests.*/assert(!parser_state-m_lip.is_partial_parser() ||!parser_state-m_input.m_has_digest);/*Only consider statements that are supposed to have a digest,like top level queries.*/if (parser_state-m_input.m_has_digest) {/*For these statements,see if the digest computation is required.*/if (thd-m_digest ! nullptr) {/* Start Digest */parser_state-m_digest_psi MYSQL_DIGEST_START(thd-m_statement_psi);if (parser_state-m_input.m_compute_digest ||(parser_state-m_digest_psi ! nullptr)) {/*If either:- the caller wants to compute a digest- the performance schema wants to compute a digestset the digest listener in the lexer.*/parser_state-m_lip.m_digest thd-m_digest;parser_state-m_lip.m_digest-m_digest_storage.m_charset_number thd-charset()-number;}}}/* Parse the query. *//*Use a temporary DA while parsing. We dont know until after parsingwhether the current command is a diagnostic statement, in which casewell need to have the previous DA around to answer questions about it.*/Diagnostics_area *parser_da thd-get_parser_da();Diagnostics_area *da thd-get_stmt_da();Parser_oom_handler poomh;// Note that we may be called recursively here, on INFORMATION_SCHEMA queries.thd-mem_root-set_max_capacity(thd-variables.parser_max_mem_size);thd-mem_root-set_error_for_capacity_exceeded(true);thd-push_internal_handler(poomh);thd-push_diagnostics_area(parser_da, false);const bool mysql_parse_status thd-sql_parser();thd-pop_internal_handler();thd-mem_root-set_max_capacity(0);thd-mem_root-set_error_for_capacity_exceeded(false);/*Unwind diagnostics area.If any issues occurred during parsing, they will becomethe sole conditions for the current statement.Otherwise, if we have a diagnostic statement on our hands,well preserve the previous diagnostics area here so wecan answer questions about it. This specifically meansthat repeatedly asking about a DA wont clear it.Otherwise, its a regular command with no issues duringparsing, so well just clear the DA in preparation forthe processing of this command.*/if (parser_da-current_statement_cond_count() ! 0) {/*Error/warning during parsing: top DA should contain parse error(s)! Anypre-existing conditions will be replaced. The exception is diagnosticsstatements, in which case we wish to keep the errors so they can be sentto the client.*/if (thd-lex-sql_command ! SQLCOM_SHOW_WARNS thd-lex-sql_command ! SQLCOM_GET_DIAGNOSTICS)da-reset_condition_info(thd);/*We need to put any errors in the DA as well as the condition list.*/if (parser_da-is_error() !da-is_error()) {da-set_error_status(parser_da-mysql_errno(), parser_da-message_text(),parser_da-returned_sqlstate());}da-copy_sql_conditions_from_da(thd, parser_da);parser_da-reset_diagnostics_area();parser_da-reset_condition_info(thd);/*Do not clear the condition list when starting execution as itnow contains not the results of the previous executions, buta non-zero number of errors/warnings thrown during parsing!*/thd-lex-keep_diagnostics DA_KEEP_PARSE_ERROR;}thd-pop_diagnostics_area();/*Check that if THD::sql_parser() failed either thd-is_error() is set, or aninternal error handler is set.The assert will not catch a situation where parsing fails without anerror reported if an error handler exists. The problem is that theerror handler might have intercepted the error, so thd-is_error() isnot set. However, there is no way to be 100% sure here (the errorhandler might be for other errors than parsing one).*/assert(!mysql_parse_status || (mysql_parse_status thd-is_error()) ||(mysql_parse_status thd-get_internal_handler()));/* Reset parser state. */thd-m_parser_state nullptr;/* Restore creation context. */if (creation_ctx) creation_ctx-restore_env(thd, backup_ctx);/* Thats it. */ret_value mysql_parse_status || thd-is_fatal_error();if ((ret_value 0) (parser_state-m_digest_psi ! nullptr)) {/*On parsing success, record the digest in the performance schema.*/assert(thd-m_digest ! nullptr);MYSQL_DIGEST_END(parser_state-m_digest_psi,thd-m_digest-m_digest_storage);}return ret_value; } ## /**Call parser to transform statement into a parse tree.Then, transform the parse tree further into an AST, ready for resolving. */ bool THD::sql_parser() {/*SQL parser function generated by YACC from sql_yacc.yy.In the case of success returns 0, and THD::is_error() is false.Otherwise returns 1, or THD::is_error() is true.The second (output) parameter root returns the new parse tree.It is undefined (unchanged) on error. If root is NULL on success,then the parser has already called lex-make_sql_cmd() internally.*/extern int my_sql_parser_parse(class THD * thd,class Parse_tree_root * *root);Parse_tree_root *root nullptr;if (my_sql_parser_parse(this, root) || is_error()) {/*Restore the original LEX if it was replaced when parsinga stored procedure. We must ensure that a parsing errordoes not leave any side effects in the THD.*/cleanup_after_parse_error();return true;}if (root ! nullptr lex-make_sql_cmd(root)) {return true;}return false; } ##词法分析部分源码 /**yylex() function implementation for the main parserparam [out] yacc_yylval semantic value of the token being parsed (yylval)param [out] yylloc location of the token being parsed (yylloc)param thd THDreturn token numbernotemy_sql_parser_lex remember the following states from thefollowing my_sql_parser_lex():- MY_LEX_END Found end of query */int my_sql_parser_lex(MY_SQL_PARSER_STYPE *yacc_yylval, POS *yylloc, THD *thd) {auto *yylval reinterpret_castLexer_yystype *(yacc_yylval);Lex_input_stream *lip thd-m_parser_state-m_lip;int token;if (thd-is_error()) {if (thd-get_parser_da()-has_sql_condition(ER_CAPACITY_EXCEEDED))return ABORT_SYM;}if (lip-lookahead_token 0) {/*The next token was already parsed in advance,return it.*/token lip-lookahead_token;lip-lookahead_token -1;*yylval *(lip-lookahead_yylval);yylloc-cpp.start lip-get_cpp_tok_start();yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.start lip-get_tok_start();yylloc-raw.end lip-get_ptr();lip-lookahead_yylval nullptr;lip-add_digest_token(token, yylval);return token;}token lex_one_token(yylval, thd);yylloc-cpp.start lip-get_cpp_tok_start();yylloc-raw.start lip-get_tok_start();switch (token) {case WITH:/*Parsing WITH ROLLUP requires 2 look ups,which makes the grammar LALR(2).Replace by a single WITH_ROLLUP token,to transform the grammar into a LALR(1) grammar,which sql_yacc.yy can process.*/token lex_one_token(yylval, thd);switch (token) {case ROLLUP_SYM:yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.end lip-get_ptr();lip-add_digest_token(WITH_ROLLUP_SYM, yylval);return WITH_ROLLUP_SYM;default:/*Save the token following WITH*/lip-lookahead_yylval lip-yylval;lip-yylval nullptr;lip-lookahead_token token;yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.end lip-get_ptr();lip-add_digest_token(WITH, yylval);return WITH;}break;}yylloc-cpp.end lip-get_cpp_ptr();yylloc-raw.end lip-get_ptr();if (!lip-skip_digest) lip-add_digest_token(token, yylval);lip-skip_digest false;return token; } ##/home/yym/mysql8/mysql-8.1.0/sql/sql_yacc.cc #define yyparse         my_sql_parser_parse #define yylex           my_sql_parser_lex ##语法树给命令行赋值 MySQL 8.0 源码中与 SQL 解析和执行相关的部分主要涉及 LEX 结构和 Sql_cmd 对象的创建和赋值过程。以下是对代码的详细解析 1. LEX::make_sql_cmd 函数 cpp 复制 bool LEX::make_sql_cmd(Parse_tree_root *parse_tree) {if (!will_contextualize) return false;m_sql_cmd parse_tree-make_cmd(thd);if (m_sql_cmd nullptr) return true;assert(m_sql_cmd-sql_command_code() sql_command);return false; } 功能 该函数的作用是通过解析树Parse_tree_root创建一个 Sql_cmd 对象并将其赋值给 LEX 结构中的 m_sql_cmd 成员。 Sql_cmd 是一个基类表示一个 SQL 命令的具体实现。不同的 SQL 命令如 SELECT、INSERT 等会有对应的派生类如 Sql_cmd_select、Sql_cmd_insert 等。 参数 parse_tree解析树的根节点表示一个 SQL 语句的抽象语法树AST。 逻辑 will_contextualize 检查 如果 will_contextualize 为 false则直接返回 false表示不需要进一步处理。 这个标志通常用于控制是否需要将解析树转换为 Sql_cmd 对象。 创建 Sql_cmd 对象 调用 parse_tree-make_cmd(thd)通过解析树创建对应的 Sql_cmd 对象。 如果创建失败返回 nullptr则返回 true表示出错。 断言检查 使用 assert 检查 m_sql_cmd-sql_command_code() 是否与 sql_command 一致。 这一步确保创建的 Sql_cmd 对象的命令类型与 LEX 中记录的 sql_command 一致。 返回值 如果成功创建 Sql_cmd 对象并赋值则返回 false表示成功。 如果失败则返回 true。 2. PT_select_stmt::make_cmd 函数 cpp 复制 Sql_cmd *PT_select_stmt::make_cmd(THD *thd) {Parse_context pc(thd, thd-lex-current_query_block());thd-lex-sql_command m_sql_command;if (m_qe-contextualize(pc)) {return nullptr;}const bool has_into_clause_inside_query_block thd-lex-result ! nullptr;if (has_into_clause_inside_query_block m_into ! nullptr) {my_error(ER_MULTIPLE_INTO_CLAUSES, MYF(0));return nullptr;}if (contextualize_safe(pc, m_into)) {return nullptr;}if (pc.finalize_query_expression()) return nullptr;if (m_into ! nullptr m_has_trailing_locking_clauses) {// Example: ... INTO ... FOR UPDATE;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);} else if (has_into_clause_inside_query_block thd-lex-unit-is_set_operation()) {// Example: ... UNION ... INTO ...;if (!m_qe-has_trailing_into_clause()) {// Example: ... UNION SELECT * INTO OUTFILE foo FROM ...;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);} else if (m_has_trailing_locking_clauses) {// Example: ... UNION SELECT ... FROM ... INTO OUTFILE foo FOR UPDATE;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);}}return new (thd-mem_root) Sql_cmd_select(thd-lex); } 功能 该函数是 PT_select_stmt 类的一个方法用于为 SELECT 语句创建一个 Sql_cmd_select 对象。 PT_select_stmt 是 SELECT 语句的解析树节点。 参数 thd当前线程的 THD 对象包含线程相关的上下文信息。 逻辑 初始化 Parse_context 创建一个 Parse_context 对象 pc用于管理解析过程中的上下文信息。 thd-lex-current_query_block() 获取当前查询块Query_block。 设置 sql_command 将 thd-lex-sql_command 设置为 m_sql_command。 m_sql_command 是 PT_select_stmt 的成员变量表示当前 SQL 命令的类型如 SQLCOM_SELECT。 上下文化查询表达式 调用 m_qe-contextualize(pc)对查询表达式进行上下文化处理。 如果失败则返回 nullptr。 检查 INTO 子句 检查是否存在多个 INTO 子句如果存在则报错ER_MULTIPLE_INTO_CLAUSES。 调用 contextualize_safe(pc, m_into)对 INTO 子句进行上下文化处理。 完成查询表达式 调用 pc.finalize_query_expression()完成查询表达式的处理。 如果失败则返回 nullptr。 处理警告 如果存在 INTO 子句和锁子句如 FOR UPDATE则发出警告ER_WARN_DEPRECATED_INNER_INTO。 对于 UNION 查询中的 INTO 子句也会发出警告。 创建 Sql_cmd_select 对象 使用 thd-mem_root 分配内存创建一个 Sql_cmd_select 对象。 返回该对象。 3. 关键点总结 sql_command 的赋值 在 PT_select_stmt::make_cmd 中thd-lex-sql_command 被赋值为 m_sql_command。 这个赋值发生在解析树转换为 Sql_cmd 对象的过程中。 Sql_cmd 的创建 Sql_cmd 对象是通过解析树Parse_tree_root创建的。 对于 SELECT 语句会创建 Sql_cmd_select 对象。 上下文化处理 在创建 Sql_cmd 对象之前需要对解析树进行上下文化处理contextualize以确保所有语法元素都被正确解析和处理。 错误处理 如果解析或上下文化过程中出现错误函数会返回 nullptr并在适当的情况下抛出错误或警告。 4. 代码的作用 这段代码的核心作用是将解析树Parse_tree_root转换为具体的 Sql_cmd 对象并将其与 LEX 结构关联起来。这是 SQL 解析和执行的关键步骤之一确保 SQL 语句能够被正确解析并执行。 ##源码 /**Uses parse_tree to instantiate an Sql_cmd object and assigns it to the Lex.param parse_tree The parse tree.returns false on success, true on error. */ bool LEX::make_sql_cmd(Parse_tree_root *parse_tree) {if (!will_contextualize) return false;m_sql_cmd parse_tree-make_cmd(thd);if (m_sql_cmd nullptr) return true;assert(m_sql_cmd-sql_command_code() sql_command);return false; }Sql_cmd *PT_select_stmt::make_cmd(THD *thd) {Parse_context pc(thd, thd-lex-current_query_block());thd-lex-sql_command m_sql_command;if (m_qe-contextualize(pc)) {return nullptr;}const bool has_into_clause_inside_query_block thd-lex-result ! nullptr;if (has_into_clause_inside_query_block m_into ! nullptr) {my_error(ER_MULTIPLE_INTO_CLAUSES, MYF(0));return nullptr;}if (contextualize_safe(pc, m_into)) {return nullptr;}if (pc.finalize_query_expression()) return nullptr;if (m_into ! nullptr m_has_trailing_locking_clauses) {// Example: ... INTO ... FOR UPDATE;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);} else if (has_into_clause_inside_query_block thd-lex-unit-is_set_operation()) {// Example: ... UNION ... INTO ...;if (!m_qe-has_trailing_into_clause()) {// Example: ... UNION SELECT * INTO OUTFILE foo FROM ...;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);} else if (m_has_trailing_locking_clauses) {// Example: ... UNION SELECT ... FROM ... INTO OUTFILE foo FOR UPDATE;push_warning(thd, ER_WARN_DEPRECATED_INNER_INTO);}}DBUG_EXECUTE_IF(ast, Query_term *qn pc.select-master_query_expression()-query_term();std::ostringstream buf; qn-debugPrint(0, buf);DBUG_PRINT(ast, (\n%s, buf.str().c_str())););if (thd-lex-sql_command SQLCOM_SELECT)return new (thd-mem_root) Sql_cmd_select(thd-lex-result);else // (thd-lex-sql_command SQLCOM_DO)return new (thd-mem_root) Sql_cmd_do(nullptr); }##gdb #0 yyparse () at /home/yym/mysql8/mysql-8.1.0/build/storage/innobase/pars0grm.cc:1409 #1 0x000057cc696f0864 in pars_sql (info0x78341c0e0cb8,str0x57cc6ba8f5a8 PROCEDURE FETCH_STATS () IS\nfound INT;\nDECLARE FUNCTION fetch_table_stats_step;\nDECLARE FUNCTION fetch_index_stats_step;\nDECLARE CURSOR table_stats_cur IS\n SELECT\n n_rows,\n clustered_index_size,\n ...) at /home/yym/mysql8/mysql-8.1.0/storage/innobase/pars/pars0pars.cc:1706 #2 0x000057cc696f7747 in que_eval_sql (info0x78341c0e0cb8,sql0x57cc6ba8f5a8 PROCEDURE FETCH_STATS () IS\nfound INT;\nDECLARE FUNCTION fetch_table_stats_step;\nDECLARE FUNCTION fetch_index_stats_step;\nDECLARE CURSOR table_stats_cur IS\n SELECT\n n_rows,\n clustered_index_size,\n ..., trx0x7834be600ff8) at /home/yym/mysql8/mysql-8.1.0/storage/innobase/que/que0que.cc:1049 #3 0x000057cc69a9d370 in dict_stats_fetch_from_ps (table0x78341c0fd1f8) at /home/yym/mysql8/mysql-8.1.0/storage/innobase/dict/dict0stats.cc:2723 #4 0x000057cc69a9d8be in dict_stats_update (table0x78341c0c5988, stats_upd_optionDICT_STATS_FETCH_ONLY_IF_NOT_IN_MEMORY)at /home/yym/mysql8/mysql-8.1.0/storage/innobase/dict/dict0stats.cc:2907 #5 0x000057cc694b0e5e in dict_stats_init (table0x78341c0c5988) at /home/yym/mysql8/mysql-8.1.0/storage/innobase/include/dict0stats.ic:159 #6 0x000057cc694c1e06 in ha_innobase::open (this0x78341c0c6450, name0x78341c032d78 ./grey/o2o_hot_marketing, open_flags2, table_def0x78341c09d668)at /home/yym/mysql8/mysql-8.1.0/storage/innobase/handler/ha_innodb.cc:7324 #7 0x000057cc67fe7cb9 in handler::ha_open (this0x78341c0c6450, table_arg0x78341c0a6e20, name0x78341c032d78 ./grey/o2o_hot_marketing, mode2, test_if_locked2,table_def0x78341c09d668) at /home/yym/mysql8/mysql-8.1.0/sql/handler.cc:2796 #8 0x000057cc67d6dfa4 in open_table_from_share (thd0x78341c000c40, share0x78341c0329c0, alias0x78341c025918 o2o_hot_marketing, db_stat39, prgflag8, ha_open_flags0,outparam0x78341c0a6e20, is_create_tablefalse, table_def_param0x78341c09d668) at /home/yym/mysql8/mysql-8.1.0/sql/table.cc:3213 #9 0x000057cc67a8b2d8 in open_table (thd0x78341c000c40, table_list0x78341c025930, ot_ctx0x7834bebfb700) at /home/yym/mysql8/mysql-8.1.0/sql/sql_base.cc:3413 #10 0x000057cc67a8f208 in open_and_process_table (thd0x78341c000c40, lex0x78341c010260, tables0x78341c025930, counter0x7834bebfb7dc, prelocking_strategy0x7834bebfb780,has_prelocking_listfalse, ot_ctx0x7834bebfb700) at /home/yym/mysql8/mysql-8.1.0/sql/sql_base.cc:5090 #11 0x000057cc67a90d82 in open_tables (thd0x78341c000c40, start0x78341c010270, counter0x7834bebfb7dc, flags0, prelocking_strategy0x7834bebfb780)at /home/yym/mysql8/mysql-8.1.0/sql/sql_base.cc:5912 #12 0x000057cc67a9ecb4 in open_tables (thd0x78341c000c40, tables0x78341c010270, counter0x7834bebfb7dc, flags0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_base.h:453 #13 0x000057cc67ca2a6c in mysql_create_table (thd0x78341c000c40, create_table0x78341c025930, create_info0x7834bebfc2a0, alter_info0x7834bebfc3e0)at /home/yym/mysql8/mysql-8.1.0/sql/sql_table.cc:10068 #14 0x000057cc6839b239 in Sql_cmd_create_table::execute (this0x78341c028c78, thd0x78341c000c40) at /home/yym/mysql8/mysql-8.1.0/sql/sql_cmd_ddl_table.cc:435 #15 0x000057cc67bbdfbb in mysql_execute_command (thd0x78341c000c40, first_leveltrue) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:3736 #16 0x000057cc67bc3cb3 in dispatch_sql_command (thd0x78341c000c40, parser_state0x7834bebfd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447 #17 0x000057cc67bb90d7 in dispatch_command (thd0x78341c000c40, com_data0x7834bebfe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #18 0x000057cc67bb6f77 in do_command (thd0x78341c000c40) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #19 0x000057cc67e0e835 in handle_connection (arg0x57cca10e5ca0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #20 0x000057cc69d4dbdc in pfs_spawn_thread (arg0x57cca0dc1ea0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #21 0x00007834cd694ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #22 0x00007834cd726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 ##gdb (gdb) bt #0 my_sql_parser_parse (YYTHD0x78341c000c40, parse_tree0x7834bebfd710) at /var/lib/pb2/sb_1-11858416-1687334106.05/dist_GPL/sql/sql_yacc.cc:25429 #1 0x000057cc67abb61c in THD::sql_parser (this0x78341c000c40) at /home/yym/mysql8/mysql-8.1.0/sql/sql_class.cc:3073 #2 0x000057cc67bc8985 in parse_sql (thd0x78341c000c40, parser_state0x7834bebfd9f0, creation_ctx0x0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:7213 #3 0x000057cc67bc36ae in dispatch_sql_command (thd0x78341c000c40, parser_state0x7834bebfd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5344 #4 0x000057cc67bb90d7 in dispatch_command (thd0x78341c000c40, com_data0x7834bebfe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #5 0x000057cc67bb6f77 in do_command (thd0x78341c000c40) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #6 0x000057cc67e0e835 in handle_connection (arg0x57cca10e5ca0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #7 0x000057cc69d4dbdc in pfs_spawn_thread (arg0x57cca0dc1ea0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #8 0x00007834cd694ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #9 0x00007834cd726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 (gdb) list 25424 | yyparse. | 25425 ----------*/ 25426 25427 int 25428 yyparse (class THD *YYTHD, class Parse_tree_root **parse_tree) 25429 { 25430 /* The lookahead symbol. */ 25431 int yychar; 25432 25433 (gdb) p YYTHD-query().str $1 0x78341c015040 CREATE TABLE o2o_hot_marketing (\n id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID,\n name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 活动名称,... (gdb) ##词法分析gdb堆栈信息  (gdb) bt #0 my_sql_parser_lex (yacc_yylval0x7607825fb960, yylloc0x7607825fb980, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_lex.cc:1356 #1 0x000060fe1444b23f in my_sql_parser_parse (YYTHD0x76069c001070, parse_tree0x7607825fd710) at /var/lib/pb2/sb_1-11858416-1687334106.05/dist_GPL/sql/sql_yacc.cc:25622 #2 0x000060fe140d161c in THD::sql_parser (this0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_class.cc:3073 #3 0x000060fe141de985 in parse_sql (thd0x76069c001070, parser_state0x7607825fd9f0, creation_ctx0x0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:7213 #4 0x000060fe141d96ae in dispatch_sql_command (thd0x76069c001070, parser_state0x7607825fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5344 #5 0x000060fe141cf0d7 in dispatch_command (thd0x76069c001070, com_data0x7607825fe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #6 0x000060fe141ccf77 in do_command (thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #7 0x000060fe14424835 in handle_connection (arg0x60fe5942f6a0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #8 0x000060fe16363bdc in pfs_spawn_thread (arg0x60fe5942eae0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #9 0x0000760791494ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #10 0x0000760791526850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 (gdb) p thd-query().str $15 0x76069c0ad510 select * from o2o_boss_order_detail\n LIMIT 0, 1000 ##执行命令 #0 mysql_execute_command (thd0x76069c001070, first_leveltrue) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2990 #1 0x000060fe141d9cb3 in dispatch_sql_command (thd0x76069c001070, parser_state0x7607825fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447 #2 0x000060fe141cf0d7 in dispatch_command (thd0x76069c001070, com_data0x7607825fe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #3 0x000060fe141ccf77 in do_command (thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #4 0x000060fe14424835 in handle_connection (arg0x60fe5942f6a0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #5 0x000060fe16363bdc in pfs_spawn_thread (arg0x60fe5942eae0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #6 0x0000760791494ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #7 0x0000760791526850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 ##通过语法树给sql命令行赋值 #0 PT_select_stmt::make_cmd (this0x76069c01e1a8, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/parse_tree_nodes.cc:750 #1 0x000060fe14188761 in LEX::make_sql_cmd (this0x76069c004650, parse_tree0x76069c01e1a8) at /home/yym/mysql8/mysql-8.1.0/sql/sql_lex.cc:5032 #2 0x000060fe140d1676 in THD::sql_parser (this0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_class.cc:3082 #3 0x000060fe141de985 in parse_sql (thd0x76069c001070, parser_state0x7607825fd9f0, creation_ctx0x0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:7213 #4 0x000060fe141d96ae in dispatch_sql_command (thd0x76069c001070, parser_state0x7607825fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5344 #5 0x000060fe141cf0d7 in dispatch_command (thd0x76069c001070, com_data0x7607825fe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #6 0x000060fe141ccf77 in do_command (thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #7 0x000060fe14424835 in handle_connection (arg0x60fe5942f6a0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #8 0x000060fe16363bdc in pfs_spawn_thread (arg0x60fe5942eae0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #9 0x0000760791494ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #10 0x0000760791526850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 ##发送网络数据包 (gdb) b /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1785 (gdb) bt #0 Protocol_classic::end_row (this0x76069c0052e0) at /home/yym/mysql8/mysql-8.1.0/sql/protocol_classic.cc:3364 #1 0x000060fe1492ded3 in Query_result_send::send_data (this0x76069cbbe118, thd0x76069c001070, items...) at /home/yym/mysql8/mysql-8.1.0/sql/query_result.cc:108 #2 0x000060fe14324ef0 in Query_expression::ExecuteIteratorQuery (this0x76069cb9eb70, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1785 #3 0x000060fe14325181 in Query_expression::execute (this0x76069cb9eb70, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1823 #4 0x000060fe14265cf6 in Sql_cmd_dml::execute_inner (this0x76069cbbe0e0, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:1022 #5 0x000060fe14265067 in Sql_cmd_dml::execute (this0x76069cbbe0e0, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:793 #6 0x000060fe141d7841 in mysql_execute_command (thd0x76069c001070, first_leveltrue) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:4797 #7 0x000060fe141d9cb3 in dispatch_sql_command (thd0x76069c001070, parser_state0x7607825fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447 #8 0x000060fe141cf0d7 in dispatch_command (thd0x76069c001070, com_data0x7607825fe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #9 0x000060fe141ccf77 in do_command (thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #10 0x000060fe14424835 in handle_connection (arg0x60fe5942f6a0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #11 0x000060fe16363bdc in pfs_spawn_thread (arg0x60fe5942eae0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #12 0x0000760791494ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #13 0x0000760791526850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81(gdb) bt #0 my_net_write (net0x76069c002ea8,packet0x76069c015210 \aioshd61\006\061.1.45\002\066\061\023\062\060\062\062-06-22 10:27:00https://gangan-test1.oss-cn-beijing.aliyuncs.com/wgt-new.html\001\071\001\061\001\060\001\061\n指定包1\373\001\060\373\373a/ios/fxbhd.plist\001\066\001\061\001\060\001\061\374\001更新包大小112.81M|更新内容:|1、, incomplete sequence \351..., len124) at /home/yym/mysql8/mysql-8.1.0/sql-common/net_serv.cc:435 #1 0x000060fe1492aeab in Protocol_classic::end_row (this0x76069c0052e0) at /home/yym/mysql8/mysql-8.1.0/sql/protocol_classic.cc:3366 #2 0x000060fe1492ded3 in Query_result_send::send_data (this0x76069cbbe118, thd0x76069c001070, items...) at /home/yym/mysql8/mysql-8.1.0/sql/query_result.cc:108 #3 0x000060fe14324ef0 in Query_expression::ExecuteIteratorQuery (this0x76069cb9eb70, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1785 #4 0x000060fe14325181 in Query_expression::execute (this0x76069cb9eb70, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1823 #5 0x000060fe14265cf6 in Sql_cmd_dml::execute_inner (this0x76069cbbe0e0, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:1022 #6 0x000060fe14265067 in Sql_cmd_dml::execute (this0x76069cbbe0e0, thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:793 #7 0x000060fe141d7841 in mysql_execute_command (thd0x76069c001070, first_leveltrue) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:4797 #8 0x000060fe141d9cb3 in dispatch_sql_command (thd0x76069c001070, parser_state0x7607825fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447 #9 0x000060fe141cf0d7 in dispatch_command (thd0x76069c001070, com_data0x7607825fe340, commandCOM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112 #10 0x000060fe141ccf77 in do_command (thd0x76069c001070) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459 #11 0x000060fe14424835 in handle_connection (arg0x60fe5942f6a0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303 #12 0x000060fe16363bdc in pfs_spawn_thread (arg0x60fe5942eae0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043 #13 0x0000760791494ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442 #14 0x0000760791526850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
http://www.w-s-a.com/news/171096/

相关文章:

  • 优秀网站主题平顶山专业做网站公司
  • wordpress返回顶部插件wordpress站群seo
  • 企业网站建设报价表百度竞价托管哪家好
  • 织梦网站首页打开慢淄博网站推广那家好
  • 苏州高端网站建设kgwl互动网站建设的主页
  • 宿州网站建设哪家公司好个人网站制作方法
  • 网站正能量晚上在线观看视频站长之家关键词挖掘工具
  • 建设网站怎么判断是电脑还是手机仿租号网站源码网站开发
  • seo百度网站排名软件重庆巫山网站设计公司
  • 搭建视频播放网站网站排名诊断
  • 网站域名注册网站centos做网站服务器
  • 网站服务器共享的 vpsh5页面制作软件电脑版
  • 免费手机网站申请上海网站建设设计公司哪家好
  • 站长工具大全企业网上书店网站建设设计
  • 做网站的专业公司公司网站是做的谷歌的
  • 做网站前期工作wordpress图片并排
  • 免费注册网站哪个好wordpress评论修改
  • 合肥模板网站建设软件赤峰公司网站建设
  • 毕业设计都是做网站吗深圳网站制作企业邮箱
  • 网站排名 优帮云小规模公司简介怎么写
  • 那个做头像的网站好选择手机网站建设
  • 设计一个网站花多少时间做视频网站适合用什么服务器
  • asp网站开发环境订单系统单页面网站怎么做
  • 山东网站建设都有那些企业推广策略
  • 网站开发文档是什么概念衣服销售网站建设规划书范文
  • 中国建筑装饰网官网企业网站设计优化公司
  • 南海建设工程交易中心网站c2c交易平台有哪些?
  • 有没有专业做网站架构图的软件番禺建设网站哪个好
  • 建立网站第一步整站seo优化公司
  • php网站开发文章管理系统wordpress 评论 顶踩 心 插件