| 7865 | */ |
| 7866 | |
| 7867 | void mysql_parse(THD *thd, char *rawbuf, uint length, |
| 7868 | Parser_state *parser_state) |
| 7869 | { |
| 7870 | DBUG_ENTER("mysql_parse"); |
| 7871 | DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_MYSQLparse();); |
| 7872 | DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_ORAparse();); |
| 7873 | |
| 7874 | /* |
| 7875 | Warning. |
| 7876 | The purpose of query_cache_send_result_to_client() is to lookup the |
| 7877 | query in the query cache first, to avoid parsing and executing it. |
| 7878 | So, the natural implementation would be to: |
| 7879 | - first, call query_cache_send_result_to_client, |
| 7880 | - second, if caching failed, initialise the lexical and syntactic parser. |
| 7881 | The problem is that the query cache depends on a clean initialization |
| 7882 | of (among others) lex->safe_to_cache_query and thd->server_status, |
| 7883 | which are reset respectively in |
| 7884 | - lex_start() |
| 7885 | - THD::reset_for_next_command() |
| 7886 | So, initializing the lexical analyser *before* using the query cache |
| 7887 | is required for the cache to work properly. |
| 7888 | FIXME: cleanup the dependencies in the code to simplify this. |
| 7889 | */ |
| 7890 | lex_start(thd); |
| 7891 | thd->reset_for_next_command(); |
| 7892 | |
| 7893 | if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) |
| 7894 | { |
| 7895 | LEX *lex= thd->lex; |
| 7896 | |
| 7897 | bool err= parse_sql(thd, parser_state, NULL, true); |
| 7898 | |
| 7899 | if (likely(!err)) |
| 7900 | { |
| 7901 | thd->m_statement_psi= |
| 7902 | MYSQL_REFINE_STATEMENT(thd->m_statement_psi, |
| 7903 | sql_statement_info[thd->lex->sql_command]. |
| 7904 | m_key); |
| 7905 | #ifndef NO_EMBEDDED_ACCESS_CHECKS |
| 7906 | if (mqh_used && thd->user_connect && |
| 7907 | check_mqh(thd, lex->sql_command)) |
| 7908 | { |
| 7909 | thd->net.error = 0; |
| 7910 | } |
| 7911 | else |
| 7912 | #endif |
| 7913 | { |
| 7914 | if (likely(! thd->is_error())) |
| 7915 | { |
| 7916 | const char *found_semicolon= parser_state->m_lip.found_semicolon; |
| 7917 | /* |
| 7918 | Binlog logs a string starting from thd->query and having length |
| 7919 | thd->query_length; so we set thd->query_length correctly (to not |
| 7920 | log several statements in one event, when we executed only first). |
| 7921 | We set it to not see the ';' (otherwise it would get into binlog |
| 7922 | and Query_log_event::print() would give ';;' output). |
| 7923 | This also helps display only the current query in SHOW |
| 7924 | PROCESSLIST. |
no test coverage detected