summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc126
1 files changed, 102 insertions, 24 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5a4f3ad0907..011fc3e9347 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -598,6 +598,7 @@ static void handle_bootstrap_impl(THD *thd)
#if defined(ENABLED_PROFILING)
thd->profiling.finish_current_query();
#endif
+ delete_qpf_query(thd->lex);
if (bootstrap_error)
break;
@@ -807,7 +808,9 @@ bool do_command(THD *thd)
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
DBUG_ASSERT(packet_length);
+ DBUG_ASSERT(!thd->apc_target.is_enabled());
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
+ DBUG_ASSERT(!thd->apc_target.is_enabled());
out:
DBUG_RETURN(return_value);
@@ -1117,6 +1120,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
log_slow_statement(thd);
+ DBUG_ASSERT(!thd->apc_target.is_enabled());
/* Remove garbage at start of query */
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
@@ -1489,6 +1493,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->update_all_stats();
log_slow_statement(thd);
+ /* psergey-todo: this is the place we could print EXPLAIN to slow query log */
thd_proc_info(thd, "cleaning up");
thd->reset_query();
@@ -1524,6 +1529,8 @@ void log_slow_statement(THD *thd)
{
DBUG_ENTER("log_slow_statement");
+ delete_qpf_query(thd->lex);
+
/*
The following should never be true with our current code base,
but better to keep this here so we don't accidently try to log a
@@ -1532,6 +1539,7 @@ void log_slow_statement(THD *thd)
if (unlikely(thd->in_sub_stmt))
DBUG_VOID_RETURN; // Don't set time for sub stmt
+
/* Follow the slow log filter configuration. */
if (!thd->enable_slow_log ||
(thd->variables.log_slow_filter
@@ -2185,6 +2193,8 @@ mysql_execute_command(THD *thd)
/* Release metadata locks acquired in this transaction. */
thd->mdl_context.release_transactional_locks();
}
+
+ create_qpf_query(thd->lex, thd->mem_root);
#ifndef DBUG_OFF
if (lex->sql_command != SQLCOM_SET_OPTION)
@@ -3265,7 +3275,8 @@ end_with_restore_list:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
- multi_delete *del_result;
+ bool explain= test(lex->describe);
+ select_result *result;
if ((res= multi_delete_precheck(thd, all_tables)))
break;
@@ -3280,37 +3291,80 @@ end_with_restore_list:
if ((res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
break;
- MYSQL_MULTI_DELETE_START(thd->query());
+ if (!explain)
+ {
+ MYSQL_MULTI_DELETE_START(thd->query());
+ }
+
if ((res= mysql_multi_delete_prepare(thd)))
{
- MYSQL_MULTI_DELETE_DONE(1, 0);
+ if (!explain)
+ {
+ MYSQL_MULTI_DELETE_DONE(1, 0);
+ }
goto error;
}
- if (!thd->is_fatal_error &&
- (del_result= new multi_delete(aux_tables, lex->table_count)))
- {
- res= mysql_select(thd, &select_lex->ref_pointer_array,
- select_lex->get_table_list(),
- select_lex->with_wild,
- select_lex->item_list,
- select_lex->where,
- 0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
- (ORDER *)NULL,
- (select_lex->options | thd->variables.option_bits |
- SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
- OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
- del_result, unit, select_lex);
- res|= thd->is_error();
- MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
- if (res)
- del_result->abort_result_set();
- delete del_result;
+ if (!thd->is_fatal_error)
+ {
+ if (explain)
+ {
+ result= new select_send();
+ if (thd->send_explain_fields(result))
+ {
+ delete result;
+ result= NULL;
+ }
+ select_lex->set_explain_type(FALSE);
+ //thd->lex->query_plan_footprint= new QPF_query;
+ }
+ else
+ result= new multi_delete(aux_tables, lex->table_count);
+
+ if (result)
+ {
+ res= mysql_select(thd, &select_lex->ref_pointer_array,
+ select_lex->get_table_list(),
+ select_lex->with_wild,
+ select_lex->item_list,
+ select_lex->where,
+ 0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
+ (ORDER *)NULL,
+ (select_lex->options | thd->variables.option_bits |
+ SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
+ OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
+ result, unit, select_lex);
+ res|= thd->is_error();
+
+ if (!explain)
+ {
+ MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
+ }
+ else
+ {
+ result->reset_offset_limit();
+ thd->lex->query_plan_footprint->print_explain(result, thd->lex->describe);
+ //delete thd->lex->query_plan_footprint;
+ //thd->lex->query_plan_footprint= NULL;
+ }
+
+ if (res)
+ result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
+ else
+ {
+ if (explain)
+ result->send_eof();
+ }
+ delete result;
+ }
}
else
{
res= TRUE; // Error
- MYSQL_MULTI_DELETE_DONE(1, 0);
+ if (!explain)
+ {
+ MYSQL_MULTI_DELETE_DONE(1, 0);
+ }
}
break;
}
@@ -4743,8 +4797,14 @@ finish:
ha_maria::implicit_commit(thd, FALSE);
#endif
}
-
lex->unit.cleanup();
+ //psergey-todo: print EXPLAIN here? After the above JOIN::cleanup calls?
+ // how do we print EXPLAIN extended, then?
+ if (lex->describe)
+ {
+ DBUG_ASSERT(lex->query_plan_footprint);
+ ///..
+ }
/* Free tables */
thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
@@ -4819,7 +4879,25 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
if (!(result= new select_send()))
return 1; /* purecov: inspected */
thd->send_explain_fields(result);
+ //thd->lex->query_plan_footprint= new QPF_query;
res= mysql_explain_union(thd, &thd->lex->unit, result);
+
+ if (!res)
+ {
+ /*
+ Do like the original select_describe did: remove OFFSET from the
+ top-level LIMIT
+ */
+ result->reset_offset_limit();
+ thd->lex->query_plan_footprint->print_explain(result, thd->lex->describe);
+ }
+ //delete thd->lex->query_plan_footprint;
+ //thd->lex->query_plan_footprint= NULL;
+
+ //psergey-todo: here, produce the EXPLAIN output.
+ // mysql_explain_union() itself is only responsible for calling
+ // optimize() for all parts of the query.
+
/*
The code which prints the extended description is not robust
against malformed queries, so skip it if we have an error.