1 #ifndef OPT_TRACE_CONTEXT_INCLUDED
2 #define OPT_TRACE_CONTEXT_INCLUDED
3 
4 #include "sql_array.h"
5 
6 class Opt_trace_context;
7 struct Opt_trace_info;
8 class Json_writer;
9 
10 class Opt_trace_stmt {
11  public:
12   /**
13      Constructor, starts a trace for information_schema and dbug.
14      @param  ctx_arg          context
15   */
16   Opt_trace_stmt(Opt_trace_context *ctx_arg);
17   ~Opt_trace_stmt();
18   void set_query(const char *query_ptr, size_t length, const CHARSET_INFO *charset);
19   void open_struct(const char *key, char opening_bracket);
20   void close_struct(const char *saved_key, char closing_bracket);
21   void fill_info(Opt_trace_info* info);
22   void add(const char *key, char *opening_bracket, size_t val_length);
23   Json_writer* get_current_json() {return current_json;}
24   void missing_privilege();
25   void disable_tracing_for_children();
26   void enable_tracing_for_children();
27   bool is_enabled()
28   {
29    return I_S_disabled == 0;
30   }
31   void set_allowed_mem_size(size_t mem_size);
32   size_t get_length();
33   size_t get_truncated_bytes();
34   bool get_missing_priv() { return missing_priv; }
35 
36 private:
37   Opt_trace_context *ctx;
38   String query;  // store the query sent by the user
39   Json_writer *current_json; // stores the trace
40   bool missing_priv;  ///< whether user lacks privilege to see this trace
41   /*
42     0 <=> this trace should be in information_schema.
43   !=0 tracing is disabled, this currently happens when we want to trace a
44       sub-statement. For now traces are only collect for the top statement
45       not for the sub-statments.
46   */
47   uint I_S_disabled;
48 };
49 
50 
51 class Opt_trace_context
52 {
53 public:
54    Opt_trace_context();
55   ~Opt_trace_context();
56 
57   void start(THD *thd, TABLE_LIST *tbl,
58              enum enum_sql_command sql_command,
59              const char *query,
60              size_t query_length,
61              const CHARSET_INFO *query_charset,
62              ulong max_mem_size_arg);
63   void end();
64   void set_query(const char *query, size_t length, const CHARSET_INFO *charset);
65   void delete_traces();
66   void set_allowed_mem_size(size_t mem_size);
67   size_t remaining_mem_size();
68 
69 private:
70   Opt_trace_stmt* top_trace()
71   {
72     return *(traces.front());
73   }
74 
75 public:
76 
77   /*
78     This returns the top trace from the list of traces. This function
79     is used when we want to see the contents of the INFORMATION_SCHEMA.OPTIMIZER_TRACE
80   table.
81   */
82 
83   Opt_trace_stmt* get_top_trace()
84   {
85     if (!traces.elements())
86       return NULL;
87     return top_trace();
88   }
89 
90   /*
91     This returns the current trace, to which we are still writing and has not been finished
92   */
93 
94   Json_writer* get_current_json()
95   {
96     if (!is_started())
97       return NULL;
98     return current_trace->get_current_json();
99   }
100 
101   bool empty()
102   {
103     return static_cast<uint>(traces.elements()) == 0;
104   }
105 
106   bool is_started()
107   {
108     return current_trace && current_trace->is_enabled();
109   }
110 
111   bool disable_tracing_if_required();
112 
113   bool enable_tracing_if_required();
114 
115   bool is_enabled();
116 
117   void missing_privilege();
118 
119   static const char *flag_names[];
120   enum
121   {
122     FLAG_DEFAULT = 0,
123     FLAG_ENABLED = 1 << 0
124   };
125 
126 private:
127   /*
128     List of traces (currently it stores only 1 trace)
129   */
130   Dynamic_array<Opt_trace_stmt*> traces;
131   Opt_trace_stmt *current_trace;
132   size_t max_mem_size;
133 };
134 
135 #endif /* OPT_TRACE_CONTEXT_INCLUDED */
136