Skip to content

Commit

Permalink
MDEV-27306: SET STATEMENT optimizer_trace=1 Doesn't save the trace
Browse files Browse the repository at this point in the history
In mysql_execute_command(), move optimizer trace initialization to be
after run_set_statement_if_requested() call.

Unfortunately, mysql_execute_command() code uses "goto error" a lot, and
this means optimizer trace code cannot use RAII objects. Work this around
by:
- Make Opt_trace_start a non-RAII object, add init() method.
- Move the code that writes the top-level object and array into
  Opt_trace_start::init().
  • Loading branch information
spetrunia committed Dec 19, 2021
1 parent 946dafb commit 3269214
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 26 deletions.
17 changes: 17 additions & 0 deletions mysql-test/main/opt_trace.result
Original file line number Diff line number Diff line change
Expand Up @@ -9248,5 +9248,22 @@ json_detailed(json_extract(trace, '$**.best_join_order'))
]
]
DROP TABLE t1;
#
# MDEV-27306: SET STATEMENT optimizer_trace=1 Doesn't save the trace
#
set optimizer_trace=0;
set statement optimizer_trace=1 for select * from seq_1_to_10 where seq<2;
seq
1
# The trace must not be empty:
select left(trace, 100) from information_schema.optimizer_trace;
left(trace, 100)
{
"steps": [
{
"join_preparation": {
"select_id": 1,
"steps": [

# End of 10.6 tests
set optimizer_trace='enabled=off';
8 changes: 8 additions & 0 deletions mysql-test/main/opt_trace.test
Original file line number Diff line number Diff line change
Expand Up @@ -865,5 +865,13 @@ select json_detailed(json_extract(trace, '$**.best_join_order'))
from information_schema.OPTIMIZER_TRACE;
DROP TABLE t1;

--echo #
--echo # MDEV-27306: SET STATEMENT optimizer_trace=1 Doesn't save the trace
--echo #
set optimizer_trace=0;
set statement optimizer_trace=1 for select * from seq_1_to_10 where seq<2;
--echo # The trace must not be empty:
select left(trace, 100) from information_schema.optimizer_trace;

--echo # End of 10.6 tests
set optimizer_trace='enabled=off';
20 changes: 14 additions & 6 deletions sql/opt_trace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,14 @@ void Opt_trace_context::end()
current_trace= NULL;
}

Opt_trace_start::Opt_trace_start(THD *thd, TABLE_LIST *tbl,
enum enum_sql_command sql_command,
List<set_var_base> *set_vars,
const char *query,
size_t query_length,
const CHARSET_INFO *query_charset):ctx(&thd->opt_trace)

void Opt_trace_start::init(THD *thd,
TABLE_LIST *tbl,
enum enum_sql_command sql_command,
List<set_var_base> *set_vars,
const char *query,
size_t query_length,
const CHARSET_INFO *query_charset)
{
/*
if optimizer trace is enabled and the statment we have is traceable,
Expand All @@ -496,13 +498,19 @@ Opt_trace_start::Opt_trace_start(THD *thd, TABLE_LIST *tbl,
ctx->set_query(query, query_length, query_charset);
traceable= TRUE;
opt_trace_disable_if_no_tables_access(thd, tbl);
Json_writer *w= ctx->get_current_json();
w->start_object();
w->add_member("steps").start_array();
}
}

Opt_trace_start::~Opt_trace_start()
{
if (traceable)
{
Json_writer *w= ctx->get_current_json();
w->end_array();
w->end_object();
ctx->end();
traceable= FALSE;
}
Expand Down
18 changes: 11 additions & 7 deletions sql/opt_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,18 @@ struct Opt_trace_info
*/


class Opt_trace_start {
class Opt_trace_start
{
public:
Opt_trace_start(THD *thd_arg, TABLE_LIST *tbl,
enum enum_sql_command sql_command,
List<set_var_base> *set_vars,
const char *query,
size_t query_length,
const CHARSET_INFO *query_charset);
Opt_trace_start(THD *thd_arg): ctx(&thd_arg->opt_trace), traceable(false) {}

void init(THD *thd, TABLE_LIST *tbl,
enum enum_sql_command sql_command,
List<set_var_base> *set_vars,
const char *query,
size_t query_length,
const CHARSET_INFO *query_charset);

~Opt_trace_start();

private:
Expand Down
7 changes: 3 additions & 4 deletions sql/sp_head.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3489,10 +3489,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
thd->lex->safe_to_cache_query= 0;
#endif

Opt_trace_start ots(thd, m_lex->query_tables,
SQLCOM_SELECT, &m_lex->var_list,
NULL, 0,
thd->variables.character_set_client);
Opt_trace_start ots(thd);
ots.init(thd, m_lex->query_tables, SQLCOM_SELECT, &m_lex->var_list,
NULL, 0, thd->variables.character_set_client);

Json_writer_object trace_command(thd);
Json_writer_array trace_command_steps(thd, "steps");
Expand Down
11 changes: 5 additions & 6 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3644,12 +3644,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
#ifdef HAVE_REPLICATION
} /* endif unlikely slave */
#endif
Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list,
thd->query(), thd->query_length(),
thd->variables.character_set_client);

Json_writer_object trace_command(thd);
Json_writer_array trace_command_steps(thd, "steps");
Opt_trace_start ots(thd);

/* store old value of binlog format */
enum_binlog_format orig_binlog_format,orig_current_stmt_binlog_format;
Expand Down Expand Up @@ -3715,6 +3710,10 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
if (run_set_statement_if_requested(thd, lex))
goto error;

/* After SET STATEMENT is done, we can initialize the Optimizer Trace: */
ots.init(thd, all_tables, lex->sql_command, &lex->var_list, thd->query(),
thd->query_length(), thd->variables.character_set_client);

if (thd->lex->mi.connection_name.str == NULL)
thd->lex->mi.connection_name= thd->variables.default_master_connection;

Expand Down
6 changes: 3 additions & 3 deletions sql/sql_prepare.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2437,9 +2437,9 @@ static bool check_prepared_statement(Prepared_statement *stmt)
For the optimizer trace, this is the symmetric, for statement preparation,
of what is done at statement execution (in mysql_execute_command()).
*/
Opt_trace_start ots(thd, tables, lex->sql_command, &lex->var_list,
thd->query(), thd->query_length(),
thd->variables.character_set_client);
Opt_trace_start ots(thd);
ots.init(thd, tables, lex->sql_command, &lex->var_list, thd->query(),
thd->query_length(), thd->variables.character_set_client);

Json_writer_object trace_command(thd);
Json_writer_array trace_command_steps(thd, "steps");
Expand Down

0 comments on commit 3269214

Please sign in to comment.