MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
opt_trace.h
Go to the documentation of this file.
1 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
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 as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #ifndef OPT_TRACE_INCLUDED
17 #define OPT_TRACE_INCLUDED
18 
19 #include "my_config.h" // OPTIMIZER_TRACE
20 #include "sql_array.h" // Dynamic_array
21 #include "sql_list.h" // because sql_cmd.h needs it
22 #include "sql_cmd.h" // for enum_sql_command
23 #include "opt_trace_context.h" // Opt_trace_context
24 
25 struct st_schema_table;
26 struct TABLE_LIST;
27 struct TABLE;
28 class sp_head;
29 class sp_printable;
30 class set_var_base;
31 
45 #ifdef OPTIMIZER_TRACE
46 
366 class Opt_trace_struct;
367 class Opt_trace_stmt; // implementation detail local to opt_trace.cc
368 
369 
373 struct Opt_trace_info
374 {
385  const char *trace_ptr;
386  size_t trace_length;
387 
388  const char *query_ptr;
389  size_t query_length;
390  const CHARSET_INFO *query_charset;
391 
395  size_t missing_bytes;
396  bool missing_priv;
397 };
398 
399 
405 class Opt_trace_iterator
406 {
407 public:
411  Opt_trace_iterator(Opt_trace_context *ctx);
412 
413  void next();
414 
424  void get_value(Opt_trace_info *info) const;
425 
427  bool at_end() const { return cursor == NULL; }
428 
429 private:
431  Opt_trace_context *ctx;
432  const Opt_trace_stmt *cursor;
433  long row_count;
434 };
435 
436 
446 class Opt_trace_struct
447 {
448 protected:
462  Opt_trace_struct(Opt_trace_context *ctx_arg, bool requires_key_arg,
463  const char *key,
465  started(false)
466  {
467  // A first inlined test
468  if (unlikely(ctx_arg->is_started()))
469  {
470  // Tracing enabled: must fully initialize the structure.
471  do_construct(ctx_arg, requires_key_arg, key, feature);
472  }
473  /*
474  Otherwise, just leave "started" to false, it marks that the structure is
475  dummy.
476  */
477  }
478  ~Opt_trace_struct() { if (unlikely(started)) do_destruct(); }
479 
480 public:
481 
487  void end() { if (unlikely(started)) do_destruct(); }
488 
521  Opt_trace_struct& add_alnum(const char *key, const char *value)
522  {
523  if (likely(!started))
524  return *this;
525  return do_add(key, value, strlen(value), false);
526  }
527 
534  Opt_trace_struct& add_alnum(const char *value)
535  {
536  if (likely(!started))
537  return *this;
538  return do_add(NULL, value, strlen(value), false);
539  }
540 
548  Opt_trace_struct& add_utf8(const char *key,
549  const char *value, size_t val_length)
550  {
551  if (likely(!started))
552  return *this;
553  return do_add(key, value, val_length, true);
554  }
555 
557  Opt_trace_struct& add_utf8(const char *value, size_t val_length)
558  {
559  if (likely(!started))
560  return *this;
561  return do_add(NULL, value, val_length, true);
562  }
563 
565  Opt_trace_struct& add_utf8(const char *key, const char *value)
566  {
567  if (likely(!started))
568  return *this;
569  return do_add(key, value, strlen(value), true);
570  }
571 
573  Opt_trace_struct& add_utf8(const char *value)
574  {
575  if (likely(!started))
576  return *this;
577  return do_add(NULL, value, strlen(value), true);
578  }
579 
589  Opt_trace_struct& add(const char *key, Item *item)
590  {
591  if (likely(!started))
592  return *this;
593  return do_add(key, item);
594  }
595  Opt_trace_struct& add(Item *item)
596  {
597  if (likely(!started))
598  return *this;
599  return do_add(NULL, item);
600  }
601 public:
602  Opt_trace_struct& add(const char *key, bool value)
603  {
604  if (likely(!started))
605  return *this;
606  return do_add(key, value);
607  }
608  Opt_trace_struct& add(bool value)
609  {
610  if (likely(!started))
611  return *this;
612  return do_add(NULL, value);
613  }
614  Opt_trace_struct& add(const char *key, int value)
615  {
616  if (likely(!started))
617  return *this;
618  return do_add(key, static_cast<longlong>(value));
619  }
620  Opt_trace_struct& add(int value)
621  {
622  if (likely(!started))
623  return *this;
624  return do_add(NULL, static_cast<longlong>(value));
625  }
626  Opt_trace_struct& add(const char *key, uint value)
627  {
628  if (likely(!started))
629  return *this;
630  return do_add(key, static_cast<ulonglong>(value));
631  }
632  Opt_trace_struct& add(uint value)
633  {
634  if (likely(!started))
635  return *this;
636  return do_add(NULL, static_cast<ulonglong>(value));
637  }
638  Opt_trace_struct& add(const char *key, ulong value)
639  {
640  if (likely(!started))
641  return *this;
642  return do_add(key, static_cast<ulonglong>(value));
643  }
644  Opt_trace_struct& add(ulong value)
645  {
646  if (likely(!started))
647  return *this;
648  return do_add(NULL, static_cast<ulonglong>(value));
649  }
650  Opt_trace_struct& add(const char *key, longlong value)
651  {
652  if (likely(!started))
653  return *this;
654  return do_add(key, value);
655  }
656  Opt_trace_struct& add(longlong value)
657  {
658  if (likely(!started))
659  return *this;
660  return do_add(NULL, value);
661  }
662  Opt_trace_struct& add(const char *key, ulonglong value)
663  {
664  if (likely(!started))
665  return *this;
666  return do_add(key, value);
667  }
668  Opt_trace_struct& add(ulonglong value)
669  {
670  if (likely(!started))
671  return *this;
672  return do_add(NULL, value);
673  }
674  Opt_trace_struct& add(const char *key, double value)
675  {
676  if (likely(!started))
677  return *this;
678  return do_add(key, value);
679  }
680  Opt_trace_struct& add(double value)
681  {
682  if (likely(!started))
683  return *this;
684  return do_add(NULL, value);
685  }
687  Opt_trace_struct& add_hex(const char *key, uint64 value)
688  {
689  if (likely(!started))
690  return *this;
691  return do_add_hex(key, value);
692  }
693  Opt_trace_struct& add_hex(uint64 value)
694  {
695  if (likely(!started))
696  return *this;
697  return do_add_hex(NULL, value);
698  }
700  Opt_trace_struct& add_null(const char *key)
701  {
702  if (likely(!started))
703  return *this;
704  return do_add_null(key);
705  }
710  Opt_trace_struct& add_utf8_table(const TABLE *tab)
711  {
712  if (likely(!started))
713  return *this;
714  return do_add_utf8_table(tab);
715  }
720  Opt_trace_struct& add_select_number(uint select_number)
721  {
722  return unlikely(select_number >= INT_MAX) ?
723  // Clearer than any huge number.
724  add_alnum("select#", "fake") :
725  add("select#", select_number);
726  }
727 
735  bool set_not_empty()
736  {
737  const bool old_empty= empty;
738  empty= false;
739  return old_empty;
740  }
774  const char *check_key(const char *key);
775 
776 private:
778  Opt_trace_struct& add(const char *key, const char* value);
779  Opt_trace_struct& add(const char *key);
780 
782  void do_construct(Opt_trace_context *ctx,
783  bool requires_key, const char *key,
786  void do_destruct();
793  Opt_trace_struct& do_add(const char *key, const char *value,
794  size_t val_length, bool escape);
795  Opt_trace_struct& do_add(const char *key, Item *item);
796  Opt_trace_struct& do_add(const char *key, bool value);
797  Opt_trace_struct& do_add(const char *key, longlong value);
798  Opt_trace_struct& do_add(const char *key, ulonglong value);
799  Opt_trace_struct& do_add(const char *key, double value);
800  Opt_trace_struct& do_add_hex(const char *key, uint64 value);
801  Opt_trace_struct& do_add_null(const char *key);
802  Opt_trace_struct& do_add_utf8_table(const TABLE *tab);
803 
804  Opt_trace_struct(const Opt_trace_struct&);
805  Opt_trace_struct& operator=(const Opt_trace_struct&);
806 
807  bool started;
808 
821  bool requires_key;
822 
828  bool has_disabled_I_S;
829  bool empty;
830  Opt_trace_stmt *stmt;
831 
832  const char *saved_key;
833 #ifndef DBUG_OFF
834 
839  char previous_key[25];
840 #endif
841 };
842 
843 
849 class Opt_trace_object: public Opt_trace_struct
850 {
851 public:
859  Opt_trace_object(Opt_trace_context *ctx, const char *key,
861  Opt_trace_context::MISC)
862  : Opt_trace_struct(ctx, true, key, feature)
863  {}
872  Opt_trace_context::MISC)
873  : Opt_trace_struct(ctx, true, NULL, feature)
874  {}
875 };
876 
877 
883 class Opt_trace_array: public Opt_trace_struct
884 {
885 public:
893  Opt_trace_array(Opt_trace_context *ctx, const char *key,
895  Opt_trace_context::MISC)
896  : Opt_trace_struct(ctx, false, key, feature)
897  {}
906  Opt_trace_context::MISC)
907  : Opt_trace_struct(ctx, false, NULL, feature)
908  {}
909 };
910 
911 
920 {
921 public:
953  Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg)
954  {
955  if (disable_arg)
956  {
957  ctx= ctx_arg;
958  ctx->disable_I_S_for_this_and_children();
959  }
960  else
961  ctx= NULL;
962  }
963 
966  {
967  if (ctx != NULL)
968  ctx->restore_I_S();
969  }
970 
971 private:
973  Opt_trace_context *ctx;
974  Opt_trace_disable_I_S(const Opt_trace_disable_I_S&); // not defined
975  Opt_trace_disable_I_S& operator=(const Opt_trace_disable_I_S&);//not defined
976 };
977 
978 
984 
1008 class Opt_trace_start
1009 {
1010 public:
1011  Opt_trace_start(THD *thd_arg, TABLE_LIST *tbl,
1012  enum enum_sql_command sql_command,
1013  List<set_var_base> *set_vars,
1014  const char *query, size_t query_length,
1015  sp_printable *instr,
1016  const CHARSET_INFO *query_charset);
1017  ~Opt_trace_start();
1018 private:
1019  Opt_trace_context * const ctx;
1020  bool error;
1021 };
1022 
1023 
1024 class st_select_lex;
1033 void opt_trace_print_expanded_query(THD *thd,
1034  st_select_lex *select_lex,
1035  Opt_trace_object *trace_object);
1036 
1072 void opt_trace_disable_if_no_security_context_access(THD *thd);
1073 
1089 void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view,
1090  TABLE_LIST *underlying_tables);
1091 
1108 void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp);
1109 
1115 int fill_optimizer_trace_info(THD *thd, TABLE_LIST *tables, Item *cond);
1116 
1118 
1119 #else /* defined (OPTIMIZER_TRACE) */
1120 
1121 /* all empty */
1122 
1125 {
1126 public:
1127  Opt_trace_object(Opt_trace_context *ctx, const char *key,
1129  Opt_trace_context::MISC)
1130  {}
1133  Opt_trace_context::MISC)
1134  {}
1135  Opt_trace_object& add_alnum(const char *key, const char *value)
1136  { return *this; }
1137  Opt_trace_object& add_utf8(const char *key,
1138  const char *value, size_t val_length)
1139  { return *this; }
1140  Opt_trace_object& add_utf8(const char *key, const char *value)
1141  { return *this; }
1142  Opt_trace_object& add(const char *key, Item *item) { return *this; }
1143  Opt_trace_object& add(const char *key, bool value) { return *this; }
1144  Opt_trace_object& add(const char *key, int value) { return *this; }
1145  Opt_trace_object& add(const char *key, uint value) { return *this; }
1146  Opt_trace_object& add(const char *key, ulong value) { return *this; }
1147  Opt_trace_object& add(const char *key, longlong value) { return *this; }
1148  Opt_trace_object& add(const char *key, ulonglong value) { return *this; }
1149  Opt_trace_object& add(const char *key, double value) { return *this; }
1150  Opt_trace_object& add_hex(const char *key, uint64 value) { return *this; }
1151  Opt_trace_object& add_utf8_table(const TABLE *tab) { return *this; }
1152  Opt_trace_object& add_select_number(uint select_number) { return *this; }
1153  void end() {}
1154 };
1155 
1158 {
1159 public:
1160  Opt_trace_array(Opt_trace_context *ctx, const char *key,
1162  Opt_trace_context::MISC)
1163  {}
1166  Opt_trace_context::MISC)
1167  {}
1168  Opt_trace_array& add_alnum(const char *value) { return *this; }
1169  Opt_trace_array& add_utf8(const char *value, size_t val_length)
1170  { return *this; }
1171  Opt_trace_array& add_utf8(const char *value)
1172  { return *this; }
1173  Opt_trace_array& add(Item *item) { return *this; }
1174  Opt_trace_array& add(bool value) { return *this; }
1175  Opt_trace_array& add(int value) { return *this; }
1176  Opt_trace_array& add(uint value) { return *this; }
1177  Opt_trace_array& add(longlong value) { return *this; }
1178  Opt_trace_array& add(ulonglong value) { return *this; }
1179  Opt_trace_array& add(double value) { return *this; }
1180  Opt_trace_array& add_hex(uint64 value) { return *this; }
1181  Opt_trace_array& add_utf8_table(TABLE *tab) { return *this; }
1182  Opt_trace_array& add_select_number(uint select_number) { return *this; }
1183  void end() {}
1184 };
1185 
1188 {
1189 public:
1190  Opt_trace_disable_I_S(Opt_trace_context *ctx_arg, bool disable_arg) {}
1191 };
1192 
1194 {
1195 public:
1196  Opt_trace_start(THD *thd, const TABLE_LIST *tbl,
1197  enum enum_sql_command sql_command,
1198  List<set_var_base> *set_vars,
1199  const char *query, size_t query_length,
1200  sp_printable *instr,
1201  const CHARSET_INFO *query_charset) {}
1202 };
1203 
1204 #define opt_trace_print_expanded_query(thd, select_lex, trace_object) \
1205  do {} while (0)
1206 #define opt_trace_disable_if_no_view_access(thd, view, underlying_tables) \
1207  do {} while (0)
1208 #define opt_trace_disable_if_no_stored_proc_func_access(thd, sp) do{} while(0)
1209 #define opt_trace_disable_if_no_security_context_access(thd) do {} while (0)
1210 
1211 #endif /* OPTIMIZER_TRACE */
1212 
1231 #define OPT_TRACE_TRANSFORM(trace,object_level0,object_level1, \
1232  select_number,from,to) \
1233  Opt_trace_object object_level0(trace); \
1234  Opt_trace_object object_level1(trace, "transformation"); \
1235  object_level1.add_select_number(select_number); \
1236  object_level1.add_alnum("from", from).add_alnum("to", to);
1237 
1238 /*
1239  A debug binary without optimizer trace compiled in, will miss some
1240  debugging info, be less useful, so:
1241 */
1242 #if !defined(DBUG_OFF) && !defined(OPTIMIZER_TRACE)
1243 #error debug binaries must support optimizer trace
1244 #endif
1245 
1246 #endif /* OPT_TRACE_INCLUDED */