| 1157 | */ |
| 1158 | |
| 1159 | void mysql_parse(THD *thd, char *rawbuf, uint length, |
| 1160 | Parser_state *parser_state) |
| 1161 | { |
| 1162 | int error __attribute__((unused)); |
| 1163 | DBUG_ENTER("mysql_parse"); |
| 1164 | |
| 1165 | DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); |
| 1166 | |
| 1167 | /* |
| 1168 | Warning. |
| 1169 | The purpose of query_cache_send_result_to_client() is to lookup the |
| 1170 | query in the query cache first, to avoid parsing and executing it. |
| 1171 | So, the natural implementation would be to: |
| 1172 | - first, call query_cache_send_result_to_client, |
| 1173 | - second, if caching failed, initialise the lexical and syntactic parser. |
| 1174 | The problem is that the query cache depends on a clean initialization |
| 1175 | of (among others) lex->safe_to_cache_query and thd->server_status, |
| 1176 | which are reset respectively in |
| 1177 | - lex_start() |
| 1178 | - mysql_reset_thd_for_next_command() |
| 1179 | So, initializing the lexical analyser *before* using the query cache |
| 1180 | is required for the cache to work properly. |
| 1181 | FIXME: cleanup the dependencies in the code to simplify this. |
| 1182 | */ |
| 1183 | lex_start(thd); |
| 1184 | mysql_reset_thd_for_next_command(thd); |
| 1185 | |
| 1186 | //if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) |
| 1187 | { |
| 1188 | LEX *lex= thd->lex; |
| 1189 | |
| 1190 | bool err= parse_sql(thd, parser_state, NULL); |
| 1191 | |
| 1192 | const char *found_semicolon= parser_state->m_lip.found_semicolon; |
| 1193 | |
| 1194 | if (!err) |
| 1195 | { |
| 1196 | { |
| 1197 | if (! thd->is_error()) |
| 1198 | { |
| 1199 | /* |
| 1200 | Binlog logs a string starting from thd->query and having length |
| 1201 | thd->query_length; so we set thd->query_length correctly (to not |
| 1202 | log several statements in one event, when we executed only first). |
| 1203 | We set it to not see the ';' (otherwise it would get into binlog |
| 1204 | and Query_log_event::print() would give ';;' output). |
| 1205 | This also helps display only the current query in SHOW |
| 1206 | PROCESSLIST. |
| 1207 | Note that we don't need LOCK_thread_count to modify query_length. |
| 1208 | */ |
| 1209 | if (found_semicolon && (ulong) (found_semicolon - thd->query())) |
| 1210 | thd->set_query_inner(thd->query(), |
| 1211 | (uint32) (found_semicolon - |
| 1212 | thd->query() - 1), |
| 1213 | thd->charset()); |
| 1214 | /* Actually execute the query */ |
| 1215 | if (found_semicolon) |
| 1216 | { |
no test coverage detected