MySQL 8.4.0
Source Code Documentation
opt_trace.h
Go to the documentation of this file.
1/* Copyright (c) 2011, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef OPT_TRACE_INCLUDED
25#define OPT_TRACE_INCLUDED
26
27#include <limits.h>
28#include <string.h>
29#include <sys/types.h>
30
31#include "my_compiler.h"
32#include "my_inttypes.h"
33#include "my_sqlcommand.h" // enum_sql_command
34#include "sql/opt_trace_context.h" // Opt_trace_context
35
36class Cost_estimate;
37class Item;
38class THD;
39class set_var_base;
40class sp_head;
41class sp_printable;
42struct CHARSET_INFO;
43class Table_ref;
44template <class T>
45class List;
46
47/**
48 @file sql/opt_trace.h
49 API for the Optimizer trace (WL#5257)
50*/
51
52/**
53 @page PAGE_OPT_TRACE The Optimizer Trace
54
55 @section INTRODUCTION Introduction
56
57 This optimizer trace is aimed at producing output, which is readable by
58 humans and by programs, to aid understanding of decisions and actions taken
59 by the MySQL Optimizer.
60
61 @section OUTPUT_FORMAT Output format
62
63 The chosen output format is JSON (JavaScript Object Notation).
64 In JSON there are:
65 @li "objects" (unordered set of key-value pairs); equivalent to Python's
66 dictionary or Perl's associative array or hash or STL's hash_map.
67 @li "arrays" (ordered set of values); equivalent to Python's and Perl's list
68 or STL's vector.
69 @li "values": a value can be a string, number, boolean, null,
70 which we all call "scalars", or be an object, array.
71
72 For example (explanations after "<<" are not part of output):
73@verbatim
74 { << start of top object
75 "first_name": "Gustave", << key/value pair (value is string)
76 "last_name": "Eiffel", << key/value pair (value is string)
77 "born": 1832, << key/value pair (value is integer)
78 "contributions_to": [ << key/value pair (value is array)
79 { << 1st item of array is an object (a building)
80 "name": "Eiffel tower",
81 "location": Paris
82 }, << end of 1st item of array
83 {
84 "name": "Liberty statue",
85 "location": "New York"
86 } << end of 2nd item of array
87 ] << end of array
88 } << end of top object
89@endverbatim
90 For more details, have a look at the syntax at json.org.
91 Note that indentation and newlines are superfluous, useful only for
92 human-readability.
93 Note also that there is nothing like a "named object": an object, array or
94 value has no name; but if it is the value of a key/value pair in an
95 enclosing, outer object, then the key can be seen as the inner object's
96 "name".
97
98 @section USER_ENABLE_TRACING How a user enables/views the trace
99
100@verbatim
101 SET SESSION OPTIMIZER_TRACE="enabled=on"; # enable tracing
102 <statement to trace>; # like SELECT, EXPLAIN SELECT, UPDATE, DELETE...
103 SELECT * FROM information_schema.OPTIMIZER_TRACE;
104 [ repeat last two steps at will ]
105 SET SESSION OPTIMIZER_TRACE="enabled=off"; # disable tracing
106@endverbatim
107
108 @c SELECT and @c EXPLAIN SELECT produce the same trace. But there are
109 exceptions regarding subqueries because the two commands treat subqueries
110 differently, for example in
111@verbatim
112 SELECT ... WHERE x IN (subq1) AND y IN (subq2)
113@endverbatim
114 SELECT terminates after executing the first subquery if the related IN
115 predicate is false, so we won't see @c JOIN::optimize() tracing for subq2;
116 whereas EXPLAIN SELECT analyzes all subqueries (see loop at the end of
117 @c select_describe()).
118
119 @section USER_SELECT_TRACING_STATEMENTS How a user traces only certain
120statements
121
122 When tracing is in force, each SQL statement generates a trace; more
123 exactly, so does any of
124 SELECT,
125 EXPLAIN SELECT,
126 INSERT or REPLACE ( with VALUES or SELECT),
127 UPDATE/DELETE and their multi-table variants,
128 SET (unless it manipulates @@@@optimizer_trace),
129 DO,
130 DECLARE/CASE/IF/RETURN (stored routines language elements),
131 CALL.
132 If a command above is prepared and executed in separate steps, preparation
133 and execution are separately traced.
134 By default each new trace overwrites the previous trace. Thus, if a
135 statement contains sub-statements (example: invokes stored procedures,
136 stored functions, triggers), the top statement and sub-statements each
137 generate traces, but at the execution's end only the last sub-statement's
138 trace is visible.
139 If the user wants to see the trace of another sub-statement, she/he can
140 enable/disable tracing around the desired sub-statement, but this requires
141 editing the routine's code, which may not be possible. Another solution is
142 to use
143@verbatim
144 SET optimizer_trace_offset=<OFFSET>, optimizer_trace_limit=<LIMIT>
145@endverbatim
146 where OFFSET is a signed integer, and LIMIT is a positive integer.
147 The effect of this SET is the following:
148
149 @li all remembered traces are cleared
150
151 @li a later SELECT on OPTIMIZER_TRACE returns the first LIMIT traces of
152 the OFFSET oldest remembered traces (if OFFSET >= 0), or the first LIMIT
153 traces of the -OFFSET newest remembered traces (if OFFSET < 0).
154
155 For example,
156 a combination of OFFSET=-1 and LIMIT=1 will make the last trace be shown (as
157 is default), OFFSET=-2 and LIMIT=1 will make the next-to-last be shown,
158 OFFSET=-5 and LIMIT=5 will make the last five traces be shown. Such negative
159 OFFSET can be useful when one knows that the interesting sub-statements are
160 the few last ones of a stored routine, like this:
161@verbatim
162 SET optimizer_trace_offset=-5, optimizer_trace_limit=5;
163 CALL stored_routine(); # more than 5 sub-statements in this routine
164 SELECT * FROM information_schema.OPTIMIZER_TRACE; # see only last 5 traces
165@endverbatim
166 On the opposite, a positive OFFSET can be useful when one knows that the
167 interesting sub-statements are the few first ones of a stored routine.
168
169 The more those two variables are accurately adjusted, the less memory is
170 used. For example, OFFSET=0 and LIMIT=5 will use memory to remember 5
171 traces, so if only the three first are needed, OFFSET=0 and LIMIT=3 is
172 better (tracing stops after the LIMITth trace, so the 4th and 5th trace are
173 not created and don't take up memory). A stored routine may have a loop
174 which executes many sub-statements and thus generates many traces, which
175 would use a lot of memory; proper OFFSET and LIMIT can restrict tracing to
176 one iteration of the loop for example. This also gains speed, as tracing a
177 sub-statement impacts performance.
178
179 If OFFSET>=0, only LIMIT traces are kept in memory. If OFFSET<0, that is not
180 true: instead, (-OFFSET) traces are kept in memory; indeed even if LIMIT is
181 smaller than (-OFFSET), so excludes the last statement, the last statement
182 must still be traced because it will be inside LIMIT after executing one
183 more statement (remember than OFFSET<0 is counted from the end: the "window"
184 slides as more statements execute).
185
186 Such memory and speed gains are the reason why optimizer_trace_offset/limit,
187 which are restrictions at the trace producer level, are offered. They are
188 better than using
189@verbatim
190 SELECT * FROM OPTIMIZER_TRACE LIMIT <LIMIT> OFFSET <OFFSET>;
191@endverbatim
192 which is a restriction on the trace consumer level, which saves almost
193 nothing.
194
195 @section USER_SELECT_TRACING_FEATURES How a user traces only certain
196 optimizer features
197
198@verbatim
199 SET OPTIMIZER_TRACE_FEATURES="feature1=on|off,...";
200@endverbatim
201 where "feature1" is one optimizer feature. For example "greedy_search": a
202 certain Opt_trace_array at the start of @c
203 Optimize_table_order::choose_table_order() has a flag "GREEDY_SEARCH" passed
204 to its constructor: this means that if the user has turned tracing of greedy
205 search off, this array will not be written to the I_S trace, neither will
206 any children structures. All this disabled "trace chunk" will be replaced by
207 an ellipsis "...".
208
209 @section DEV_ADDS_TRACING How a developer adds tracing to a function
210
211 Check @c Opt_trace* usage in @c advance_sj_state():
212
213@verbatim
214 Opt_trace_array trace_choices(trace, "semijoin_strategy_choice");
215@endverbatim
216
217 This creates an array for key "semijoin_strategy_choice". We are going to
218 list possible semijoin strategy choices.
219
220@verbatim
221 Opt_trace_object trace_one_strategy(trace);
222@endverbatim
223
224 This creates an object without key (normal, it's in an array). This
225 object will describe one single strategy choice.
226
227@verbatim
228 trace_one_strategy.add_alnum("strategy", "FirstMatch");
229@endverbatim
230
231 This adds a key/value pair to the just-created object: key is "strategy",
232 value is "FirstMatch". This is the strategy to be described in the
233 just-created object.
234
235@verbatim
236 trace_one_strategy.add("cost", *current_read_time).
237 add("records", *current_record_count);
238 trace_one_strategy.add("chosen", (pos->sj_strategy == SJ_OPT_FIRST_MATCH));
239@endverbatim
240
241 This adds 3 key/value pairs: cost of strategy, number of records produced
242 by this strategy, and whether this strategy is chosen.
243
244 After that, there is similar code for other semijoin strategies.
245
246 The resulting trace piece (seen in @c information_schema.OPTIMIZER_TRACE) is
247@verbatim
248 "semijoin_strategy_choice": [
249 {
250 "strategy": "FirstMatch",
251 "cost": 1,
252 "records": 1,
253 "chosen": true
254 },
255 {
256 "strategy": "DuplicatesWeedout",
257 "cost": 1.1,
258 "records": 1,
259 "duplicate_tables_left": false,
260 "chosen": false
261 }
262 ]
263@endverbatim
264
265 For more output examples, check result files of the opt_trace suite in
266 @c mysql-test.
267
268 Feature can be un-compiled with @code cmake -DOPTIMIZER_TRACE=0 @endcode.
269
270 @section WITH_DBUG Interaction between trace and DBUG
271
272 We don't want to have to duplicate code like this:
273@verbatim
274 DBUG_PRINT("info",("cost %g",cost));
275 Opt_trace_object(thd->opt_trace).add("cost",cost);
276@endverbatim
277
278 Thus, any optimizer trace operation, *even* if tracing is run-time disabled,
279 has an implicit DBUG_PRINT("opt",...) inside. This way, only the
280 second line above is needed, and several DBUG_PRINT() could be removed from
281 the Optimizer code.
282 When tracing is run-time disabled, in a debug binary, traces are still
283 created in order to catch the @c add() calls and write their text to DBUG,
284 but those traces are not visible into INFORMATION_SCHEMA.OPTIMIZER_TRACE: we
285 then say that they "don't support I_S".
286 A debug binary without optimizer trace compiled in, will intentionally not
287 compile.
288
289 Because opening an object or array, or add()-ing to it, writes to DBUG
290 immediately, a key/value pair and its outer object may be 100 lines
291 apart in the DBUG log.
292
293 @section ADDING_TRACING Guidelines for adding tracing
294
295 @li Try to limit the number of distinct "words". For example, when
296 describing an optimizer's decision, the words "chosen" (true/false value,
297 tells whether we are choosing the said optimization), "cause" (free text
298 value, tells why we are making this choice, when it's not obvious)
299 can and should often be used. Having a restricted vocabulary helps
300 consistency. Use "row" instead of "record". Use "tmp" instead of
301 "temporary".
302
303 @li Use only simple characters for key names: a-ZA-Z_#, and no space. '#'
304 serves to denote a number, like in "select#" .
305
306 @li Keep in mind than in an object, keys are not ordered; an application may
307 parse the JSON output and output it again with keys order changed; thus
308 when order matters, use an array (which may imply having anonymous objects
309 as items of the array, with keys inside the anonymous objects, see how it's
310 done in @c JOIN::optimize()). Keep in mind that in an object keys should
311 be unique, an application may lose duplicate keys.
312
313 @section OOM_HANDLING Handling of "out-of-memory" errors
314
315 All memory allocations (with exceptions: see below) in the Optimizer trace
316 use @c my_error() to report errors, which itself calls @c
317 error_handler_hook. It is the responsibility of the API user to set up a
318 proper @c error_handler_hook which will alert her/him of the OOM
319 problem. When in the server, this is already the case (@c error_handler_hook
320 is @c my_message_sql() which makes the statement fail).
321 Note that the debug binary may crash if OOM (OOM can cause syntax
322 errors...).
323
324 @section TRACE_SECURITY Description of trace-induced security checks.
325
326 A trace exposes information. For example if one does SELECT on a view, the
327 trace contains the view's body. So, the user should be allowed to see the
328 trace only if she/he has privilege to see the body, i.e. privilege to do
329 SHOW CREATE VIEW.
330 There are similar issues with stored procedures, functions, triggers.
331
332 We implement this by doing additional checks on SQL objects when tracing is
333 on:
334 @li stored procedures, functions, triggers: checks are done when executing
335 those objects
336 @li base tables and views.
337
338 Base tables or views are listed in some @c LEX::query_tables.
339 The LEX may be of the executing statement (statement executed by
340 @c mysql_execute_command(), or by
341 @c sp_lex_keeper::reset_lex_and_exec_core()), we check this LEX in the
342 constructor of Opt_trace_start.
343 Or it may be a LEX describing a view, we check this LEX when
344 opening the view (@c open_and_read_view()).
345
346 Those checks are greatly simplified by disabling traces in case of security
347 context changes. @see opt_trace_disable_if_no_security_context_access().
348
349 Those checks must be done with the security context of the connected
350 user. Checks with the SUID context would be useless: assume the design is
351 that the basic user does not have DML privileges on tables, but only
352 EXECUTE on SUID-highly-privileged routines (which implement _controlled_
353 _approved_ DMLs): then the SUID context would successfully pass all
354 additional privilege checks, routine would generate tracing, and the
355 connected user would view the trace after the routine's execution, seeing
356 secret information.
357
358 @section NEXT What a developer should read next
359
360 The documentation of those classes, in order
361@code
362 Opt_trace_context
363 Opt_trace_context_impl
364 Opt_trace_stmt
365 Opt_trace_struct
366 Opt_trace_object
367 Opt_trace_array
368@endcode
369 and then @ref opt_trace.h as a whole.
370*/
371
372class Opt_trace_stmt; // implementation detail local to opt_trace.cc
373
374/**
375 User-visible information about a trace. @sa Opt_trace_iterator.
376*/
378 /**
379 String containing trace.
380 If trace has been end()ed, this is 0-terminated, which is only to aid
381 debugging or unit testing; this property is not relied upon in normal
382 server usage.
383 If trace has not been ended, this is not 0-terminated. That rare case can
384 happen when a substatement reads OPTIMIZER_TRACE (at that stage, the top
385 statement is still executing so its trace is not ended yet, but may still
386 be read by the sub-statement).
387 */
388 const char *trace_ptr;
389 size_t trace_length; ///< length of trace string
390 //// String containing original query. 0-termination: like trace_ptr.
391 const char *query_ptr;
392 size_t query_length; ///< length of query string
393 const CHARSET_INFO *query_charset; ///< charset of query string
394 /**
395 How many bytes this trace is missing (for traces which were truncated
396 because of @@@@optimizer-trace-max-mem-size).
397 */
399 bool missing_priv; ///< whether user lacks privilege to see this trace
400};
401
402/**
403 Iterator over the list of remembered traces.
404 @note due to implementation, the list must not change during an
405 iterator's lifetime, or results may be unexpected (no crash though).
406*/
408 public:
409 /**
410 @param ctx context
411 */
413
414 void next(); ///< Advances iterator to next trace.
415
416 /**
417 Provides information about the trace on which the iterator is
418 positioned.
419 @param[out] info information returned.
420 The usage pattern is
421 1) instantiate the iterator
422 2) test at_end(), if false: call get_value() and then next()
423 3) repeat (2) until at_end() is true.
424 */
425 void get_value(Opt_trace_info *info) const;
426
427 /// @returns whether iterator is positioned to the end.
428 bool at_end() const { return cursor == nullptr; }
429
430 private:
431 /// Pointer to context, from which traces are retrieved
433 const Opt_trace_stmt *cursor; ///< trace which the iterator is positioned on
434 long row_count; ///< how many traces retrieved so far
435};
436
437/**
438 Object and array are both "structured data" and have lots in common, so the
439 Opt_trace_struct is a base class for them.
440 When you want to add a structure to the trace, you create an instance of
441 Opt_trace_object or Opt_trace_array, then you add information to it with
442 add(), then the destructor closes the structure (we use RAII, Resource
443 Acquisition Is Initialization).
444*/
445
447 protected:
448 /**
449 @param ctx_arg Optimizer trace context for this structure
450 @param requires_key_arg whether this structure requires/forbids keys
451 for values put inside it (an object requires them, an
452 array forbids them)
453 @param key key if this structure is the value of a key/value pair,
454 NULL otherwise. This pointer must remain constant and
455 valid until the object is destroyed (to support
456 @ref saved_key).
457 @param feature optimizer feature to which this structure belongs
458
459 This constructor is never called directly, only from subclasses.
460 */
461 Opt_trace_struct(Opt_trace_context *ctx_arg, bool requires_key_arg,
462 const char *key, Opt_trace_context::feature_value feature)
463 : started(false),
464 requires_key(false),
465 has_disabled_I_S(false),
466 empty(false),
467 stmt(nullptr),
469 // A first inlined test
470 if (unlikely(ctx_arg->is_started())) {
471 // Tracing enabled: must fully initialize the structure.
472 do_construct(ctx_arg, requires_key_arg, key, feature);
473 }
474 /*
475 Otherwise, just leave "started" to false, it marks that the structure is
476 dummy.
477 */
478 }
481 }
482
483 public:
484 /**
485 The exception to RAII: this function is an explicit way of ending a
486 structure before it goes out of scope. Don't use it unless RAII mandates
487 a new scope which mandates re-indenting lots of code lines.
488 */
489 void end() {
491 }
492
493 /**
494 Adds a value (of string type) to the structure. A key is specified, so it
495 adds the key/value pair (the structure must thus be an object).
496
497 There are two "add_*" variants to add a string value.
498 If the value is 0-terminated and each character
499 - is ASCII 7-bit
500 - has ASCII code >=32 and is neither '"' nor '\\'
501 then add_alnum() should be used. That should be the case for all fixed
502 strings like add_alnum("cause", "cost").
503 Otherwise, add_utf8() should be used; it accepts any UTF8-encoded
504 character in 'value' and will escape characters which JSON requires (and
505 is thus slower than add_alnum()). It should be used for all strings which
506 we get from the server's objects (indeed a table's name, a WHERE
507 condition, may contain "strange" characters).
508
509 @param key key
510 @param value value
511 @returns a reference to the structure, useful for chaining like this:
512 @verbatim add(x,y).add(z,t).add(u,v) @endverbatim
513
514 String-related add() variants are named add_[something]():
515 - to avoid confusing the compiler between:
516 add(const char *value, size_t val_length) and
517 add(const char *key, ulonglong value)
518 - and because String::length() returns uint32 and not size_t, so for
519 add(str.ptr(), str.length())
520 compiler may pick
521 add(const char *key, double value) instead of
522 add(const char *value, size_t val_length).
523 */
524 Opt_trace_struct &add_alnum(const char *key, const char *value) {
525 if (likely(!started)) return *this;
526 return do_add(key, value, strlen(value), false);
527 }
528
529 /**
530 Adds a value (of string type) to the structure. No key is specified, so
531 it adds only the value (the structure must thus be an array).
532 @param value value
533 @returns a reference to the structure
534 */
535 Opt_trace_struct &add_alnum(const char *value) {
536 if (likely(!started)) return *this;
537 return do_add(nullptr, value, strlen(value), false);
538 }
539
540 /**
541 Like add_alnum() but supports any UTF8 characters in 'value'.
542 Will "escape" 'value' to be JSON-compliant.
543 @param key key
544 @param value value
545 @param val_length length of string 'value'
546 */
547 Opt_trace_struct &add_utf8(const char *key, const char *value,
548 size_t val_length) {
549 if (likely(!started)) return *this;
550 return do_add(key, value, val_length, true);
551 }
552
553 /// Variant of add_utf8() for adding to an array (no key)
554 Opt_trace_struct &add_utf8(const char *value, size_t val_length) {
555 if (likely(!started)) return *this;
556 return do_add(nullptr, value, val_length, true);
557 }
558
559 /// Variant of add_utf8() where 'value' is 0-terminated
560 Opt_trace_struct &add_utf8(const char *key, const char *value) {
561 if (likely(!started)) return *this;
562 return do_add(key, value, strlen(value), true);
563 }
564
565 /// Variant of add_utf8() where 'value' is 0-terminated
566 Opt_trace_struct &add_utf8(const char *value) {
567 if (likely(!started)) return *this;
568 return do_add(nullptr, value, strlen(value), true);
569 }
570
571 /**
572 Add a value (of Item type) to the structure. The Item should be a
573 condition (like a WHERE clause) which will be pretty-printed into the
574 trace. This is useful for showing condition transformations (equality
575 propagation etc).
576 @param key key
577 @param item the Item
578 @return a reference to the structure
579 */
580 Opt_trace_struct &add(const char *key, const Item *item) {
581 if (likely(!started)) return *this;
582 return do_add(key, item);
583 }
584 Opt_trace_struct &add(const Item *item) {
585 if (likely(!started)) return *this;
586 return do_add(nullptr, item);
587 }
588 Opt_trace_struct &add(const char *key, bool value) {
589 if (likely(!started)) return *this;
590 return do_add(key, value);
591 }
592 Opt_trace_struct &add(bool value) {
593 if (likely(!started)) return *this;
594 return do_add(nullptr, value);
595 }
596 Opt_trace_struct &add(const char *key, int value) {
597 if (likely(!started)) return *this;
598 return do_add(key, static_cast<longlong>(value));
599 }
600 Opt_trace_struct &add(int value) {
601 if (likely(!started)) return *this;
602 return do_add(nullptr, static_cast<longlong>(value));
603 }
604 Opt_trace_struct &add(const char *key, uint value) {
605 if (likely(!started)) return *this;
606 return do_add(key, static_cast<ulonglong>(value));
607 }
608 Opt_trace_struct &add(uint value) {
609 if (likely(!started)) return *this;
610 return do_add(nullptr, static_cast<ulonglong>(value));
611 }
612 Opt_trace_struct &add(const char *key, ulong value) {
613 if (likely(!started)) return *this;
614 return do_add(key, static_cast<ulonglong>(value));
615 }
616 Opt_trace_struct &add(ulong value) {
617 if (likely(!started)) return *this;
618 return do_add(nullptr, static_cast<ulonglong>(value));
619 }
620 Opt_trace_struct &add(const char *key, longlong value) {
621 if (likely(!started)) return *this;
622 return do_add(key, value);
623 }
625 if (likely(!started)) return *this;
626 return do_add(nullptr, value);
627 }
628 Opt_trace_struct &add(const char *key, ulonglong value) {
629 if (likely(!started)) return *this;
630 return do_add(key, value);
631 }
633 if (likely(!started)) return *this;
634 return do_add(nullptr, value);
635 }
636 Opt_trace_struct &add(const char *key, double value) {
637 if (likely(!started)) return *this;
638 return do_add(key, value);
639 }
640 Opt_trace_struct &add(double value) {
641 if (likely(!started)) return *this;
642 return do_add(nullptr, value);
643 }
644 /// Adds a JSON null object (==Python's "None")
646 if (likely(!started)) return *this;
647 return do_add_null(key);
648 }
649 /**
650 Helper to put the database/table name in an object.
651 @param tab TABLE* pointer
652 */
654 if (likely(!started)) return *this;
655 return do_add_utf8_table(tab);
656 }
657 /**
658 Helper to put the number of query_block in an object.
659 @param select_number number of query_block
660 */
661 Opt_trace_struct &add_select_number(uint select_number) {
662 return add("select#", select_number);
663 }
664 /**
665 Add a value to the structure.
666 @param key key
667 @param cost the value of Cost_estimate
668 @return a reference to the structure
669 */
670 Opt_trace_struct &add(const char *key, const Cost_estimate &cost) {
671 if (likely(!started)) return *this;
672 return do_add(key, cost);
673 }
674
675 /**
676 Informs this structure that we are adding data (scalars, structures) to
677 it.
678 This is used only if sending to I_S.
679 @returns whether the structure was empty so far.
680 @note this is reserved for use by Opt_trace_stmt.
681 */
683 const bool old_empty = empty;
684 empty = false;
685 return old_empty;
686 }
687 /**
688 Validates the key about to be added.
689 @note this is reserved for use by Opt_trace_stmt.
690
691 When adding a value (or array or object) to an array, or a key/value pair
692 to an object, we need to know this outer array or object.
693
694 It would be possible, when trying to add a key to an array, which is wrong
695 in JSON, or similarly when trying to add a value without any key to an
696 object, to catch it at compilation time, if the adder received, as
697 function parameter, the type of the structure (like @c
698 Opt_trace_array*). Then the @c add(key,val) call would not compile as
699 Opt_trace_array wouldn't feature it.
700
701 But as explained in comment of class Opt_trace_context we
702 cannot pass down the object, have to maintain a "current object or
703 array" in the Opt_trace_context context (pointer to an instance of
704 Opt_trace_struct), and the adder grabs it from the context.
705
706 As this current structure is of type "object or array", we cannot do
707 compile-time checks that only suitable functions are used. A call to @c
708 add(key,value) is necessarily legal for the compiler as the structure may
709 be an object, though it will be wrong in case the structure is actually
710 an array at run-time. Thus we have the risk of an untested particular
711 situation where the current structure is not an object (but an array)
712 though the code expected it to be one. This happens in practice, because
713 subqueries are evaluated in many possible places of code, not all of them
714 being known. Same happens, to a lesser extent, with calls to the range
715 optimizer.
716 So at run-time, in check_key(), we detect wrong usage, like adding a value
717 to an object without specifying a key, and then remove the unnecessary
718 key, or add an autogenerated key.
719 */
720 const char *check_key(const char *key);
721
722 private:
723 /// Not implemented, use add_alnum() instead.
724 Opt_trace_struct &add(const char *key, const char *value);
725 Opt_trace_struct &add(const char *key);
726
727 /// Full initialization. @sa Opt_trace_struct::Opt_trace_struct
728 void do_construct(Opt_trace_context *ctx, bool requires_key, const char *key,
730 /// Really does destruction
731 void do_destruct();
732 /**
733 Really adds to the object. @sa add().
734
735 @note add() has an up-front if(), hopefully inlined, so that in the
736 common case - tracing run-time disabled - we have no function call. If
737 tracing is enabled, we call do_add().
738 In a 20-table plan search (as in BUG#50595), the execution time was
739 decreased from 2.6 to 2.0 seconds thanks to this inlined-if trick.
740
741 @param key key
742 @param value value
743 @param val_length length of string 'value'
744 @param escape do JSON-compliant escaping of 'value'. If 'escape' is
745 false, 'value' should be ASCII. Otherwise, should be UTF8.
746 */
747 Opt_trace_struct &do_add(const char *key, const char *value,
748 size_t val_length, bool escape);
749 Opt_trace_struct &do_add(const char *key, const Item *item);
750 Opt_trace_struct &do_add(const char *key, bool value);
751 Opt_trace_struct &do_add(const char *key, longlong value);
752 Opt_trace_struct &do_add(const char *key, ulonglong value);
753 Opt_trace_struct &do_add(const char *key, double value);
754 Opt_trace_struct &do_add_null(const char *key);
756 Opt_trace_struct &do_add(const char *key, const Cost_estimate &value);
757
758 Opt_trace_struct(const Opt_trace_struct &); ///< not defined
759 Opt_trace_struct &operator=(const Opt_trace_struct &); ///< not defined
760
761 bool started; ///< Whether the structure does tracing or is dummy
762
763 /**
764 Whether the structure requires/forbids keys for values inside it.
765 true: this is an object. false: this is an array.
766
767 @note The canonical way would be to not have such bool per instance, but
768 rather have a pure virtual member function
769 Opt_trace_struct::requires_key(), overloaded by Opt_trace_object
770 (returning true) and by Opt_trace_array (returning false). But
771 Opt_trace_object::requires_key() would not be accessible from
772 Opt_trace_struct::do_construct() (which would complicate coding), whereas
773 the bool is.
774 */
776
777 /**
778 Whether this structure caused tracing to be disabled in this statement
779 because belonging to a not-traced optimizer feature, in accordance with
780 the value of @@@@optimizer_trace_features.
781 */
783 bool empty; ///< @see set_not_empty()
784 Opt_trace_stmt *stmt; ///< Trace owning the structure
785 /// Key if the structure is the value of a key/value pair, NULL otherwise
786 const char *saved_key;
787#ifndef NDEBUG
788 /**
789 Fixed-length prefix of previous key in this structure, if this structure
790 is an object. Serves to detect when adding two same consecutive keys to
791 an object, which would be wrong.
792 */
793 char previous_key[25];
794#endif
795};
796
797/**
798 A JSON object (unordered set of key/value pairs).
799 Defines only a constructor, all the rest is inherited from
800 Opt_trace_struct.
801*/
803 public:
804 /**
805 Constructs an object. Key is specified, so the object is the value of a
806 key/value pair.
807 @param ctx context for this object
808 @param key key
809 @param feature optimizer feature to which this structure belongs
810 */
812 Opt_trace_context *ctx, const char *key,
814 : Opt_trace_struct(ctx, true, key, feature) {}
815 /**
816 Constructs an object. No key is specified, so the object is just a value
817 (serves for the single root object or for adding the object to an array).
818 @param ctx context for this object
819 @param feature optimizer feature to which this structure belongs
820 */
824 : Opt_trace_struct(ctx, true, nullptr, feature) {}
825};
826
827/**
828 A JSON array (ordered set of values).
829 Defines only a constructor, all the rest in inherited from
830 Opt_trace_struct.
831*/
833 public:
834 /**
835 Constructs an array. Key is specified, so the array is the value of a
836 key/value pair.
837 @param ctx context for this array
838 @param key key
839 @param feature optimizer feature to which this structure belongs
840 */
842 Opt_trace_context *ctx, const char *key,
844 : Opt_trace_struct(ctx, false, key, feature) {}
845 /**
846 Constructs an array. No key is specified, so the array is just a value
847 (serves for adding the object to an array).
848 @param ctx context for this array
849 @param feature optimizer feature to which this structure belongs
850 */
854 : Opt_trace_struct(ctx, false, nullptr, feature) {}
855};
856
857/**
858 Instantiate an instance of this class for specific cases where
859 optimizer trace, in a certain section of Optimizer code, should write only
860 to DBUG and not I_S. Example: see sql_select.cc.
861 Note that this class should rarely be used; the "feature" parameter of
862 Opt_trace_struct is a good alternative.
863*/
865 public:
866 /**
867 @param ctx_arg Context.
868 @param disable_arg Whether the instance should really disable
869 anything. If false, the object is dummy. If true,
870 tracing-to-I_S is disabled at construction and
871 re-enabled at destruction.
872 @details A dummy instance is there only for RAII reasons. Imagine we want
873 to do this:
874@verbatim
875 {
876 if (x) disable tracing;
877 code;
878 } // tracing should be re-enabled here
879@endverbatim
880 As we use RAII, we cannot put the instance declaration inside if(x):
881@verbatim
882 {
883 if (x) Opt_trace_disable_I_S instance(ctx);
884 code;
885 }
886@endverbatim
887 because it would be destroyed as soon as the if() block is left, so
888 tracing would be re-enabled before @c code;. It should rather be written
889 as:
890@verbatim
891 {
892 Opt_trace_disable_I_S instance(ctx, x); // if !x, does nothing
893 code;
894 } // re-enabling happens here, if x is true
895@endverbatim
896 */
897 Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg) {
898 if (disable_arg) {
899 ctx = ctx_arg;
901 } else
902 ctx = nullptr;
903 }
904
905 /// Destructor. Restores trace's "enabled" property to its previous value.
907 if (ctx != nullptr) ctx->restore_I_S();
908 }
909
910 private:
911 /** Context. Non-NULL if and only if this instance really does disabling */
915 const Opt_trace_disable_I_S &); // not defined
916};
917
918/**
919 @name Helpers connecting the optimizer trace to THD or Information Schema.
920*/
921
922//@{
923
925 public:
926 /**
927 Instantiate this class to start tracing a THD's actions (generally at a
928 statement's start), and to set the "original" query (not transformed, as
929 sent by client) for the new trace. Destructor will end the trace.
930
931 If in a routine's instruction, there is no "query". To be helpful to the
932 user, we craft a query using the instruction's print(). We don't leave this
933 to the caller, because it would be inefficient if tracing is off.
934
935 @param thd_arg the THD
936 @param tbl list of tables read/written by the statement.
937 @param sql_command SQL command being prepared or executed
938 @param set_vars what variables are set by this command (only used if
939 sql_command is SQLCOM_SET_OPTION)
940 @param query query
941 @param query_length query's length
942 @param instr routine's instruction, if applicable; if so, 'query'
943 and 'query_length' above are ignored
944 @param query_charset charset which was used to encode this query
945
946 @note Each sub-statement is responsible for ending the trace which it
947 has started; this class achieves this by keeping some memory inside.
948 */
949 Opt_trace_start(THD *thd_arg, Table_ref *tbl,
950 enum enum_sql_command sql_command,
951 List<set_var_base> *set_vars, const char *query,
952 size_t query_length, sp_printable *instr,
953 const CHARSET_INFO *query_charset);
955
956 private:
958 bool error; ///< whether trace start() had an error
959};
960
961class Query_block;
962
963/**
964 Prints SELECT query to optimizer trace. It is not the original query (as in
965 @c Opt_trace_context::set_query()) but a printout of the parse tree
966 (Item-s).
967 @param thd the THD
968 @param query_block query's parse tree
969 @param trace_object Opt_trace_object to which the query will be added
970*/
972 Opt_trace_object *trace_object);
973
974/**
975 If the security context is not that of the connected user, inform the trace
976 system that a privilege is missing. With one exception: see below.
977
978 @param thd the THD
979
980 This serves to eliminate the following issue.
981 Any information readable by a SELECT may theoretically end up in
982 the trace. And a SELECT may read information from other places than tables:
983 - from views (reading their bodies)
984 - from stored routines (reading their bodies)
985 - from files (reading their content), with LOAD_FILE()
986 - from the list of connections (reading their queries...), with
987 I_S.PROCESSLIST.
988 If the connected user has EXECUTE privilege on a routine which does a
989 security context change, the routine can retrieve information internally
990 (if allowed by the SUID context's privileges), and present only a portion
991 of it to the connected user. But with tracing on, all information is
992 possibly in the trace. So the connected user receives more information than
993 the routine's definer intended to provide. Fixing this issue would require
994 adding, near many privilege checks in the server, a new
995 optimizer-trace-specific check done against the connected user's context,
996 to verify that the connected user has the right to see the retrieved
997 information.
998
999 Instead, our chosen simpler solution is that if we see a security context
1000 change where SUID user is not the connected user, we disable tracing. With
1001 only one safe exception: if the connected user has all global privileges
1002 (because then she/he can find any information anyway). By "all global
1003 privileges" we mean everything but WITH GRANT OPTION (that latter one isn't
1004 related to information gathering).
1005
1006 Read access to I_S.OPTIMIZER_TRACE by another user than the connected user
1007 is restricted: @see fill_optimizer_trace_info().
1008*/
1010
1011/**
1012 If tracing is on, checks additional privileges for a view, to make sure
1013 that the user has the right to do SHOW CREATE VIEW. For that:
1014 - this function checks SHOW VIEW
1015 - SELECT is tested in opt_trace_disable_if_no_tables_access()
1016 - SELECT + SHOW VIEW is sufficient for SHOW CREATE VIEW.
1017 We also check underlying tables.
1018 If a privilege is missing, notifies the trace system.
1019 This function should be called when the view's underlying tables have not
1020 yet been merged.
1021
1022 @param thd THD context
1023 @param view view to check
1024 @param underlying_tables underlying tables/views of 'view'
1025 */
1027 Table_ref *underlying_tables);
1028
1029/**
1030 If tracing is on, checks additional privileges on a stored routine, to make
1031 sure that the user has the right to do SHOW CREATE PROCEDURE/FUNCTION. For
1032 that, we use the same checks as in those SHOW commands.
1033 If a privilege is missing, notifies the trace system.
1034
1035 This function is not redundant with
1036 opt_trace_disable_if_no_security_context_access().
1037 Indeed, for a SQL SECURITY INVOKER routine, there is no context change, but
1038 we must still verify that the invoker can do SHOW CREATE.
1039
1040 For triggers, see note in sp_head::execute_trigger().
1041
1042 @param thd The THD
1043 @param sp routine to check
1044 */
1046
1047/**
1048 Fills information_schema.OPTIMIZER_TRACE with rows (one per trace)
1049 @retval 0 ok
1050 @retval 1 error
1051*/
1052int fill_optimizer_trace_info(THD *thd, Table_ref *tables, Item *);
1053
1054//@}
1055
1056/**
1057 Helper for defining query-transformation-related trace objects in one
1058 code line. This produces
1059 {
1060 "transformation": {
1061 "select#": @<select_number@>,
1062 "from": @<from@>,
1063 "to": @<to@>
1064 The objects are left open, so that one can add more to them (often a
1065 "chosen" property after making some computation). Objects get closed when
1066 going out of scope as usual.
1067 @param trace optimizer trace
1068 @param object_level0 name of the outer Opt_trace_object C++ object
1069 @param object_level1 name of the inner Opt_trace_object C++ object
1070 @param select_number number of the being-transformed Query_block
1071 @param from description of the before-transformation state
1072 @param to description of the after-transformation state
1073*/
1074#define OPT_TRACE_TRANSFORM(trace, object_level0, object_level1, \
1075 select_number, from, to) \
1076 const Opt_trace_object object_level0(trace); \
1077 Opt_trace_object object_level1(trace, "transformation"); \
1078 object_level1.add_select_number(select_number); \
1079 object_level1.add_alnum("from", from).add_alnum("to", to);
1080
1081#endif /* OPT_TRACE_INCLUDED */
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
Used to store optimizer cost estimates.
Definition: handler.h:3864
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:934
Definition: sql_list.h:467
A JSON array (ordered set of values).
Definition: opt_trace.h:832
Opt_trace_array(Opt_trace_context *ctx, const char *key, Opt_trace_context::feature_value feature=Opt_trace_context::MISC)
Constructs an array.
Definition: opt_trace.h:841
Opt_trace_array(Opt_trace_context *ctx, Opt_trace_context::feature_value feature=Opt_trace_context::MISC)
Constructs an array.
Definition: opt_trace.h:851
A per-session context which is always available at any point of execution, because in practice it's a...
Definition: opt_trace_context.h:93
void disable_I_S_for_this_and_children()
Temporarily disables I_S for this trace and its children.
Definition: opt_trace_context.h:260
feature_value
Features' numeric values for @@optimizer_trace_features variable.
Definition: opt_trace_context.h:204
@ MISC
Anything unclassified, including the top object (thus, by "inheritance from parent",...
Definition: opt_trace_context.h:219
bool is_started() const
Returns whether there is a current trace.
Definition: opt_trace_context.h:147
void restore_I_S()
Restores I_S support to what it was before the previous call to disable_I_S_for_this_and_children().
Definition: opt_trace_context.h:269
Instantiate an instance of this class for specific cases where optimizer trace, in a certain section ...
Definition: opt_trace.h:864
Opt_trace_disable_I_S(const Opt_trace_disable_I_S &)
~Opt_trace_disable_I_S()
Destructor. Restores trace's "enabled" property to its previous value.
Definition: opt_trace.h:906
Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg)
Definition: opt_trace.h:897
Opt_trace_disable_I_S & operator=(const Opt_trace_disable_I_S &)
Opt_trace_context * ctx
Context.
Definition: opt_trace.h:912
Iterator over the list of remembered traces.
Definition: opt_trace.h:407
Opt_trace_iterator(Opt_trace_context *ctx)
Definition: opt_trace.cc:1151
bool at_end() const
Definition: opt_trace.h:428
void get_value(Opt_trace_info *info) const
Provides information about the trace on which the iterator is positioned.
Definition: opt_trace.cc:1160
const Opt_trace_stmt * cursor
trace which the iterator is positioned on
Definition: opt_trace.h:433
Opt_trace_context * ctx
Pointer to context, from which traces are retrieved.
Definition: opt_trace.h:432
void next()
Advances iterator to next trace.
Definition: opt_trace.cc:1156
long row_count
how many traces retrieved so far
Definition: opt_trace.h:434
A JSON object (unordered set of key/value pairs).
Definition: opt_trace.h:802
Opt_trace_object(Opt_trace_context *ctx, Opt_trace_context::feature_value feature=Opt_trace_context::MISC)
Constructs an object.
Definition: opt_trace.h:821
Opt_trace_object(Opt_trace_context *ctx, const char *key, Opt_trace_context::feature_value feature=Opt_trace_context::MISC)
Constructs an object.
Definition: opt_trace.h:811
Definition: opt_trace.h:924
bool error
whether trace start() had an error
Definition: opt_trace.h:958
~Opt_trace_start()
Definition: opt_trace2server.cc:239
Opt_trace_context *const ctx
Definition: opt_trace.h:957
Opt_trace_start(THD *thd_arg, Table_ref *tbl, enum enum_sql_command sql_command, List< set_var_base > *set_vars, const char *query, size_t query_length, sp_printable *instr, const CHARSET_INFO *query_charset)
Instantiate this class to start tracing a THD's actions (generally at a statement's start),...
Definition: opt_trace2server.cc:134
The trace of one statement.
Definition: opt_trace.cc:111
Object and array are both "structured data" and have lots in common, so the Opt_trace_struct is a bas...
Definition: opt_trace.h:446
Opt_trace_struct & add_null(const char *key)
Adds a JSON null object (==Python's "None")
Definition: opt_trace.h:645
Opt_trace_struct & add(const Item *item)
Definition: opt_trace.h:584
Opt_trace_struct & add_select_number(uint select_number)
Helper to put the number of query_block in an object.
Definition: opt_trace.h:661
Opt_trace_struct & do_add_utf8_table(const Table_ref *tab)
Definition: opt_trace.cc:371
char previous_key[25]
Fixed-length prefix of previous key in this structure, if this structure is an object.
Definition: opt_trace.h:793
Opt_trace_struct & add(ulonglong value)
Definition: opt_trace.h:632
const char * saved_key
Key if the structure is the value of a key/value pair, NULL otherwise.
Definition: opt_trace.h:786
~Opt_trace_struct()
Definition: opt_trace.h:479
void do_construct(Opt_trace_context *ctx, bool requires_key, const char *key, Opt_trace_context::feature_value feature)
Full initialization.
Definition: opt_trace.cc:267
void end()
The exception to RAII: this function is an explicit way of ending a structure before it goes out of s...
Definition: opt_trace.h:489
Opt_trace_struct & add(ulong value)
Definition: opt_trace.h:616
void do_destruct()
Really does destruction.
Definition: opt_trace.cc:285
Opt_trace_struct & add(int value)
Definition: opt_trace.h:600
bool started
Whether the structure does tracing or is dummy.
Definition: opt_trace.h:761
Opt_trace_struct & add(const char *key, longlong value)
Definition: opt_trace.h:620
Opt_trace_struct & add(const char *key, const Item *item)
Add a value (of Item type) to the structure.
Definition: opt_trace.h:580
Opt_trace_stmt * stmt
Trace owning the structure.
Definition: opt_trace.h:784
bool requires_key
Whether the structure requires/forbids keys for values inside it.
Definition: opt_trace.h:775
Opt_trace_struct & add(longlong value)
Definition: opt_trace.h:624
bool set_not_empty()
Informs this structure that we are adding data (scalars, structures) to it.
Definition: opt_trace.h:682
Opt_trace_struct & do_add(const char *key, const char *value, size_t val_length, bool escape)
Really adds to the object.
Definition: opt_trace.cc:293
Opt_trace_struct & add(double value)
Definition: opt_trace.h:640
Opt_trace_struct & add_alnum(const char *key, const char *value)
Adds a value (of string type) to the structure.
Definition: opt_trace.h:524
Opt_trace_struct & add(const char *key, uint value)
Definition: opt_trace.h:604
Opt_trace_struct & add(const char *key, double value)
Definition: opt_trace.h:636
Opt_trace_struct & operator=(const Opt_trace_struct &)
not defined
const char * check_key(const char *key)
Validates the key about to be added.
Definition: opt_trace.cc:382
Opt_trace_struct & add_utf8(const char *value)
Variant of add_utf8() where 'value' is 0-terminated.
Definition: opt_trace.h:566
Opt_trace_struct & add(const char *key, ulong value)
Definition: opt_trace.h:612
Opt_trace_struct & add_utf8(const char *key, const char *value, size_t val_length)
Like add_alnum() but supports any UTF8 characters in 'value'.
Definition: opt_trace.h:547
Opt_trace_struct(Opt_trace_context *ctx_arg, bool requires_key_arg, const char *key, Opt_trace_context::feature_value feature)
Definition: opt_trace.h:461
bool has_disabled_I_S
Whether this structure caused tracing to be disabled in this statement because belonging to a not-tra...
Definition: opt_trace.h:782
Opt_trace_struct & add(bool value)
Definition: opt_trace.h:592
Opt_trace_struct & add_utf8(const char *key, const char *value)
Variant of add_utf8() where 'value' is 0-terminated.
Definition: opt_trace.h:560
Opt_trace_struct & add(uint value)
Definition: opt_trace.h:608
Opt_trace_struct & add_utf8(const char *value, size_t val_length)
Variant of add_utf8() for adding to an array (no key)
Definition: opt_trace.h:554
Opt_trace_struct(const Opt_trace_struct &)
not defined
Opt_trace_struct & add(const char *key, const Cost_estimate &cost)
Add a value to the structure.
Definition: opt_trace.h:670
Opt_trace_struct & do_add_null(const char *key)
Definition: opt_trace.cc:344
Opt_trace_struct & add(const char *key, const char *value)
Not implemented, use add_alnum() instead.
bool empty
Definition: opt_trace.h:783
Opt_trace_struct & add(const char *key, bool value)
Definition: opt_trace.h:588
Opt_trace_struct & add(const char *key)
Opt_trace_struct & add_alnum(const char *value)
Adds a value (of string type) to the structure.
Definition: opt_trace.h:535
Opt_trace_struct & add(const char *key, ulonglong value)
Definition: opt_trace.h:628
Opt_trace_struct & add_utf8_table(const Table_ref *tab)
Helper to put the database/table name in an object.
Definition: opt_trace.h:653
Opt_trace_struct & add(const char *key, int value)
Definition: opt_trace.h:596
This class represents a query block, aka a query specification, which is a query consisting of a SELE...
Definition: sql_lex.h:1163
Query_block * query_block() const override
The query_block which holds the ORDER BY and LIMIT information for this set operation.
Definition: sql_lex.h:1179
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: table.h:2863
A base class for everything that can be set with SET command.
Definition: set_var.h:950
sp_head represents one instance of a stored program.
Definition: sp_head.h:383
sp_printable defines an interface which should be implemented if a class wants report some internal i...
Definition: sp_instr.h:67
Header for compiler-dependent features.
constexpr bool likely(bool expr)
Definition: my_compiler.h:57
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:58
Some integer typedefs for easier portability.
unsigned long long int ulonglong
Definition: my_inttypes.h:56
long long int longlong
Definition: my_inttypes.h:55
enum_sql_command
Definition: my_sqlcommand.h:46
static char * query
Definition: myisam_ftdump.cc:47
static std::string escape(const std::string &str)
Escapes (only) apostrophes.
Definition: st_units_of_measure.cc:39
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 th...
Definition: opt_trace2server.cc:344
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 t...
Definition: opt_trace2server.cc:365
void opt_trace_print_expanded_query(const THD *thd, Query_block *query_block, Opt_trace_object *trace_object)
Prints SELECT query to optimizer trace.
Definition: opt_trace2server.cc:244
int fill_optimizer_trace_info(THD *thd, Table_ref *tables, Item *)
Fills information_schema.OPTIMIZER_TRACE with rows (one per trace)
Definition: opt_trace2server.cc:480
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 i...
Definition: opt_trace2server.cc:275
This contains the declaration of class Opt_trace_context, which is needed to declare THD.
required string key
Definition: replication_asynchronous_connection_failover.proto:60
Definition: m_ctype.h:423
User-visible information about a trace.
Definition: opt_trace.h:377
size_t missing_bytes
How many bytes this trace is missing (for traces which were truncated because of @@optimizer-trace-ma...
Definition: opt_trace.h:398
size_t trace_length
length of trace string / String containing original query. 0-termination: like trace_ptr.
Definition: opt_trace.h:389
const CHARSET_INFO * query_charset
charset of query string
Definition: opt_trace.h:393
const char * query_ptr
Definition: opt_trace.h:391
const char * trace_ptr
String containing trace.
Definition: opt_trace.h:388
bool missing_priv
whether user lacks privilege to see this trace
Definition: opt_trace.h:399
size_t query_length
length of query string
Definition: opt_trace.h:392