List:Commits« Previous MessageNext Message »
From:Guilhem Bichot Date:September 27 2010 8:02am
Subject:bzr push into mysql-next-mr-bugfixing branch (guilhem:3213 to 3214)
View as plain text  
 3214 Guilhem Bichot	2010-09-27
      WL4800_validate_json.py: detect non-unique keys.
      Review comment: add a "feature" parameter to the constructors of
      Opt_trace_object/array, and a system variable "optimizer_trace_features"
      which allows to select what features to trace; replaces
      optimizer_trace=skip_plan=off
     @ mysql-test/include/optimizer_trace.inc
        test filtering by feature
     @ mysql-test/suite/sys_vars/t/optimizer_trace_features_basic.test
        basic test for new system variable
     @ unittest/gunit/opt_trace-t.cc
        test filtering by feature

    added:
      mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result
      mysql-test/suite/sys_vars/t/optimizer_trace_features_basic.test
    modified:
      WL4800_TODO.txt
      WL4800_validate_json.py
      mysql-test/include/optimizer_trace.inc
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/r/optimizer_trace_no_prot.result
      mysql-test/r/optimizer_trace_ps_prot.result
      mysql-test/suite/sys_vars/r/optimizer_trace_basic.result
      sql/opt_trace.cc
      sql/opt_trace.h
      sql/opt_trace2server.cc
      sql/sql_class.h
      sql/sql_select.cc
      sql/sys_vars.cc
      unittest/gunit/opt_trace-t.cc
 3213 Guilhem Bichot	2010-09-24
      review comment: renamed "ooa" to "structure" or "struct".
      This may have made lines longer than 79 chars; I will fix them in a batch later

    modified:
      WL4800_TODO.txt
      sql/opt_trace.cc
      sql/opt_trace.h
      unittest/gunit/opt_trace-t.cc
=== modified file 'WL4800_TODO.txt'
--- a/WL4800_TODO.txt	2010-09-24 14:09:24 +0000
+++ b/WL4800_TODO.txt	2010-09-27 08:00:25 +0000
@@ -42,7 +42,7 @@ I find a proper combination of client/se
 the trace makes the server do wrong?). Review how escaping is done in
 opt_trace.cc.
 
-Review comments:
-- parameter for filtering
+Review comments left:
 - in doc, mention DUMPFILE instead of OUTFILE
+- more checks for non-unique keys?
 

=== modified file 'WL4800_validate_json.py'
--- a/WL4800_validate_json.py	2010-09-24 09:11:29 +0000
+++ b/WL4800_validate_json.py	2010-09-27 08:00:25 +0000
@@ -39,14 +39,28 @@ def check(trace, first_trace_line):
     global retcode
     s = "".join(trace)
     try:
-        json.loads(s)
+        parsed = json.loads(s)
     except:
-        print "error at line", first_trace_line
+        print "parse error at line", first_trace_line
         print sys.exc_info()
         print s
-        retcode=1
-    else:
-        print "ok at line", first_trace_line
+        retcode = 1
+        print
+        return
+    # detect non-unique keys in one object, by counting
+    # number of quote symbols ("'): the json module outputs only
+    # one of the non-unique keys, making the number of " and '
+    # smaller compared to the input string.
+    before = s.count('"') + s.count("'")
+    str_parsed = str(parsed)
+    after = str_parsed.count('"') + str_parsed.count("'")
+    if (before != after):
+        print "non-unique keys at line %d (%d vs %d)" % (first_trace_line, before, after)
+        print s
+        retcode = 1
+        print
+        return
+    print "ok at line", first_trace_line
     print
 
 all = open(sys.argv[1]).readlines()

=== modified file 'mysql-test/include/optimizer_trace.inc'
--- a/mysql-test/include/optimizer_trace.inc	2010-09-24 09:11:29 +0000
+++ b/mysql-test/include/optimizer_trace.inc	2010-09-27 08:00:25 +0000
@@ -138,10 +138,14 @@ set @@session.optimizer_prune_level=0;
 explain select * from t1,t2;
 select * from information_schema.OPTIMIZER_TRACE;
 # don't print plans:
-set optimizer_trace="skip_plan=on";
+select @@optimizer_trace_features;
+set @@optimizer_trace_features="greedy_search=off";
 explain select * from t1,t2;
 select * from information_schema.OPTIMIZER_TRACE;
-set optimizer_trace="skip_plan=off";
+set @@optimizer_trace_features="greedy_search=on,misc=off";
+explain select * from t1,t2;
+select * from information_schema.OPTIMIZER_TRACE;
+set @@optimizer_trace_features=default;
 set @@session.optimizer_prune_level=default;
 drop table t1, t2;
 

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2010-09-18 16:25:43 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2010-09-27 08:00:25 +0000
@@ -410,8 +410,14 @@ The following options may be given as th
  --optimizer-trace=name 
  Controls tracing of the Optimizer:
  optimizer_trace=option=val[,option=val...], where option
- is one of {enabled, end_marker, one_line, skip_plan} and
- val is one of {on, off, default}
+ is one of {enabled, end_marker, one_line} and val is one
+ of {on, off, default}
+ --optimizer-trace-features=name 
+ Enables/disables tracing of selected features of the
+ Optimizer:
+ optimizer_trace_features=option=val[,option=val...],
+ where option is one of {misc, greedy_search} and val is
+ one of {on, off, default}
  --optimizer-trace-limit=# 
  Maximum number of shown optimizer traces
  --optimizer-trace-max-mem-size=# 
@@ -863,6 +869,7 @@ optimizer-prune-level 1
 optimizer-search-depth 62
 optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,materialization=on,semijoin=on,loosescan=on,firstmatch=on,mrr=on,mrr_cost_based=off,index_condition_pushdown=on
 optimizer-trace 
+optimizer-trace-features misc=on,greedy_search=on
 optimizer-trace-limit 1
 optimizer-trace-max-mem-size 16384
 optimizer-trace-offset -1

=== modified file 'mysql-test/r/optimizer_trace_no_prot.result'
--- a/mysql-test/r/optimizer_trace_no_prot.result	2010-09-24 09:11:29 +0000
+++ b/mysql-test/r/optimizer_trace_no_prot.result	2010-09-27 08:00:25 +0000
@@ -1882,7 +1882,10 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
     }
   ] /* steps */
 }	0	0
-set optimizer_trace="skip_plan=on";
+select @@optimizer_trace_features;
+@@optimizer_trace_features
+misc=on,greedy_search=on
+set @@optimizer_trace_features="greedy_search=off";
 explain select * from t1,t2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
@@ -1924,9 +1927,7 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
             ] /* records_estimation */
           },
           {
-            "considered_execution_plans": [
-              "..."
-            ] /* considered_execution_plans */
+            "considered_execution_plans": "..."
           },
           {
             "attaching_conditions_to_tables": {
@@ -1948,7 +1949,15 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
     }
   ] /* steps */
 }	0	0
-set optimizer_trace="skip_plan=off";
+set @@optimizer_trace_features="greedy_search=on,misc=off";
+explain select * from t1,t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (BNL, regular buffers)
+select * from information_schema.OPTIMIZER_TRACE;
+QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	OS_MALLOC_ERROR
+0		0	0
+set @@optimizer_trace_features=default;
 set @@session.optimizer_prune_level=default;
 drop table t1, t2;
 set @@optimizer_switch='semijoin=off';
@@ -4715,7 +4724,7 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
 }	0	0
 select @@optimizer_trace|
 @@optimizer_trace
-enabled=off,end_marker=on,one_line=off,skip_plan=off
+enabled=off,end_marker=on,one_line=off
 set optimizer_trace="enabled=on";
 drop table optt;
 drop function f1;
@@ -4962,7 +4971,7 @@ drop view v1;
 select * from information_schema.SESSION_VARIABLES where
 VARIABLE_NAME="optimizer_trace";
 VARIABLE_NAME	VARIABLE_VALUE
-OPTIMIZER_TRACE	enabled=on,end_marker=on,one_line=off,skip_plan=off
+OPTIMIZER_TRACE	enabled=on,end_marker=on,one_line=off
 select * from information_schema.OPTIMIZER_TRACE;
 QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	OS_MALLOC_ERROR
 0	{

=== modified file 'mysql-test/r/optimizer_trace_ps_prot.result'
--- a/mysql-test/r/optimizer_trace_ps_prot.result	2010-09-24 09:11:29 +0000
+++ b/mysql-test/r/optimizer_trace_ps_prot.result	2010-09-27 08:00:25 +0000
@@ -1866,7 +1866,10 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
     }
   ] /* steps */
 }	0	0
-set optimizer_trace="skip_plan=on";
+select @@optimizer_trace_features;
+@@optimizer_trace_features
+misc=on,greedy_search=on
+set @@optimizer_trace_features="greedy_search=off";
 explain select * from t1,t2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
@@ -1908,9 +1911,7 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
             ] /* records_estimation */
           },
           {
-            "considered_execution_plans": [
-              "..."
-            ] /* considered_execution_plans */
+            "considered_execution_plans": "..."
           },
           {
             "attaching_conditions_to_tables": {
@@ -1932,7 +1933,15 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
     }
   ] /* steps */
 }	0	0
-set optimizer_trace="skip_plan=off";
+set @@optimizer_trace_features="greedy_search=on,misc=off";
+explain select * from t1,t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (BNL, regular buffers)
+select * from information_schema.OPTIMIZER_TRACE;
+QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	OS_MALLOC_ERROR
+0		0	0
+set @@optimizer_trace_features=default;
 set @@session.optimizer_prune_level=default;
 drop table t1, t2;
 set @@optimizer_switch='semijoin=off';
@@ -4691,7 +4700,7 @@ QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_
 }	0	0
 select @@optimizer_trace|
 @@optimizer_trace
-enabled=off,end_marker=on,one_line=off,skip_plan=off
+enabled=off,end_marker=on,one_line=off
 set optimizer_trace="enabled=on";
 drop table optt;
 drop function f1;
@@ -4938,7 +4947,7 @@ drop view v1;
 select * from information_schema.SESSION_VARIABLES where
 VARIABLE_NAME="optimizer_trace";
 VARIABLE_NAME	VARIABLE_VALUE
-OPTIMIZER_TRACE	enabled=on,end_marker=on,one_line=off,skip_plan=off
+OPTIMIZER_TRACE	enabled=on,end_marker=on,one_line=off
 select * from information_schema.OPTIMIZER_TRACE;
 QUERY_ID	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	OS_MALLOC_ERROR
 0	{

=== modified file 'mysql-test/suite/sys_vars/r/optimizer_trace_basic.result'
--- a/mysql-test/suite/sys_vars/r/optimizer_trace_basic.result	2010-05-24 18:38:10 +0000
+++ b/mysql-test/suite/sys_vars/r/optimizer_trace_basic.result	2010-09-27 08:00:25 +0000
@@ -1,45 +1,45 @@
 SET @start_global_value = @@global.optimizer_trace;
 SELECT @start_global_value;
 @start_global_value
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 select @@global.optimizer_trace;
 @@global.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 select @@session.optimizer_trace;
 @@session.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 show global variables like 'optimizer_trace';
 Variable_name	Value
-optimizer_trace	enabled=off,end_marker=off,one_line=off,skip_plan=off
+optimizer_trace	enabled=off,end_marker=off,one_line=off
 show session variables like 'optimizer_trace';
 Variable_name	Value
-optimizer_trace	enabled=off,end_marker=off,one_line=off,skip_plan=off
+optimizer_trace	enabled=off,end_marker=off,one_line=off
 select * from information_schema.global_variables where variable_name='optimizer_trace';
 VARIABLE_NAME	VARIABLE_VALUE
-OPTIMIZER_TRACE	enabled=off,end_marker=off,one_line=off,skip_plan=off
+OPTIMIZER_TRACE	enabled=off,end_marker=off,one_line=off
 select * from information_schema.session_variables where variable_name='optimizer_trace';
 VARIABLE_NAME	VARIABLE_VALUE
-OPTIMIZER_TRACE	enabled=off,end_marker=off,one_line=off,skip_plan=off
+OPTIMIZER_TRACE	enabled=off,end_marker=off,one_line=off
 set global optimizer_trace=10;
 select @@global.optimizer_trace;
 @@global.optimizer_trace
-enabled=off,end_marker=on,one_line=off,skip_plan=on
+enabled=off,end_marker=on,one_line=off
 set session optimizer_trace=10;
 select @@session.optimizer_trace;
 @@session.optimizer_trace
-enabled=off,end_marker=on,one_line=off,skip_plan=on
+enabled=off,end_marker=on,one_line=off
 set global optimizer_trace=0;
 select @@global.optimizer_trace;
 @@global.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 set session optimizer_trace=0;
 select @@session.optimizer_trace;
 @@session.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 set session optimizer_trace=default;
 select @@session.optimizer_trace;
 @@session.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off
 set global optimizer_trace=1.1;
 ERROR 42000: Incorrect argument type to variable 'optimizer_trace'
 set global optimizer_trace=1e1;
@@ -49,4 +49,4 @@ ERROR 42000: Variable 'optimizer_trace' 
 SET @@global.optimizer_trace = @start_global_value;
 SELECT @@global.optimizer_trace;
 @@global.optimizer_trace
-enabled=off,end_marker=off,one_line=off,skip_plan=off
+enabled=off,end_marker=off,one_line=off

=== added file 'mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result'
--- a/mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/optimizer_trace_features_basic.result	2010-09-27 08:00:25 +0000
@@ -0,0 +1,52 @@
+SET @start_global_value = @@global.optimizer_trace_features;
+SELECT @start_global_value;
+@start_global_value
+misc=on,greedy_search=on
+select @@global.optimizer_trace_features;
+@@global.optimizer_trace_features
+misc=on,greedy_search=on
+select @@session.optimizer_trace_features;
+@@session.optimizer_trace_features
+misc=on,greedy_search=on
+show global variables like 'optimizer_trace_features';
+Variable_name	Value
+optimizer_trace_features	misc=on,greedy_search=on
+show session variables like 'optimizer_trace_features';
+Variable_name	Value
+optimizer_trace_features	misc=on,greedy_search=on
+select * from information_schema.global_variables where variable_name='optimizer_trace_features';
+VARIABLE_NAME	VARIABLE_VALUE
+OPTIMIZER_TRACE_FEATURES	misc=on,greedy_search=on
+select * from information_schema.session_variables where variable_name='optimizer_trace_features';
+VARIABLE_NAME	VARIABLE_VALUE
+OPTIMIZER_TRACE_FEATURES	misc=on,greedy_search=on
+set global optimizer_trace_features=2;
+select @@global.optimizer_trace_features;
+@@global.optimizer_trace_features
+misc=off,greedy_search=on
+set session optimizer_trace_features=2;
+select @@session.optimizer_trace_features;
+@@session.optimizer_trace_features
+misc=off,greedy_search=on
+set global optimizer_trace_features=0;
+select @@global.optimizer_trace_features;
+@@global.optimizer_trace_features
+misc=off,greedy_search=off
+set session optimizer_trace_features=0;
+select @@session.optimizer_trace_features;
+@@session.optimizer_trace_features
+misc=off,greedy_search=off
+set session optimizer_trace_features=default;
+select @@session.optimizer_trace_features;
+@@session.optimizer_trace_features
+misc=off,greedy_search=off
+set global optimizer_trace_features=1.1;
+ERROR 42000: Incorrect argument type to variable 'optimizer_trace_features'
+set global optimizer_trace_features=1e1;
+ERROR 42000: Incorrect argument type to variable 'optimizer_trace_features'
+set session optimizer_trace_features="foobar";
+ERROR 42000: Variable 'optimizer_trace_features' can't be set to the value of 'foobar'
+SET @@global.optimizer_trace_features = @start_global_value;
+SELECT @@global.optimizer_trace_features;
+@@global.optimizer_trace_features
+misc=on,greedy_search=on

=== added file 'mysql-test/suite/sys_vars/t/optimizer_trace_features_basic.test'
--- a/mysql-test/suite/sys_vars/t/optimizer_trace_features_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/optimizer_trace_features_basic.test	2010-09-27 08:00:25 +0000
@@ -0,0 +1,41 @@
+--source include/have_optimizer_trace.inc
+
+SET @start_global_value = @@global.optimizer_trace_features;
+SELECT @start_global_value;
+
+#
+# exists as global and session
+#
+select @@global.optimizer_trace_features;
+select @@session.optimizer_trace_features;
+show global variables like 'optimizer_trace_features';
+show session variables like 'optimizer_trace_features';
+select * from information_schema.global_variables where variable_name='optimizer_trace_features';
+select * from information_schema.session_variables where variable_name='optimizer_trace_features';
+
+#
+# show that it's writable
+#
+set global optimizer_trace_features=2;
+select @@global.optimizer_trace_features;
+set session optimizer_trace_features=2;
+select @@session.optimizer_trace_features;
+set global optimizer_trace_features=0;
+select @@global.optimizer_trace_features;
+set session optimizer_trace_features=0;
+select @@session.optimizer_trace_features;
+set session optimizer_trace_features=default;
+select @@session.optimizer_trace_features;
+
+#
+# incorrect assignments
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global optimizer_trace_features=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global optimizer_trace_features=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+set session optimizer_trace_features="foobar";
+
+SET @@global.optimizer_trace_features = @start_global_value;
+SELECT @@global.optimizer_trace_features;

=== modified file 'sql/opt_trace.cc'
--- a/sql/opt_trace.cc	2010-09-24 14:09:24 +0000
+++ b/sql/opt_trace.cc	2010-09-27 08:00:25 +0000
@@ -54,9 +54,10 @@ void Opt_trace_struct::syntax_error(cons
 
 
 void Opt_trace_struct::do_construct(Opt_trace_stmt *stmt_arg,
-                                 Opt_trace_struct *parent_arg,
-                                 bool requires_key_arg,
-                                 const char *key)
+                                    Opt_trace_struct *parent_arg,
+                                    bool requires_key_arg,
+                                    const char *key,
+                                    Opt_trace_context::feature_value feature)
 {
   saved_key= key;
   requires_key= requires_key_arg;
@@ -69,6 +70,24 @@ void Opt_trace_struct::do_construct(Opt_
 #ifndef DBUG_OFF
   previous_key[0]= 0;
 #endif
+  save_stmt_support_I_S=
+    stmt->support_I_S;
+  if (save_stmt_support_I_S &&
+      (feature & stmt->ctx->features) == 0)
+  {
+    /*
+      User requested no tracing for this structure's feature. We are entering
+      a disabled portion; put an ellipsis "..." to alert the user
+    */
+    if (stmt->current_struct != NULL)
+    {
+      if (key != NULL)
+        stmt->current_struct->add(key, "...");
+      else
+        stmt->current_struct->add("...");
+    }
+    stmt->support_I_S= false; // disable tracing for this struct and children
+  }
   if (stmt->support_I_S)
   {
     const size_t alloced=   stmt->buffer.alloced_length();
@@ -168,17 +187,19 @@ void Opt_trace_struct::do_destruct(void)
   */
   stmt->current_struct= parent;
   DBUG_ASSERT(parent == NULL || stmt == parent->stmt);
-  if (!stmt->support_I_S)
-    return;
-  stmt->pop();
-  stmt->next_line();
-  stmt->buffer.append(brackets[requires_key + 2]);
-  if (stmt->ctx->end_marker && saved_key != NULL)
-  {
-    stmt->buffer.append(" /* ");
-    stmt->buffer.append(saved_key);
-    stmt->buffer.append(" */");
+  if (stmt->support_I_S)
+  {
+    stmt->pop();
+    stmt->next_line();
+    stmt->buffer.append(brackets[requires_key + 2]);
+    if (stmt->ctx->end_marker && saved_key != NULL)
+    {
+      stmt->buffer.append(" /* ");
+      stmt->buffer.append(saved_key);
+      stmt->buffer.append(" */");
+    }
   }
+  stmt->support_I_S= save_stmt_support_I_S;
 }
 
 
@@ -301,9 +322,17 @@ Opt_trace_struct& Opt_trace_struct::do_a
 
 const char *Opt_trace_context::flag_names[]=
 {
-  "enabled", "end_marker", "one_line", "skip_plan", "default", NullS
+  "enabled", "end_marker", "one_line", "default", NullS
+};
+
+const char *Opt_trace_context::feature_names[]=
+{
+  "misc", "greedy_search", "default", NullS
 };
 
+const Opt_trace_context::feature_value Opt_trace_context::FEATURES_DEFAULT=
+  Opt_trace_context::feature_value(Opt_trace_context::MISC |
+                                   Opt_trace_context::GREEDY_SEARCH);
 
 Opt_trace_context::Opt_trace_context(void):
   oldest_stmt_to_show(NULL), newest_stmt_to_show(NULL), stmt_to_del(NULL),
@@ -457,7 +486,8 @@ bool Opt_trace_context::start(bool suppo
                               bool one_line_arg,
                               long offset_arg,
                               long limit_arg,
-                              ulong max_mem_size_arg)
+                              ulong max_mem_size_arg,
+                              feature_value features_arg)
 {
   DBUG_ENTER("Opt_trace_context::start");
   /*
@@ -496,6 +526,7 @@ bool Opt_trace_context::start(bool suppo
     offset= offset_arg;
     limit= limit_arg;
     max_mem_size= max_mem_size_arg;
+    features= features_arg;
   }
   /*
     Decide whether to-be-created trace should support I_S.

=== modified file 'sql/opt_trace.h'
--- a/sql/opt_trace.h	2010-09-24 14:09:24 +0000
+++ b/sql/opt_trace.h	2010-09-27 08:00:25 +0000
@@ -332,6 +332,39 @@ class Opt_trace_context
 public:
   Opt_trace_context(void);
   ~Opt_trace_context(void);
+
+  /**
+     Flags' names for @@@@optimizer_trace variable of @c sys_vars.cc :
+     @li "enabled" = tracing enabled
+     @li "end_marker" = see parameter of @ref Opt_trace_context::start
+     @li "one_line"= see parameter of @ref Opt_trace_context::start
+     @li "default".
+  */
+  static const char *flag_names[];
+  /** Flags' numeric values for @@@@optimizer_trace variable */
+  enum flag_value {
+    FLAG_DEFAULT= 0, FLAG_ENABLED= 1, FLAG_END_MARKER= 2, FLAG_ONE_LINE= 4
+  };
+  /**
+     Features' names for @@@@optimizer_trace_features variable of
+     @c sys_vars.cc:
+     @li "misc" = anything unclassified
+     @li "greedy_search" = the greedy search for a plan
+     @li "default".
+  */
+  static const char *feature_names[];
+  /** Features' numeric values for @@@@optimizer_trace_features variable */
+  enum feature_value {
+    /**
+       Anything unclassified, including the top object (thus, by "inheritance
+       from parent", disabling MISC makes an empty trace).
+    */
+    MISC= 1,
+    GREEDY_SEARCH= 2 ///@todo range opt, join cache, semijoin...
+    /* if you add here, update FEATURES_DEFAULT! */
+  };
+  static const feature_value FEATURES_DEFAULT;
+
   /**
      Starts a new trace.
      @param  need_it_for_I_S  should trace produce output suitable for
@@ -355,12 +388,14 @@ public:
      @param  limit            limit for restricting trace production
      @param  max_mem_size     maximum allowed for cumulated size of all
                               remembered traces
+     @param  features         only those optimizer features should be traced
 
      @retval false            ok
      @retval true             error (OOM)
   */
   bool start(bool need_it_for_I_S, bool end_marker, bool one_line,
-             long offset, long limit, ulong max_mem_size);
+             long offset, long limit, ulong max_mem_size,
+             feature_value features);
   /** Ends the current trace */
   void end(void);
   /** Returns whether there is a current trace */
@@ -379,22 +414,6 @@ public:
   */
   void reset(void);
 
-  /**
-     Flags' names for @@@@optimizer_trace variable of @c sys_vars.cc :
-     @li "enabled" = tracing enabled
-     @li "end_marker" = see parameter of @ref Opt_trace_context::start
-     @li "one_line"= see parameter of @ref Opt_trace_context::start
-     @li "skip_plan" = no tracing of plan search (mandatory when using many
-     tables, due to combinatorial explosion in @c greedy_search())
-     @li "default".
-  */
-  static const char *flag_names[];
-  /** Flags' numeric values for @@@@optimizer_trace variable */
-  enum flag_values {
-    FLAG_DEFAULT= 0, FLAG_ENABLED= 1, FLAG_END_MARKER= 2, FLAG_ONE_LINE= 4,
-    FLAG_SKIP_PLAN= 8
-  };
-
 private:
 
   /**
@@ -454,6 +473,7 @@ private:
   long offset;      ///< copy of parameter of Opt_trace_context::start
   long limit;       ///< copy of parameter of Opt_trace_context::start
   size_t max_mem_size; ///< copy of parameter of Opt_trace_context::start
+  feature_value features; ///< copy of parameter of Opt_trace_context::start
 
   /** Whether the settings above may be changed for a new trace */
   bool cannot_change_settings;
@@ -669,11 +689,13 @@ protected:
                       NULL otherwise. This pointer must remain constant and
                       valid until the object is destroyed (to support
                       @ref saved_key).
+     @param  feature  optimizer feature to which this objects belong
 
      This constructor is never called directly, only from subclasses.
   */
   Opt_trace_struct(Opt_trace_context *ctx_arg, bool requires_key,
-                const char *key) :
+                   const char *key,
+                   Opt_trace_context::feature_value feature) :
     started(false)
   {
     /* A first inlined test */
@@ -682,7 +704,7 @@ protected:
       /* tracing enabled: must fully initialize the structure */
       do_construct(ctx_arg->current_stmt_in_gen,
                    ctx_arg->current_stmt_in_gen->current_struct,
-                   requires_key, key);
+                   requires_key, key, feature);
     }
     /*
       Otherwise, just leave "started" to false, it marks that the structure is
@@ -862,7 +884,8 @@ private:
   void do_construct(Opt_trace_stmt *stmt,
                     Opt_trace_struct *parent,
                     bool requires_key,
-                    const char *key);
+                    const char *key,
+                    Opt_trace_context::feature_value feature);
   /** Really does destruction */
   void do_destruct(void);
   /** Really adds to the object. @sa add() */
@@ -950,6 +973,14 @@ private:
   char previous_key[20];
 #endif
 
+  /**
+     A structure may, because it belongs to a feature for which tracing is not
+     wanted, disable the statement's tracing; it will thus apply to all the
+     structure's children. When the structure is destroyed, it restores the
+     initial setting.
+  */
+  bool save_stmt_support_I_S;
+
   /** opening and closing symbols for arrays ([])and objects ({}) */
   static const char brackets[];
   /** human-readable names of structure types */
@@ -971,15 +1002,25 @@ class Opt_trace_object: public Opt_trace
 {
 public:
   /**
-     Constructs an object. If a key is specified, the object is the value of a
-     key/value pair (serves for adding the object to an object). Otherwise the
-     object is just a value (serves for the single root object, or for adding
-     the object to an array).
+     Constructs an object. Key is specified, so the object is the value of a
+     key/value pair.
+     @param  ctx  context for this object
+     @param  key  key
+  */
+  Opt_trace_object(Opt_trace_context *ctx, const char *key,
+                   Opt_trace_context::feature_value feature=
+                   Opt_trace_context::MISC) :
+  Opt_trace_struct(ctx, true, key, feature) {}
+  /**
+     Constructs an object. No key is specified, so the object is just a value
+     (serves for the single root object, or for adding the object to an array).
      @param  ctx  context for this object
-     @param  key  optional key
   */
-  Opt_trace_object(Opt_trace_context *ctx, const char *key= NULL) :
-  Opt_trace_struct(ctx, true, key) {}
+  Opt_trace_object(Opt_trace_context *ctx,
+                   Opt_trace_context::feature_value feature=
+                   Opt_trace_context::MISC) :
+  Opt_trace_struct(ctx, true, NULL, feature) {}
+
 };
 
 
@@ -991,14 +1032,18 @@ class Opt_trace_array: public Opt_trace_
 {
 public:
   /**
-     Constructs an array. If a key is specified, the array is the value of a
-     key/value pair (serves for adding the array to an object). Otherwise the
-     array is just a value (serves for adding the array to an array).
+     Constructs an array. @sa Opt_trace_object::Opt_trace_object.
      @param  ctx  context for this array
-     @param  key  optional key
+     @param  key  key
   */
-  Opt_trace_array(Opt_trace_context *ctx, const char *key= NULL) :
-  Opt_trace_struct(ctx, false, key) {}
+  Opt_trace_array(Opt_trace_context *ctx, const char *key,
+                  Opt_trace_context::feature_value feature=
+                  Opt_trace_context::MISC) :
+  Opt_trace_struct(ctx, false, key, feature) {}
+  Opt_trace_array(Opt_trace_context *ctx,
+                  Opt_trace_context::feature_value feature=
+                  Opt_trace_context::MISC) :
+  Opt_trace_struct(ctx, false, NULL, feature) {}
 };
 
 
@@ -1012,6 +1057,8 @@ public:
    undesirable, so it is silenced with such object below (trace only goes to
    DBUG then, for the duration of @c TEST_join()).
    Re-enabling happens when the instance is destroyed.
+   Note that this class should rarely be used; the "feature" parameter of
+   Opt_trace_struct is a good alternative.
 */
 class Opt_trace_disable_I_S
 {
@@ -1138,12 +1185,21 @@ extern ST_FIELD_INFO optimizer_trace_inf
 /* all empty */
 
 class Opt_trace_context
-{};
+{
+public:
+  /* We need this one */
+  enum feature_value { MISC= 1, GREEDY_SEARCH= 2 };
+};
 
 class Opt_trace_object
 {
 public:
-  Opt_trace_object(Opt_trace_context *ctx, const char *key= NULL) {}
+  Opt_trace_object(Opt_trace_context *ctx, const char *key,
+                   Opt_trace_context::feature_value feature=
+                   Opt_trace_context::MISC) {}
+  Opt_trace_object(Opt_trace_context *ctx,
+                   Opt_trace_context::feature_value feature=
+                   Opt_trace_context::MISC) {}
   static void *operator new(size_t size, MEM_ROOT *mem_root)
   { return (void*) alloc_root(mem_root, (uint) size); }
   Opt_trace_object& add(const char *key, const char *value) { return *this; }
@@ -1160,7 +1216,12 @@ public:
 class Opt_trace_array
 {
 public:
-  Opt_trace_array(Opt_trace_context *ctx, const char *key= NULL) {}
+  Opt_trace_array(Opt_trace_context *ctx, const char *key,
+                  Opt_trace_context::feature_value feature=
+                  Opt_trace_context::MISC) {}
+  Opt_trace_array(Opt_trace_context *ctx,
+                  Opt_trace_context::feature_value feature=
+                  Opt_trace_context::MISC) {}
   static void *operator new(size_t size, MEM_ROOT *mem_root)
   { return (void*) alloc_root(mem_root, (uint) size); }
   Opt_trace_array& add(const char *value) { return *this; }

=== modified file 'sql/opt_trace2server.cc'
--- a/sql/opt_trace2server.cc	2010-09-22 19:50:59 +0000
+++ b/sql/opt_trace2server.cc	2010-09-27 08:00:25 +0000
@@ -90,7 +90,8 @@ bool opt_trace_start(THD *thd, TABLE_LIS
                             (var & Opt_trace_context::FLAG_ONE_LINE),
                             thd->variables.optimizer_trace_offset,
                             thd->variables.optimizer_trace_limit,
-                            thd->variables.optimizer_trace_max_mem_size))
+                            thd->variables.optimizer_trace_max_mem_size,
+                            Opt_trace_context::feature_value(thd->variables.optimizer_trace_features)))
   {
     delete thd->opt_trace;
     thd->opt_trace= NULL;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-09-18 16:25:43 +0000
+++ b/sql/sql_class.h	2010-09-27 08:00:25 +0000
@@ -387,6 +387,7 @@ typedef struct system_variables
   /* A bitmap for switching optimizations on/off */
   ulonglong optimizer_switch;
   ulonglong optimizer_trace; ///< bitmap to tune optimizer tracing
+  ulonglong optimizer_trace_features; ///< bitmap to select features to trace
   long      optimizer_trace_offset;
   long      optimizer_trace_limit;
   ulong     optimizer_trace_max_mem_size;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-09-24 09:11:29 +0000
+++ b/sql/sql_select.cc	2010-09-27 08:00:25 +0000
@@ -7886,13 +7886,6 @@ greedy_search(JOIN      *join,
   JOIN_TAB  *best_table; // the next plan node to be added to the curr QEP
   uint      n_tables; // ==join->tables or # tables in the sj-mat nest we're optimizing
   Opt_trace_context *opt_trace= join->thd->opt_trace;
-#ifdef OPTIMIZER_TRACE
-  bool      skip_plan_tracing= join->thd->variables.optimizer_trace &
-    Opt_trace_context::FLAG_SKIP_PLAN;
-#else
-  const bool skip_plan_tracing= false;
-#endif
-
   DBUG_ENTER("greedy_search");
 
   ulonglong now= my_getsystime();
@@ -7904,10 +7897,8 @@ greedy_search(JOIN      *join,
                                          ~(table_map)0));
 
   Opt_trace_object oto0(opt_trace);
-  Opt_trace_array ota(opt_trace, "considered_execution_plans");
-  if (unlikely(skip_plan_tracing))
-    OPT_TRACE(opt_trace, add("..."));
-  Opt_trace_disable_I_S otd(opt_trace, skip_plan_tracing);
+  Opt_trace_array ota(opt_trace, "considered_execution_plans",
+                      Opt_trace_context::GREEDY_SEARCH);
 
   do {
     /* Find the extension of the current QEP with the lowest cost */

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-09-18 16:25:43 +0000
+++ b/sql/sys_vars.cc	2010-09-27 08:00:25 +0000
@@ -1403,12 +1403,22 @@ static Sys_var_flagset Sys_optimizer_tra
        "optimizer_trace",
        "Controls tracing of the Optimizer:"
        " optimizer_trace=option=val[,option=val...], where option is one of"
-       " {enabled, end_marker, one_line, skip_plan}"
+       " {enabled, end_marker, one_line}"
        " and val is one of {on, off, default}",
        SESSION_VAR(optimizer_trace), CMD_LINE(REQUIRED_ARG),
        Opt_trace_context::flag_names,
        DEFAULT(Opt_trace_context::FLAG_DEFAULT));
 
+static Sys_var_flagset Sys_optimizer_trace_features(
+       "optimizer_trace_features",
+       "Enables/disables tracing of selected features of the Optimizer:"
+       " optimizer_trace_features=option=val[,option=val...], where option is one of"
+       " {misc, greedy_search}"
+       " and val is one of {on, off, default}",
+       SESSION_VAR(optimizer_trace_features), CMD_LINE(REQUIRED_ARG),
+       Opt_trace_context::feature_names,
+       DEFAULT(Opt_trace_context::FEATURES_DEFAULT));
+
 /** Delete all old optimizer traces */
 static bool optimizer_trace_update(sys_var *self, THD *thd,
                                    enum_var_type type)

=== modified file 'unittest/gunit/opt_trace-t.cc'
--- a/unittest/gunit/opt_trace-t.cc	2010-09-24 14:09:24 +0000
+++ b/unittest/gunit/opt_trace-t.cc	2010-09-27 08:00:25 +0000
@@ -29,13 +29,15 @@
 CHARSET_INFO *system_charset_info= &my_charset_utf8_general_ci;
 /* ... end here. */
 
+const Opt_trace_context::feature_value all_features=
+  Opt_trace_context::FEATURES_DEFAULT;
 
 /** Test empty trace */
 TEST(Trace_content_test, empty)
 {
   /* Create a trace */
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, false, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, false, false, -1, 1, 0, all_features));
   /*
     Add at least an object to it. A really empty trace ("") is not
     JSON-compliant, at least Python's JSON module raises an exception.
@@ -64,7 +66,7 @@ TEST(Trace_content_test, empty)
 TEST(Trace_content_test, normal_usage)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -124,7 +126,7 @@ TEST(Trace_content_test, normal_usage)
 TEST(Trace_content_test, tail)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -182,7 +184,7 @@ TEST(Trace_content_test, tail)
 TEST(Trace_content_test, buggy_object)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -238,7 +240,7 @@ TEST(Trace_content_test, buggy_object)
 TEST(Trace_content_test, buggy_array)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -283,7 +285,7 @@ TEST(Trace_content_test, buggy_array)
 TEST(Trace_content_test, disable_I_S)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -348,7 +350,8 @@ TEST(Trace_content_test, disable_I_S)
 static void make_one_trace(Opt_trace_context &trace, const char *name,
                            long offset, long limit)
 {
-  ASSERT_EQ(false, trace.start(true, true, false, offset, limit, 0));
+  ASSERT_EQ(false, trace.start(true, true, false, offset, limit, 0,
+                               all_features));
   {
     Opt_trace_object oto(&trace);
     oto.add(name, 0LL);
@@ -449,7 +452,7 @@ TEST(Trace_settings_test, max_mem_size)
 {
   Opt_trace_context trace;
   ASSERT_EQ(false, trace.start(true, false, false, -1, 1,
-                               1000 /* max_mem_size */));
+                               1000 /* max_mem_size */, all_features));
   /* make a "long" trace */
   {
     Opt_trace_object oto(&trace);
@@ -488,7 +491,7 @@ TEST(Trace_settings_test, max_mem_size2)
 {
   Opt_trace_context trace;
   ASSERT_EQ(false, trace.start(true, false, false, -2, 2,
-                               21 /* max_mem_size */));
+                               21 /* max_mem_size */, all_features));
   /* make a "long" trace */
   {
     Opt_trace_object oto(&trace);
@@ -496,7 +499,7 @@ TEST(Trace_settings_test, max_mem_size2)
   }
   trace.end();
   /* A second similar trace */
-  ASSERT_EQ(false, trace.start(true, false, false, -2, 2, 21));
+  ASSERT_EQ(false, trace.start(true, false, false, -2, 2, 21, all_features));
   {
     Opt_trace_object oto(&trace);
     oto.add("some key2", "make it long");
@@ -520,7 +523,7 @@ TEST(Trace_settings_test, max_mem_size2)
     3rd trace; the first one should automatically be purged, thus the 3rd
     should have a bit of room.
   */
-  ASSERT_EQ(false, trace.start(true, false, false, -2, 2, 21));
+  ASSERT_EQ(false, trace.start(true, false, false, -2, 2, 21, all_features));
   {
     Opt_trace_object oto(&trace);
     oto.add("some key3", "make it long");
@@ -551,7 +554,7 @@ TEST(Trace_settings_test, max_mem_size2)
 TEST(Trace_content_test, out_of_memory)
 {
   Opt_trace_context trace;
-  ASSERT_EQ(false, trace.start(true, false, false, -1, 1, 0));
+  ASSERT_EQ(false, trace.start(true, false, false, -1, 1, 0, all_features));
   {
     Opt_trace_object oto(&trace);
     {
@@ -580,4 +583,65 @@ TEST(Trace_content_test, out_of_memory)
 }
 #endif // !DBUG_OFF
 
+
+/** Test filtering by feature */
+TEST(Trace_content_test, filtering_by_feature)
+{
+  Opt_trace_context trace;
+  ASSERT_EQ(false, trace.start(true, false, false, -1, 1, 0,
+                               Opt_trace_context::MISC));
+  {
+    Opt_trace_object oto(&trace);
+    {
+      Opt_trace_array ota(&trace, "one array");
+      ota.add(200.4);
+      {
+        Opt_trace_object oto1(&trace, Opt_trace_context::GREEDY_SEARCH);
+        oto1.add("one key", "one value").
+          add("another key", 100LL);
+        Opt_trace_object oto2(&trace, "a fourth key",
+                              Opt_trace_context::MISC);
+        oto2.add("another key inside", 5LL);
+      }
+      ota.add(true);
+    }
+    {
+      Opt_trace_object oto3(&trace, "key for oto3",
+                            Opt_trace_context::GREEDY_SEARCH);
+      oto3.add("etc", 25);
+    }
+    oto.add("yet another key", -1000LL);
+    {
+      Opt_trace_array ota(&trace, "another array");
+      ota.add(1LL).add(2LL).add(3LL).add(4LL);
+    }
+  }
+  trace.end();
+  Opt_trace_iterator it(&trace);
+  ASSERT_EQ(true, it != Opt_trace_iterator::end);
+  const Opt_trace_info info= *it;
+  const char expected[]=
+    "{\n"
+    "  \"one array\": [\n"
+    "    200.4,\n"
+    "    \"...\",\n"
+    "    true\n"
+    "  ],\n"
+    "  \"key for oto3\": \"...\",\n"
+    "  \"yet another key\": -1000,\n"
+    "  \"another array\": [\n"
+    "    1,\n"
+    "    2,\n"
+    "    3,\n"
+    "    4\n"
+    "  ]\n"
+    "}";
+  ASSERT_STREQ(expected, info.ptr);
+  ASSERT_EQ(sizeof(expected) - 1, info.length);
+  ASSERT_EQ((size_t)0, info.missing_bytes);
+  ASSERT_EQ(false, info.malloc_error);
+  it++;
+  ASSERT_EQ(false, it != Opt_trace_iterator::end);
+}
+
 #endif // OPTIMIZER_TRACE


Attachment: [text/bzr-bundle] bzr/guilhem@mysql.com-20100927080025-k7l20zgflvnhlj2t.bundle
Thread
bzr push into mysql-next-mr-bugfixing branch (guilhem:3213 to 3214) Guilhem Bichot27 Sep