My Project
opt_trace.h
Go to the documentation of this file.
00001 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA  */
00015 
00016 #ifndef OPT_TRACE_INCLUDED
00017 #define OPT_TRACE_INCLUDED
00018 
00019 #include "my_config.h"  // OPTIMIZER_TRACE
00020 #include "sql_array.h"  // Dynamic_array
00021 #include "sql_list.h"   // because sql_cmd.h needs it
00022 #include "sql_cmd.h"    // for enum_sql_command
00023 #include "opt_trace_context.h" // Opt_trace_context
00024 
00025 struct st_schema_table;
00026 struct TABLE_LIST;
00027 struct TABLE;
00028 class sp_head;
00029 class sp_printable;
00030 class set_var_base;
00031 
00045 #ifdef OPTIMIZER_TRACE
00046 
00366 class Opt_trace_struct;
00367 class Opt_trace_stmt;           // implementation detail local to opt_trace.cc
00368 
00369 
00373 struct Opt_trace_info
00374 {
00385   const char *trace_ptr;
00386   size_t trace_length;                          
00387 
00388   const char *query_ptr;
00389   size_t query_length;                          
00390   const CHARSET_INFO *query_charset;            
00391 
00395   size_t missing_bytes;
00396   bool missing_priv; 
00397 };
00398 
00399 
00405 class Opt_trace_iterator
00406 {
00407 public:
00411   Opt_trace_iterator(Opt_trace_context *ctx);
00412 
00413   void next();                           
00414 
00424   void get_value(Opt_trace_info *info) const;
00425 
00427   bool at_end() const { return cursor == NULL; }
00428 
00429 private:
00431   Opt_trace_context *ctx;
00432   const Opt_trace_stmt *cursor; 
00433   long row_count;               
00434 };
00435 
00436 
00446 class Opt_trace_struct
00447 {
00448 protected:
00462   Opt_trace_struct(Opt_trace_context *ctx_arg, bool requires_key_arg,
00463                    const char *key,
00464                    Opt_trace_context::feature_value feature) :
00465     started(false)
00466   {
00467     // A first inlined test
00468     if (unlikely(ctx_arg->is_started()))
00469     {
00470       // Tracing enabled: must fully initialize the structure.
00471       do_construct(ctx_arg, requires_key_arg, key, feature);
00472     }
00473     /*
00474       Otherwise, just leave "started" to false, it marks that the structure is
00475       dummy.
00476     */
00477   }
00478   ~Opt_trace_struct() { if (unlikely(started)) do_destruct(); }
00479 
00480 public:
00481 
00487   void end() { if (unlikely(started)) do_destruct(); }
00488 
00521   Opt_trace_struct& add_alnum(const char *key, const char *value)
00522   {
00523     if (likely(!started))
00524       return *this;
00525     return do_add(key, value, strlen(value), false);
00526   }
00527 
00534   Opt_trace_struct& add_alnum(const char *value)
00535   {
00536     if (likely(!started))
00537       return *this;
00538     return do_add(NULL, value, strlen(value), false);
00539   }
00540 
00548   Opt_trace_struct& add_utf8(const char *key,
00549                              const char *value, size_t val_length)
00550   {
00551     if (likely(!started))
00552       return *this;
00553     return do_add(key, value, val_length, true);
00554   }
00555 
00557   Opt_trace_struct& add_utf8(const char *value, size_t val_length)
00558   {
00559     if (likely(!started))
00560       return *this;
00561     return do_add(NULL, value, val_length, true);
00562   }
00563 
00565   Opt_trace_struct& add_utf8(const char *key, const char *value)
00566   {
00567     if (likely(!started))
00568       return *this;
00569     return do_add(key, value, strlen(value), true);
00570   }
00571 
00573   Opt_trace_struct& add_utf8(const char *value)
00574   {
00575     if (likely(!started))
00576       return *this;
00577     return do_add(NULL, value, strlen(value), true);
00578   }
00579 
00589   Opt_trace_struct& add(const char *key, Item *item)
00590   {
00591     if (likely(!started))
00592       return *this;
00593     return do_add(key, item);
00594   }
00595   Opt_trace_struct& add(Item *item)
00596   {
00597     if (likely(!started))
00598       return *this;
00599     return do_add(NULL, item);
00600   }
00601 public:
00602   Opt_trace_struct& add(const char *key, bool value)
00603   {
00604     if (likely(!started))
00605       return *this;
00606     return do_add(key, value);
00607   }
00608   Opt_trace_struct& add(bool value)
00609   {
00610     if (likely(!started))
00611       return *this;
00612     return do_add(NULL, value);
00613   }
00614   Opt_trace_struct& add(const char *key, int value)
00615   {
00616     if (likely(!started))
00617       return *this;
00618     return do_add(key, static_cast<longlong>(value));
00619   }
00620   Opt_trace_struct& add(int value)
00621   {
00622     if (likely(!started))
00623       return *this;
00624     return do_add(NULL, static_cast<longlong>(value));
00625   }
00626   Opt_trace_struct& add(const char *key, uint value)
00627   {
00628     if (likely(!started))
00629       return *this;
00630     return do_add(key, static_cast<ulonglong>(value));
00631   }
00632   Opt_trace_struct& add(uint value)
00633   {
00634     if (likely(!started))
00635       return *this;
00636     return do_add(NULL, static_cast<ulonglong>(value));
00637   }
00638   Opt_trace_struct& add(const char *key, ulong value)
00639   {
00640     if (likely(!started))
00641       return *this;
00642     return do_add(key, static_cast<ulonglong>(value));
00643   }
00644   Opt_trace_struct& add(ulong value)
00645   {
00646     if (likely(!started))
00647       return *this;
00648     return do_add(NULL, static_cast<ulonglong>(value));
00649   }
00650   Opt_trace_struct& add(const char *key, longlong value)
00651   {
00652     if (likely(!started))
00653       return *this;
00654     return do_add(key, value);
00655   }
00656   Opt_trace_struct& add(longlong value)
00657   {
00658     if (likely(!started))
00659       return *this;
00660     return do_add(NULL, value);
00661   }
00662   Opt_trace_struct& add(const char *key, ulonglong value)
00663   {
00664     if (likely(!started))
00665       return *this;
00666     return do_add(key, value);
00667   }
00668   Opt_trace_struct& add(ulonglong value)
00669   {
00670     if (likely(!started))
00671       return *this;
00672     return do_add(NULL, value);
00673   }
00674   Opt_trace_struct& add(const char *key, double value)
00675   {
00676     if (likely(!started))
00677       return *this;
00678     return do_add(key, value);
00679   }
00680   Opt_trace_struct& add(double value)
00681   {
00682     if (likely(!started))
00683       return *this;
00684     return do_add(NULL, value);
00685   }
00687   Opt_trace_struct& add_hex(const char *key, uint64 value)
00688   {
00689     if (likely(!started))
00690       return *this;
00691     return do_add_hex(key, value);
00692   }
00693   Opt_trace_struct& add_hex(uint64 value)
00694   {
00695     if (likely(!started))
00696       return *this;
00697     return do_add_hex(NULL, value);
00698   }
00700   Opt_trace_struct& add_null(const char *key)
00701   {
00702     if (likely(!started))
00703       return *this;
00704     return do_add_null(key);
00705   }
00710   Opt_trace_struct& add_utf8_table(const TABLE *tab)
00711   {
00712     if (likely(!started))
00713       return *this;
00714     return do_add_utf8_table(tab);
00715   }
00720   Opt_trace_struct& add_select_number(uint select_number)
00721   {
00722     return unlikely(select_number >= INT_MAX) ?
00723       // Clearer than any huge number.
00724       add_alnum("select#", "fake") :
00725       add("select#", select_number);
00726   }
00727 
00735   bool set_not_empty()
00736   {
00737     const bool old_empty= empty;
00738     empty= false;
00739     return old_empty;
00740   }
00774   const char *check_key(const char *key);
00775 
00776 private:
00778   Opt_trace_struct& add(const char *key, const char* value);
00779   Opt_trace_struct& add(const char *key);
00780 
00782   void do_construct(Opt_trace_context *ctx,
00783                     bool requires_key, const char *key,
00784                     Opt_trace_context::feature_value feature);
00786   void do_destruct();
00793   Opt_trace_struct& do_add(const char *key, const char *value,
00794                            size_t val_length, bool escape);
00795   Opt_trace_struct& do_add(const char *key, Item *item);
00796   Opt_trace_struct& do_add(const char *key, bool value);
00797   Opt_trace_struct& do_add(const char *key, longlong value);
00798   Opt_trace_struct& do_add(const char *key, ulonglong value);
00799   Opt_trace_struct& do_add(const char *key, double value);
00800   Opt_trace_struct& do_add_hex(const char *key, uint64 value);
00801   Opt_trace_struct& do_add_null(const char *key);
00802   Opt_trace_struct& do_add_utf8_table(const TABLE *tab);
00803 
00804   Opt_trace_struct(const Opt_trace_struct&);            
00805   Opt_trace_struct& operator=(const Opt_trace_struct&); 
00806 
00807   bool started; 
00808 
00821   bool requires_key;
00822 
00828   bool has_disabled_I_S;
00829   bool empty;                                   
00830   Opt_trace_stmt *stmt;                        
00831 
00832   const char *saved_key;
00833 #ifndef DBUG_OFF
00834 
00839   char previous_key[25];
00840 #endif
00841 };
00842 
00843 
00849 class Opt_trace_object: public Opt_trace_struct
00850 {
00851 public:
00859   Opt_trace_object(Opt_trace_context *ctx, const char *key,
00860                    Opt_trace_context::feature_value feature=
00861                    Opt_trace_context::MISC)
00862     : Opt_trace_struct(ctx, true, key, feature)
00863   {}
00870   Opt_trace_object(Opt_trace_context *ctx,
00871                    Opt_trace_context::feature_value feature=
00872                    Opt_trace_context::MISC)
00873     : Opt_trace_struct(ctx, true, NULL, feature)
00874   {}
00875 };
00876 
00877 
00883 class Opt_trace_array: public Opt_trace_struct
00884 {
00885 public:
00893   Opt_trace_array(Opt_trace_context *ctx, const char *key,
00894                   Opt_trace_context::feature_value feature=
00895                   Opt_trace_context::MISC)
00896     : Opt_trace_struct(ctx, false, key, feature)
00897   {}
00904   Opt_trace_array(Opt_trace_context *ctx,
00905                   Opt_trace_context::feature_value feature=
00906                   Opt_trace_context::MISC)
00907     : Opt_trace_struct(ctx, false, NULL, feature)
00908   {}
00909 };
00910 
00911 
00919 class Opt_trace_disable_I_S
00920 {
00921 public:
00953   Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg)
00954   {
00955     if (disable_arg)
00956     {
00957       ctx= ctx_arg;
00958       ctx->disable_I_S_for_this_and_children();
00959     }
00960     else
00961       ctx= NULL;
00962   }
00963 
00965   ~Opt_trace_disable_I_S()
00966   {
00967     if (ctx != NULL)
00968       ctx->restore_I_S();
00969   }
00970 
00971 private:
00973   Opt_trace_context *ctx;
00974   Opt_trace_disable_I_S(const Opt_trace_disable_I_S&); // not defined
00975   Opt_trace_disable_I_S& operator=(const Opt_trace_disable_I_S&);//not defined
00976 };
00977 
00978 
00984 
01008 class Opt_trace_start
01009 {
01010 public:
01011   Opt_trace_start(THD *thd_arg, TABLE_LIST *tbl,
01012                   enum enum_sql_command sql_command,
01013                   List<set_var_base> *set_vars,
01014                   const char *query, size_t query_length,
01015                   sp_printable *instr,
01016                   const CHARSET_INFO *query_charset);
01017   ~Opt_trace_start();
01018 private:
01019   Opt_trace_context * const ctx;
01020   bool error; 
01021 };
01022 
01023 
01024 class st_select_lex;
01033 void opt_trace_print_expanded_query(THD *thd,
01034                                     st_select_lex *select_lex,
01035                                     Opt_trace_object *trace_object);
01036 
01072 void opt_trace_disable_if_no_security_context_access(THD *thd);
01073 
01089 void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view,
01090                                          TABLE_LIST *underlying_tables);
01091 
01108 void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp);
01109 
01115 int fill_optimizer_trace_info(THD *thd, TABLE_LIST *tables, Item *cond);
01116 
01118 
01119 #else /* defined (OPTIMIZER_TRACE) */
01120 
01121 /* all empty */
01122 
01124 class Opt_trace_object
01125 {
01126 public:
01127   Opt_trace_object(Opt_trace_context *ctx, const char *key,
01128                    Opt_trace_context::feature_value feature=
01129                    Opt_trace_context::MISC)
01130   {}
01131   Opt_trace_object(Opt_trace_context *ctx,
01132                    Opt_trace_context::feature_value feature=
01133                    Opt_trace_context::MISC)
01134   {}
01135   Opt_trace_object& add_alnum(const char *key, const char *value)
01136   { return *this; }
01137   Opt_trace_object& add_utf8(const char *key,
01138                              const char *value, size_t val_length)
01139   { return *this; }
01140   Opt_trace_object& add_utf8(const char *key, const char *value)
01141   { return *this; }
01142   Opt_trace_object& add(const char *key, Item *item) { return *this; }
01143   Opt_trace_object& add(const char *key, bool value) { return *this; }
01144   Opt_trace_object& add(const char *key, int value) { return *this; }
01145   Opt_trace_object& add(const char *key, uint value) { return *this; }
01146   Opt_trace_object& add(const char *key, ulong value) { return *this; }
01147   Opt_trace_object& add(const char *key, longlong value) { return *this; }
01148   Opt_trace_object& add(const char *key, ulonglong value) { return *this; }
01149   Opt_trace_object& add(const char *key, double value) { return *this; }
01150   Opt_trace_object& add_hex(const char *key, uint64 value) { return *this; }
01151   Opt_trace_object& add_utf8_table(const TABLE *tab) { return *this; }
01152   Opt_trace_object& add_select_number(uint select_number) { return *this; }
01153   void end() {}
01154 };
01155 
01157 class Opt_trace_array
01158 {
01159 public:
01160   Opt_trace_array(Opt_trace_context *ctx, const char *key,
01161                   Opt_trace_context::feature_value feature=
01162                   Opt_trace_context::MISC)
01163   {}
01164   Opt_trace_array(Opt_trace_context *ctx,
01165                   Opt_trace_context::feature_value feature=
01166                   Opt_trace_context::MISC)
01167   {}
01168   Opt_trace_array& add_alnum(const char *value) { return *this; }
01169   Opt_trace_array& add_utf8(const char *value, size_t val_length)
01170   { return *this; }
01171   Opt_trace_array& add_utf8(const char *value)
01172   { return *this; }
01173   Opt_trace_array& add(Item *item) { return *this; }
01174   Opt_trace_array& add(bool value) { return *this; }
01175   Opt_trace_array& add(int value) { return *this; }
01176   Opt_trace_array& add(uint value) { return *this; }
01177   Opt_trace_array& add(longlong value) { return *this; }
01178   Opt_trace_array& add(ulonglong value) { return *this; }
01179   Opt_trace_array& add(double value) { return *this; }
01180   Opt_trace_array& add_hex(uint64 value) { return *this; }
01181   Opt_trace_array& add_utf8_table(TABLE *tab) { return *this; }
01182   Opt_trace_array& add_select_number(uint select_number) { return *this; }
01183   void end() {}
01184 };
01185 
01187 class Opt_trace_disable_I_S
01188 {
01189 public:
01190   Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg) {}
01191 };
01192 
01193 class Opt_trace_start
01194 {
01195 public:
01196   Opt_trace_start(THD *thd, const TABLE_LIST *tbl,
01197                   enum enum_sql_command sql_command,
01198                   List<set_var_base> *set_vars,
01199                   const char *query, size_t query_length,
01200                   sp_printable *instr,
01201                   const CHARSET_INFO *query_charset) {}
01202 };
01203 
01204 #define opt_trace_print_expanded_query(thd, select_lex, trace_object) \
01205   do {} while (0)
01206 #define opt_trace_disable_if_no_view_access(thd, view, underlying_tables) \
01207   do {} while (0)
01208 #define opt_trace_disable_if_no_stored_proc_func_access(thd, sp) do{} while(0)
01209 #define opt_trace_disable_if_no_security_context_access(thd) do {} while (0)
01210 
01211 #endif /* OPTIMIZER_TRACE */
01212 
01231 #define OPT_TRACE_TRANSFORM(trace,object_level0,object_level1,          \
01232                             select_number,from,to)                      \
01233   Opt_trace_object object_level0(trace);                                \
01234   Opt_trace_object object_level1(trace, "transformation");              \
01235   object_level1.add_select_number(select_number);                       \
01236   object_level1.add_alnum("from", from).add_alnum("to", to);
01237 
01238 /*
01239   A debug binary without optimizer trace compiled in, will miss some
01240   debugging info, be less useful, so:
01241 */
01242 #if !defined(DBUG_OFF) && !defined(OPTIMIZER_TRACE)
01243 #error debug binaries must support optimizer trace
01244 #endif
01245 
01246 #endif /* OPT_TRACE_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines