MySQL 8.4.3
Source Code Documentation
opt_trace.h File Reference

API for the Optimizer trace (WL#5257) More...

#include <limits.h>
#include <string.h>
#include <sys/types.h>
#include "my_compiler.h"
#include "my_inttypes.h"
#include "my_sqlcommand.h"
#include "sql/opt_trace_context.h"

Go to the source code of this file.

Classes

struct  Opt_trace_info
 User-visible information about a trace. More...
 
class  Opt_trace_iterator
 Iterator over the list of remembered traces. More...
 
class  Opt_trace_struct
 Object and array are both "structured data" and have lots in common, so the Opt_trace_struct is a base class for them. More...
 
class  Opt_trace_object
 A JSON object (unordered set of key/value pairs). More...
 
class  Opt_trace_array
 A JSON array (ordered set of values). More...
 
class  Opt_trace_disable_I_S
 Instantiate an instance of this class for specific cases where optimizer trace, in a certain section of Optimizer code, should write only to DBUG and not I_S. More...
 
class  Opt_trace_start
 

Helpers connecting the optimizer trace to THD or Information Schema.

#define OPT_TRACE_TRANSFORM(trace, object_level0, object_level1, select_number, from, to)
 Helper for defining query-transformation-related trace objects in one code line. More...
 
void opt_trace_print_expanded_query (const THD *thd, Query_block *query_block, Opt_trace_object *trace_object)
 Prints SELECT query to optimizer trace. More...
 
void opt_trace_disable_if_no_security_context_access (THD *thd)
 If the security context is not that of the connected user, inform the trace system that a privilege is missing. More...
 
void opt_trace_disable_if_no_view_access (THD *thd, Table_ref *view, Table_ref *underlying_tables)
 If tracing is on, checks additional privileges for a view, to make sure that the user has the right to do SHOW CREATE VIEW. More...
 
void opt_trace_disable_if_no_stored_proc_func_access (THD *thd, sp_head *sp)
 If tracing is on, checks additional privileges on a stored routine, to make sure that the user has the right to do SHOW CREATE PROCEDURE/FUNCTION. More...
 
int fill_optimizer_trace_info (THD *thd, Table_ref *tables, Item *)
 Fills information_schema.OPTIMIZER_TRACE with rows (one per trace) More...
 

Detailed Description

API for the Optimizer trace (WL#5257)

Macro Definition Documentation

◆ OPT_TRACE_TRANSFORM

#define OPT_TRACE_TRANSFORM (   trace,
  object_level0,
  object_level1,
  select_number,
  from,
  to 
)
Value:
const Opt_trace_object object_level0(trace); \
Opt_trace_object object_level1(trace, "transformation"); \
object_level1.add_select_number(select_number); \
object_level1.add_alnum("from", from).add_alnum("to", to);
A JSON object (unordered set of key/value pairs).
Definition: opt_trace.h:802

Helper for defining query-transformation-related trace objects in one code line.

This produces { "transformation": { "select#": <select_number>, "from": <from>, "to": <to> The objects are left open, so that one can add more to them (often a "chosen" property after making some computation). Objects get closed when going out of scope as usual.

Parameters
traceoptimizer trace
object_level0name of the outer Opt_trace_object C++ object
object_level1name of the inner Opt_trace_object C++ object
select_numbernumber of the being-transformed Query_block
fromdescription of the before-transformation state
todescription of the after-transformation state

Function Documentation

◆ fill_optimizer_trace_info()

int fill_optimizer_trace_info ( THD thd,
Table_ref tables,
Item  
)

Fills information_schema.OPTIMIZER_TRACE with rows (one per trace)

Return values
0ok
1error

◆ opt_trace_disable_if_no_security_context_access()

void opt_trace_disable_if_no_security_context_access ( THD thd)

If the security context is not that of the connected user, inform the trace system that a privilege is missing.

With one exception: see below.

Parameters
thdthe THD

This serves to eliminate the following issue. Any information readable by a SELECT may theoretically end up in the trace. And a SELECT may read information from other places than tables:

  • from views (reading their bodies)
  • from stored routines (reading their bodies)
  • from files (reading their content), with LOAD_FILE()
  • from the list of connections (reading their queries...), with I_S.PROCESSLIST. If the connected user has EXECUTE privilege on a routine which does a security context change, the routine can retrieve information internally (if allowed by the SUID context's privileges), and present only a portion of it to the connected user. But with tracing on, all information is possibly in the trace. So the connected user receives more information than the routine's definer intended to provide. Fixing this issue would require adding, near many privilege checks in the server, a new optimizer-trace-specific check done against the connected user's context, to verify that the connected user has the right to see the retrieved information.

Instead, our chosen simpler solution is that if we see a security context change where SUID user is not the connected user, we disable tracing. With only one safe exception: if the connected user has all global privileges (because then she/he can find any information anyway). By "all global privileges" we mean everything but WITH GRANT OPTION (that latter one isn't related to information gathering).

Read access to I_S.OPTIMIZER_TRACE by another user than the connected user is restricted:

See also
fill_optimizer_trace_info().

◆ opt_trace_disable_if_no_stored_proc_func_access()

void opt_trace_disable_if_no_stored_proc_func_access ( THD thd,
sp_head sp 
)

If tracing is on, checks additional privileges on a stored routine, to make sure that the user has the right to do SHOW CREATE PROCEDURE/FUNCTION.

For that, we use the same checks as in those SHOW commands. If a privilege is missing, notifies the trace system.

This function is not redundant with opt_trace_disable_if_no_security_context_access(). Indeed, for a SQL SECURITY INVOKER routine, there is no context change, but we must still verify that the invoker can do SHOW CREATE.

For triggers, see note in sp_head::execute_trigger().

Parameters
thdThe THD
sproutine to check

◆ opt_trace_disable_if_no_view_access()

void opt_trace_disable_if_no_view_access ( THD thd,
Table_ref view,
Table_ref underlying_tables 
)

If tracing is on, checks additional privileges for a view, to make sure that the user has the right to do SHOW CREATE VIEW.

For that:

  • this function checks SHOW VIEW
  • SELECT is tested in opt_trace_disable_if_no_tables_access()
  • SELECT + SHOW VIEW is sufficient for SHOW CREATE VIEW. We also check underlying tables. If a privilege is missing, notifies the trace system. This function should be called when the view's underlying tables have not yet been merged.
Parameters
thdTHD context
viewview to check
underlying_tablesunderlying tables/views of 'view'

◆ opt_trace_print_expanded_query()

void opt_trace_print_expanded_query ( const THD thd,
Query_block query_block,
Opt_trace_object trace_object 
)

Prints SELECT query to optimizer trace.

It is not the original query (as in Opt_trace_context::set_query()) but a printout of the parse tree (Item-s).

Parameters
thdthe THD
query_blockquery's parse tree
trace_objectOpt_trace_object to which the query will be added

It's hard to prove that Query_block::print() doesn't modify any of its Item-s in a dangerous way. Item_int::print(), for example, modifies its internal str_value. To make the danger rare, we print the expanded query as rarely as possible: only if I_S output is needed. If only –debug is on, we don't print it. See also the corresponding call to "set_items_ref_array" at end of JOIN::exec().