← Back to team overview

maria-developers team mailing list archive

[Branch ~maria-captains/maria/5.1] Rev 2726: Updated documentation files to reflect MariaDB and not the Maria storage engine or MySQL

 

Merge authors:
  Michael Widenius (monty)
------------------------------------------------------------
revno: 2726 [merge]
committer: Michael Widenius <monty@xxxxxxxxx>
branch nick: maria
timestamp: Thu 2009-09-03 17:56:46 +0300
message:
  Updated documentation files to reflect MariaDB and not the Maria storage engine or MySQL
  Added (rewritten) patch from Percona to get extended statistics in slow.log:
  - Added handling of 'set' variables to set_var.cc. Changed sql_mode to use this
  - Added extra logging to slow log of 'Thread_id, Schema, Query Cache hit, Rows sent and Rows examined'
  - Added optional logging to slow log, through log_slow_verbosity, of query plan statistics
  - Added new user variables log_slow_rate_limit, log_slow_verbosity, log_slow_filter
  - Added log-slow-file as synonym for 'slow-log-file', as most slow-log variables starts with 'log-slow'
  - Added log-slow-time as synonym for long-query-time
  Some trivial MyISAM optimizations:
  - In prepare for drop, flush key blocks
  - Don't call mi_lock_database if my_disable_locking is used
  ******
  Automatic merge with trunc
  ******
  Updated documentation files to reflect MariaDB and not the Maria storage engine or MySQL
  Added (rewritten) patch from Percona to get extended statistics in slow.log:
  - Added handling of 'set' variables to set_var.cc. Changed sql_mode to use this
  - Added extra logging to slow log of 'Thread_id, Schema, Query Cache hit, Rows sent and Rows examined'
  - Added optional logging to slow log, through log_slow_verbosity, of query plan statistics
  - Added new user variables log_slow_rate_limit, log_slow_verbosity, log_slow_filter
  - Added log-slow-file as synonym for 'slow-log-file', as most slow-log variables starts with 'log-slow'
  - Added log-slow-time as synonym for long-query-time
  Some trivial MyISAM optimizations:
  - In prepare for drop, flush key blocks
  - Don't call mi_lock_database if my_disable_locking is used
added:
  mysql-test/r/log_slow.result
  mysql-test/t/log_slow.test
  sql/log_slow.h
modified:
  KNOWN_BUGS.txt
  README
  mysql-test/r/variables.result
  sql/Makefile.am
  sql/event_data_objects.cc
  sql/events.cc
  sql/filesort.cc
  sql/log.cc
  sql/mysql_priv.h
  sql/mysqld.cc
  sql/set_var.cc
  sql/set_var.h
  sql/slave.cc
  sql/sp_head.cc
  sql/sql_cache.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_parse.cc
  sql/sql_select.cc
  sql/sql_show.cc
  sql/strfunc.cc
  storage/myisam/mi_extra.c
  storage/myisam/mi_locking.c


--
lp:maria
https://code.launchpad.net/~maria-captains/maria/5.1

Your team Maria developers is subscribed to branch lp:maria.
To unsubscribe from this branch go to https://code.launchpad.net/~maria-captains/maria/5.1/+edit-subscription.
=== modified file 'KNOWN_BUGS.txt'
--- KNOWN_BUGS.txt	2008-12-02 22:02:52 +0000
+++ KNOWN_BUGS.txt	2009-09-03 14:05:38 +0000
@@ -1,86 +1,35 @@
-This file should contain all know fatal bugs in the Maria storage
-engine for the last source or binary release.  Minor bugs, extensions
-and feature request and bugs found since this release can be find in the
-MySQL bugs databases at: http://bugs.mysql.com/ (category "Maria
-storage engine").
+This file should contain all know fatal bugs in the Mariadb and the
+Maria storage engine for the last source or binary release.  Minor
+bugs, extensions and feature request and bugs found since this release
+can be find in the MariaDB bugs database at:
+https://bugs.launchpad.net/maria and in the MySQL bugs databases at:
+http://bugs.mysql.com/ (category "Maria storage engine").
 
 There shouldn't normally be any bugs that affects normal operations in
-any Maria release.  Still, there are always exceptions and edge cases
+any MariaDB release.  Still, there are always exceptions and edge cases
 and that's what this file is for.
 
-For the first few Alpha releases of Maria there may be some edge cases
-that crashes during recovery; We don't like that but we think it's
-better to get the Maria alpha out early to get things tested and get
-more developers on the code early than wait until these are fixed.  We
-do however think that the bugs are not seriously enough to stop anyone
-from starting to test and even use Maria for real (as long as they are
-prepared to upgrade to next MySQL-Maria release ASAP).
-
 If you have found a bug that is not listed here, please add it to
-http://bugs.mysql.com/ so that we can either fix it for next release
-or in the worst case add it here for others to know!
+http://bugs.launchpad.net/maria so that we can either fix it for next
+release or in the worst case add it here for others to know!
 
 IMPORTANT:
 
-If you have been using a MySQL-5.1-Maria-alpha build and upgrading to
-MySQL-5.1-Maria-beta you MUST run maria_chk --recover on all your
-Maria tables.  This is because we made an incompatible change of how
-transaction id is stored and old transaction id's must be reset!
+If you have been using the Maria storage engine with
+MySQL-5.1-Maria-alpha build and upgrading to a newer MariaDB you MUST
+run maria_chk --recover on all your Maria tables.  This is because we
+made an incompatible change of how transaction id is stored and old
+transaction id's must be reset!
 
 cd mysql-data-directory
 maria_chk --recover */*.MAI
 
-As the Maria-1.5 engine is now in beta we will do our best to not
+As the Maria storage engine is now in beta we will do our best to not
 introduce any incompatible changes in the data format for the Maria
 tables; If this would be ever be needed, we will, if possible, support
 both the old and the new version to make upgrades as easy as possible.
 
-Known bugs that we are working on and will be fixed shortly
-===========================================================
-
-- We have some time ago some instabilities in log writing that is was 
-  under investigation but we haven't been able to repeat in a while.
-  This causes mainly assert to triggers in the code and sometimes
-  the log handler doesn't start up after restart.
-  Most of this should now be fixed.
-
-- INSERT on a duplicate key against a key inserted by another connection
-  that has not yet ended will give a duplicate key error instead of
-  waiting for the other statement to end.
-
-
-Known bugs that are planned to be fixed before Gamma/RC
-=======================================================
-
-- If we get a write failure on disk (disk full or disk error) for the
-  log, we should stop all usage of transactional tables and mark all
-  transactional tables that are changed as crashed.
-  For the moment, if this happens, you have to take down mysqld,
-  remove all logs, restart mysqld and repair your tables.
-
-  If you get the related error:
-  "Disk is full writing '/usr/local/mysql/var/maria_log.????????' (Errcode: 28)
-   Waiting for someone to free space..."
-  you should either free disk space, in which Maria will continue as before
-  or kill mysqld, remove logs and repair tables.
-
-
-Known bugs that are planned to be fixed later
-=============================================
-
-LOCK TABLES .. WRITE CONCURRENT is mainly done for testing MVCC.  Don't
-use this in production.
-
-Missing features that is planned to fix before Beta
-===================================================
-
-None
-
-Features planned for future releases
-====================================
-
-Most notable is full transaction support and multiple reader/writers
-in Maria 2.0
-
-http://forge.mysql.com/worklog/
-(you can enter "maria" in the "quick search" field there).
+Note that for the MariaDB 5.1 release the Maria storage engine is
+classified as 'beta'; It should work, but use it with caution.  Please
+report all bugs to https://bugs.launchpad.net/maria so that we can fix
+them!

=== modified file 'README'
--- README	2008-03-26 10:15:03 +0000
+++ README	2009-09-03 14:05:38 +0000
@@ -1,35 +1,44 @@
-This is a release of MySQL, a dual-license SQL database server.
-MySQL is brought to you by the MySQL team at MySQL AB.
+This is a release of MariaDB, a branch of MySQL.
+
+MariaDB is a drop-in replacement of MySQL, with more features, less
+bugs and better performance.
+
+MariaDB is brought to you by many of the original developers of MySQL,
+that now work for Monty Program Ab, and by many people in the
+community.
+
+MySQL, which is the base of MariaDB, is brought to you by Sun.
 
 License information can be found in these files:
 - For GPL (free) distributions, see the COPYING file and
   the EXCEPTIONS-CLIENT file.
-- For commercial distributions, see the LICENSE.mysql file.
-
-
-For further information about MySQL or additional documentation, see:
-- The latest information about MySQL: http://www.mysql.com
-- The current MySQL documentation: http://dev.mysql.com/doc
+
+A description of the MariaDB project can be found at:
+http://askmonty.org/wiki/index.php/MariaDB
+
+The differences between MariaDB and MySQL can be found at:
+http://askmonty.org/wiki/index.php/MariaDB_versus_MySQL
+
+Documentation about MySQL can be found at:
+http://dev.mysql.com/doc
+
+For further information about MySQL documentation, see:
+- The current MySQL documentation: 
 
 Some manual sections of special interest:
 
-- If you are migrating from an older version of MySQL, please read the
-  "Upgrading from..." section first!
-- To see what MySQL can do, take a look at the features section.
-- For installation instructions, see the Installing and Upgrading chapter.
-- For the new features/bugfix history, see the Change History appendix.
-- For the currently known bugs/misfeatures (known errors) see the Problems
-  and Common Errors appendix.
 - For a list of developers and other contributors, see the Credits
   appendix.
 
 A local copy of the MySQL Reference Manual can be found in the Docs
 directory in GNU Info format.  You can also browse the manual online or
-download it in any of several formats at the URL given earlier in this
-file.
+download it in any of several formats from
+http://dev.mysql.com/doc
 
 ************************************************************
 
 IMPORTANT:
 
-Bug or error reports should be sent to http://bugs.mysql.com.
+Bug or error reports regarding MariaDB should be sent to
+https://bugs.launchpad.net/maria
+Bugs in the MySQL code can also be sent to http://bugs.mysql.com

=== added file 'mysql-test/r/log_slow.result'
--- mysql-test/r/log_slow.result	1970-01-01 00:00:00 +0000
+++ mysql-test/r/log_slow.result	2009-09-03 14:05:38 +0000
@@ -0,0 +1,60 @@
+select @@log_slow_filter;
+@@log_slow_filter
+
+select @@log_slow_rate_limit;
+@@log_slow_rate_limit
+1
+select @@log_slow_verbosity;
+@@log_slow_verbosity
+
+show variables like "log_slow%";
+Variable_name	Value
+log_slow_filter	
+log_slow_queries	ON
+log_slow_rate_limit	1
+log_slow_time	10.000000
+log_slow_verbosity	
+set @@log_slow_filter= "filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk,admin";
+select @@log_slow_filter;
+@@log_slow_filter
+admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
+set @@log_slow_filter="admin,admin";
+select @@log_slow_filter;
+@@log_slow_filter
+admin
+set @@log_slow_filter=7;
+select @@log_slow_filter;
+@@log_slow_filter
+admin,filesort,filesort_on_disk
+set @@log_slow_filter= "filesort,impossible,impossible2,admin";
+ERROR 42000: Variable 'log_slow_filter' can't be set to the value of 'impossible'
+set @@log_slow_filter= "filesort, admin";
+ERROR 42000: Variable 'log_slow_filter' can't be set to the value of ' admin'
+set @@log_slow_filter= 1<<31;
+ERROR 42000: Variable 'log_slow_filter' can't be set to the value of '2147483648'
+select @@log_slow_filter;
+@@log_slow_filter
+admin,filesort,filesort_on_disk
+set @@log_slow_verbosity= "query_plan,innodb";
+select @@log_slow_verbosity;
+@@log_slow_verbosity
+innodb,query_plan
+set @@log_slow_verbosity=1;
+select @@log_slow_verbosity;
+@@log_slow_verbosity
+innodb
+show fields from mysql.slow_log;
+Field	Type	Null	Key	Default	Extra
+start_time	timestamp	NO		CURRENT_TIMESTAMP	on update CURRENT_TIMESTAMP
+user_host	mediumtext	NO		NULL	
+query_time	time	NO		NULL	
+lock_time	time	NO		NULL	
+rows_sent	int(11)	NO		NULL	
+rows_examined	int(11)	NO		NULL	
+db	varchar(512)	NO		NULL	
+last_insert_id	int(11)	NO		NULL	
+insert_id	int(11)	NO		NULL	
+server_id	int(10) unsigned	NO		NULL	
+sql_text	mediumtext	NO		NULL	
+set @@log_slow_filter=default;
+set @@log_slow_verbosity=default;

=== modified file 'mysql-test/r/variables.result'
--- mysql-test/r/variables.result	2009-06-11 17:49:51 +0000
+++ mysql-test/r/variables.result	2009-09-03 14:05:38 +0000
@@ -865,7 +865,7 @@
 @@query_prealloc_size = @test
 1
 set global sql_mode=repeat('a',80);
-ERROR 42000: Variable 'sql_mode' can't be set to the value of 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Variable 'sql_mode' can't be set to the value of 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
 End of 4.1 tests
 create table t1 (a int);
 select a into @x from t1;

=== added file 'mysql-test/t/log_slow.test'
--- mysql-test/t/log_slow.test	1970-01-01 00:00:00 +0000
+++ mysql-test/t/log_slow.test	2009-09-03 14:05:38 +0000
@@ -0,0 +1,42 @@
+#
+# Testing of slow log query options
+#
+
+select @@log_slow_filter;
+select @@log_slow_rate_limit;
+select @@log_slow_verbosity;
+show variables like "log_slow%";
+
+# Some simple test to set log_slow_filter
+set @@log_slow_filter= "filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk,admin";
+select @@log_slow_filter;
+set @@log_slow_filter="admin,admin";
+select @@log_slow_filter;
+set @@log_slow_filter=7;
+select @@log_slow_filter;
+
+# Test of wrong values
+--error 1231
+set @@log_slow_filter= "filesort,impossible,impossible2,admin";
+--error 1231
+set @@log_slow_filter= "filesort, admin";
+--error 1231
+set @@log_slow_filter= 1<<31;
+select @@log_slow_filter;
+
+# Some simple test to set log_slow_verbosity
+set @@log_slow_verbosity= "query_plan,innodb";
+select @@log_slow_verbosity;
+set @@log_slow_verbosity=1;
+select @@log_slow_verbosity;
+
+#
+# Check which fields are in slow_log table
+#
+
+show fields from mysql.slow_log;
+
+# Reset used variables
+
+set @@log_slow_filter=default;
+set @@log_slow_verbosity=default;

=== modified file 'sql/Makefile.am'
--- sql/Makefile.am	2009-06-25 10:05:53 +0000
+++ sql/Makefile.am	2009-09-03 14:56:46 +0000
@@ -61,7 +61,7 @@
 			ha_partition.h rpl_constants.h \
 			opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
 			rpl_reporting.h \
-			log.h sql_show.h rpl_rli.h rpl_mi.h \
+			log.h log_slow.h sql_show.h rpl_rli.h rpl_mi.h \
 			sql_select.h structs.h table.h sql_udf.h hash_filo.h \
 			lex.h lex_symbol.h sql_acl.h sql_crypt.h  \
 			sql_repl.h slave.h rpl_filter.h rpl_injector.h \

=== modified file 'sql/event_data_objects.cc'
--- sql/event_data_objects.cc	2009-04-25 10:05:32 +0000
+++ sql/event_data_objects.cc	2009-09-03 14:05:38 +0000
@@ -1456,8 +1456,7 @@
 
     DBUG_ASSERT(sphead);
 
-    if (thd->enable_slow_log)
-      sphead->m_flags|= sp_head::LOG_SLOW_STATEMENTS;
+    sphead->m_flags|= sp_head::LOG_SLOW_STATEMENTS;
     sphead->m_flags|= sp_head::LOG_GENERAL_LOG;
 
     sphead->set_info(0, 0, &thd->lex->sp_chistics, sql_mode);

=== modified file 'sql/events.cc'
--- sql/events.cc	2009-04-25 10:05:32 +0000
+++ sql/events.cc	2009-09-03 14:05:38 +0000
@@ -689,8 +689,7 @@
 
   field_list.push_back(new Item_empty_string("Event", NAME_CHAR_LEN));
 
-  if (sys_var_thd_sql_mode::symbolic_mode_representation(thd, et->sql_mode,
-                                                         &sql_mode))
+  if (sys_var::make_set(thd, et->sql_mode, &sql_mode_typelib, &sql_mode))
     DBUG_RETURN(TRUE);
 
   field_list.push_back(new Item_empty_string("sql_mode", (uint) sql_mode.length));

=== modified file 'sql/filesort.cc'
--- sql/filesort.cc	2009-05-06 12:03:24 +0000
+++ sql/filesort.cc	2009-09-03 14:05:38 +0000
@@ -188,6 +188,7 @@
   {
     status_var_increment(thd->status_var.filesort_scan_count);
   }
+  thd->query_plan_flags|= QPLAN_FILESORT;
 #ifdef CAN_TRUST_RANGE
   if (select && select->quick && select->quick->records > 0L)
   {
@@ -253,6 +254,7 @@
   }
   else
   {
+    thd->query_plan_flags|= QPLAN_FILESORT_DISK;
     if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
     {
       x_free(table_sort.buffpek);
@@ -1199,6 +1201,7 @@
   DBUG_ENTER("merge_buffers");
 
   status_var_increment(current_thd->status_var.filesort_merge_passes);
+  current_thd->query_plan_fsort_passes++;
   if (param->not_killable)
   {
     killed= &not_killable;

=== modified file 'sql/log.cc'
--- sql/log.cc	2009-04-25 10:05:32 +0000
+++ sql/log.cc	2009-09-03 14:05:38 +0000
@@ -964,7 +964,7 @@
     /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
     user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
                              sctx->priv_user ? sctx->priv_user : "", "[",
-                             sctx->user ? sctx->user : "", "] @ ",
+                             sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
                              sctx->host ? sctx->host : "", " [",
                              sctx->ip ? sctx->ip : "", "]", NullS) -
                     user_host_buff);
@@ -987,6 +987,17 @@
       query_length= command_name[thd->command].length;
     }
 
+    if (!query_length) 
+    {
+      /*
+        Not a real query; Reset counts for slow query logging
+        (QQ: Wonder if this is really needed)
+      */
+      thd->sent_row_count= thd->examined_row_count= 0;
+      thd->query_plan_flags= QPLAN_INIT;
+      thd->query_plan_fsort_passes= 0;
+    }
+
     for (current_handler= slow_log_handler_list; *current_handler ;)
       error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
                                             user_host_buff, user_host_len,
@@ -2202,19 +2213,39 @@
       if (my_b_write(&log_file, (uchar*) "\n", 1))
         tmp_errno= errno;
     }
+    
     /* For slow query log */
     sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
     sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
     if (my_b_printf(&log_file,
-                    "# Query_time: %s  Lock_time: %s"
-                    " Rows_sent: %lu  Rows_examined: %lu\n",
+                    "# Thread_id: %lu  Schema: %s  QC_hit: %s\n" \
+                    "# Query_time: %s  Lock_time: %s  Rows_sent: %lu  Rows_examined: %lu\n",
+                    (ulong) thd->thread_id, (thd->db ? thd->db : ""),
+                    ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
                     query_time_buff, lock_time_buff,
                     (ulong) thd->sent_row_count,
-                    (ulong) thd->examined_row_count) == (uint) -1)
+                    (ulong) thd->examined_row_count) == (size_t) -1)
       tmp_errno= errno;
+     if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) &&
+         (thd->query_plan_flags &
+          (QPLAN_FULL_SCAN | QPLAN_FULL_JOIN | QPLAN_TMP_TABLE |
+           QPLAN_TMP_DISK | QPLAN_FILESORT | QPLAN_FILESORT_DISK)) &&
+         my_b_printf(&log_file,
+                     "# Full_scan: %s  Full_join: %s  "
+                     "Tmp_table: %s  Tmp_table_on_disk: %s\n"
+                     "# Filesort: %s  Filesort_on_disk: %s  Merge_passes: %lu\n",
+                     ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
+                     ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
+                     ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
+                     ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
+                     ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
+                     ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ?
+                      "Yes" : "No"),
+                     thd->query_plan_fsort_passes) == (size_t) -1)
+       tmp_errno= errno;
     if (thd->db && strcmp(thd->db, db))
     {						// Database changed
-      if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
+      if (my_b_printf(&log_file,"use %s;\n",thd->db) == (size_t) -1)
         tmp_errno= errno;
       strmov(db,thd->db);
     }

=== added file 'sql/log_slow.h'
--- sql/log_slow.h	1970-01-01 00:00:00 +0000
+++ sql/log_slow.h	2009-09-03 14:05:38 +0000
@@ -0,0 +1,107 @@
+/* Copyright (C) 2009 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 or later of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Defining what to log to slow log */
+
+#define LOG_SLOW_VERBOSITY_INIT           0
+#define LOG_SLOW_VERBOSITY_INNODB         1 << 0
+#define LOG_SLOW_VERBOSITY_QUERY_PLAN     1 << 1
+
+#ifdef DEFINE_VARIABLES_LOG_SLOW
+
+/* Names here must be in same order as the bit's above */
+static const char *log_slow_verbosity_names[]=
+{
+  "innodb","query_plan",
+  NullS
+};
+
+static const unsigned int log_slow_verbosity_names_len[]=
+{
+  sizeof("innodb") -1,
+  sizeof("query_plan")-1
+};
+
+TYPELIB log_slow_verbosity_typelib=
+{  array_elements(log_slow_verbosity_names)-1,"", log_slow_verbosity_names,
+   (unsigned int *) log_slow_verbosity_names_len };
+
+#else
+extern TYPELIB log_slow_verbosity_typelib;
+#endif /* DEFINE_VARIABLES_LOG_SLOW */
+
+/* Defines for what kind of query plan was used and what to log */
+
+/*
+  We init the used query plan with a bit that is alwyas set and all 'no' bits
+  to enable easy testing of what to log in sql_log.cc
+*/
+#define QPLAN_INIT            (QPLAN_ALWAYS_SET | QPLAN_QC_NO)
+
+#define QPLAN_ADMIN           1 << 0
+#define QPLAN_FILESORT        1 << 1
+#define QPLAN_FILESORT_DISK   1 << 2
+#define QPLAN_FULL_JOIN       1 << 3
+#define QPLAN_FULL_SCAN       1 << 4
+#define QPLAN_QC              1 << 5
+#define QPLAN_QC_NO           1 << 6
+#define QPLAN_TMP_DISK        1 << 7
+#define QPLAN_TMP_TABLE       1 << 8
+/* ... */
+#define QPLAN_MAX             ((ulong) 1) << 31 /* reserved as placeholder */
+#define QPLAN_ALWAYS_SET      QPLAN_MAX
+#define QPLAN_VISIBLE_MASK    (~(QPLAN_ALWAYS_SET))
+
+#ifdef DEFINE_VARIABLES_LOG_SLOW
+/* Names here must be in same order as the bit's above */
+static const char *log_slow_filter_names[]= 
+{
+  "admin",
+  "filesort",
+  "filesort_on_disk",
+  "full_join",
+  "full_scan",
+  "query_cache",
+  "query_cache_miss",
+  "tmp_table",
+  "tmp_table_on_disk",
+  NullS
+};
+
+static const unsigned int log_slow_filter_names_len[]=
+{
+  sizeof("admin")-1,
+  sizeof("filesort")-1,
+  sizeof("filesort_on_disk")-1,
+  sizeof("full_join")-1,
+  sizeof("full_scan")-1,
+  sizeof("query_cache")-1,
+  sizeof("query_cache_miss")-1,
+  sizeof("tmp_table")-1,
+  sizeof("tmp_table_on_disk")-1
+};
+
+TYPELIB log_slow_filter_typelib=
+{  array_elements(log_slow_filter_names)-1,"", log_slow_filter_names,
+   (unsigned int *) log_slow_filter_names_len };
+
+#else
+extern TYPELIB log_slow_filter_typelib;
+#endif /* DEFINE_VARIABLES_LOG_SLOW */
+
+static inline ulong fix_log_slow_filter(ulong org_filter)
+{
+  return org_filter ? org_filter : QPLAN_ALWAYS_SET;
+}

=== modified file 'sql/mysql_priv.h'
--- sql/mysql_priv.h	2009-08-24 19:10:48 +0000
+++ sql/mysql_priv.h	2009-09-03 14:56:46 +0000
@@ -43,6 +43,7 @@
 #include "sql_array.h"
 #include "sql_plugin.h"
 #include "scheduler.h"
+#include "log_slow.h"
 
 class Parser_state;
 

=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc	2009-08-25 09:27:50 +0000
+++ sql/mysqld.cc	2009-09-03 14:56:46 +0000
@@ -13,6 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#define DEFINE_VARIABLES_LOG_SLOW          // Declare variables in log_slow.h
 #include "mysql_priv.h"
 #include <m_ctype.h>
 #include <my_dir.h>
@@ -5771,6 +5772,9 @@
   OPT_DEADLOCK_SEARCH_DEPTH_LONG,
   OPT_DEADLOCK_TIMEOUT_SHORT,
   OPT_DEADLOCK_TIMEOUT_LONG,
+  OPT_LOG_SLOW_RATE_LIMIT, 
+  OPT_LOG_SLOW_VERBOSITY, 
+  OPT_LOG_SLOW_FILTER, 
   OPT_GENERAL_LOG_FILE,
   OPT_SLOW_QUERY_LOG_FILE,
   OPT_IGNORE_BUILTIN_INNODB
@@ -6113,7 +6117,7 @@
    (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
    NO_ARG, 0, 0, 0, 0, 0, 0},
   {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
-   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
+   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open. .  Please note that this option is deprecated; see --log-slow-filter for filtering slow query log output",
    (uchar**) &opt_log_slow_admin_statements,
    (uchar**) &opt_log_slow_admin_statements,
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -6122,15 +6126,15 @@
   (uchar**) &opt_log_slow_slave_statements,
   (uchar**) &opt_log_slow_slave_statements,
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"log_slow_queries", OPT_SLOW_QUERY_LOG,
+  {"log-slow-queries", OPT_SLOW_QUERY_LOG,
     "Log slow queries to a table or log file. Defaults logging to table "
     "mysql.slow_log or hostname-slow.log if --log-output=file is used. "
     "Must be enabled to activate other slow log options. "
     "(deprecated option, use --slow_query_log/--slow_query_log_file instead)",
    (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
    0, 0, 0, 0, 0, 0},
-  {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE,
-    "Log slow queries to given log file. Defaults logging to hostname-slow.log. Must be enabled to activate other slow log options.",
+  {"slow-query-log-file", OPT_SLOW_QUERY_LOG_FILE,
+    "Log slow queries to given log file. Defaults logging to hostname-slow.log.",
    (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"log-tc", OPT_LOG_TC,
@@ -6750,11 +6754,31 @@
    (uchar**) 0,
    0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
    1, 100, 0, 1, 0},
+  {"log-slow-filter", OPT_LOG_SLOW_FILTER,
+   "Log only the queries that followed certain execution plan. Multiple flags allowed in a comma-separated string. [admin, filesort, filesort_on_disk, full_join, full_scan, query_cache, query_cache_miss, tmp_table, tmp_table_on_disk]. Sets log-slow-admin-command to ON",
+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, QPLAN_ALWAYS_SET, 0, 0},
+  {"log-slow-rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
+   "If set, only write to slow log every 'log_slow_rate_limit' query (use this to reduce output on slow query log)",
+   (uchar**) &global_system_variables.log_slow_rate_limit,
+   (uchar**) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
+   REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0},
+  {"log-slow-verbosity", OPT_LOG_SLOW_VERBOSITY,
+   "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [query_plan, innodb]",
+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+  {"log-slow-file", OPT_SLOW_QUERY_LOG_FILE,
+    "Log slow queries to given log file. Defaults logging to hostname-slow.log",
+   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR,
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"long_query_time", OPT_LONG_QUERY_TIME,
    "Log all queries that have taken more than long_query_time seconds to execute to file. "
    "The argument will be treated as a decimal value with microsecond precission.",
    (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
    REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
+  {"log-slow-time", OPT_LONG_QUERY_TIME,
+   "Log all queries that have taken more than long_query_time seconds to execute to file. "
+   "The argument will be treated as a decimal value with microsecond precission.",
+   (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
+   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
   {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
    "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.  Should be set to 2 if you are using a case insensitive file system",
    (uchar**) &lower_case_table_names,
@@ -7859,6 +7883,9 @@
   global_system_variables.old_passwords= 0;
   global_system_variables.old_alter_table= 0;
   global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
+  global_system_variables.log_slow_verbosity= LOG_SLOW_VERBOSITY_INIT;
+  global_system_variables.log_slow_filter=    QPLAN_ALWAYS_SET;
+  
   /*
     Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
     when collecting index statistics for MyISAM tables.
@@ -8213,7 +8240,7 @@
   }
 #endif /* HAVE_REPLICATION */
   case (int) OPT_SLOW_QUERY_LOG:
-    WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'");
+    WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--log-slow-file'");
     opt_slow_log= 1;
     break;
 #ifdef WITH_CSV_STORAGE_ENGINE
@@ -8366,6 +8393,25 @@
   case OPT_BOOTSTRAP:
     opt_noacl=opt_bootstrap=1;
     break;
+  case OPT_LOG_SLOW_FILTER:
+    global_system_variables.log_slow_filter=
+      find_bit_type_or_exit(argument, &log_slow_verbosity_typelib,
+                            opt->name, &error);
+    /*
+      If we are using filters, we set opt_slow_admin_statements to be always
+      true so we can maintain everything with filters
+    */
+    opt_log_slow_admin_statements= 1;
+    if (error)
+      return 1;
+    break;
+  case OPT_LOG_SLOW_VERBOSITY:
+    global_system_variables.log_slow_verbosity=
+      find_bit_type_or_exit(argument, &log_slow_filter_typelib,
+                            opt->name, &error);
+    if (error)
+      return 1;
+    break;
   case OPT_SERVER_ID:
     server_id_supplied = 1;
     break;
@@ -8674,6 +8720,8 @@
   /* Set global slave_exec_mode from its option */
   fix_slave_exec_mode(OPT_GLOBAL);
 
+  global_system_variables.log_slow_filter=
+    fix_log_slow_filter(global_system_variables.log_slow_filter);
 #ifndef EMBEDDED_LIBRARY
   if (mysqld_chroot)
     set_root(mysqld_chroot);

=== modified file 'sql/set_var.cc'
--- sql/set_var.cc	2009-06-24 22:22:20 +0000
+++ sql/set_var.cc	2009-09-03 14:05:38 +0000
@@ -147,6 +147,7 @@
 static void sys_default_general_log_path(THD *thd, enum_var_type type);
 static bool sys_update_slow_log_path(THD *thd, set_var * var);
 static void sys_default_slow_log_path(THD *thd, enum_var_type type);
+static void fix_sys_log_slow_filter(THD *thd, enum_var_type);
 
 /*
   Variable definition list
@@ -359,6 +360,9 @@
 static sys_var_thd_ulong	sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
 static sys_var_microseconds	sys_var_long_query_time(&vars, "long_query_time",
                                                         &SV::long_query_time);
+static sys_var_microseconds	sys_var_long_query_time2(&vars,
+                                                         "log_slow_time",
+                                                         &SV::long_query_time);
 static sys_var_thd_bool	sys_low_priority_updates(&vars, "low_priority_updates",
 						 &SV::low_priority_updates,
 						 fix_low_priority_updates);
@@ -852,6 +856,20 @@
 sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
                                     sys_var::SESSION_VARIABLE_IN_BINLOG);
 
+/* Unique variables for MariaDB */
+static sys_var_thd_ulong  sys_log_slow_rate_limit(&vars,
+                                                  "log_slow_rate_limit",
+                                                  &SV::log_slow_rate_limit);
+static sys_var_thd_set sys_log_slow_filter(&vars, "log_slow_filter",
+                                           &SV::log_slow_filter,
+                                           &log_slow_filter_typelib,
+                                           QPLAN_VISIBLE_MASK,
+                                           fix_sys_log_slow_filter);
+static sys_var_thd_set sys_log_slow_verbosity(&vars,
+                                              "log_slow_verbosity",
+                                              &SV::log_slow_verbosity,
+                                              &log_slow_verbosity_typelib);
+
 /* Global read-only variable containing hostname */
 static sys_var_const_str        sys_hostname(&vars, "hostname", glob_hostname);
 
@@ -1850,11 +1868,17 @@
   return 1;
 }
 
+/**
+   Check vality of set
+
+   Note that this sets 'save_result.ulong_value' for the update function,
+   which means that we don't need a separate sys_var::update() function
+*/
 
 bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
 {
   bool not_used;
-  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
+  char buff[256], *error= 0;
   uint error_len= 0;
   String str(buff, sizeof(buff) - 1, system_charset_info), *res;
 
@@ -1866,8 +1890,7 @@
       goto err;
     }
 
-    if (!m_allow_empty_value &&
-        res->length() == 0)
+    if (!m_allow_empty_value && res->length() == 0)
     {
       buff[0]= 0;
       goto err;
@@ -1889,8 +1912,7 @@
   {
     ulonglong tmp= var->value->val_int();
 
-    if (!m_allow_empty_value &&
-        tmp == 0)
+    if (!m_allow_empty_value && tmp == 0)
     {
       buff[0]= '0';
       buff[1]= 0;
@@ -1917,6 +1939,49 @@
 }
 
 
+/**
+  Make string representation of set
+
+  @param[in]  thd    thread handler
+  @param[in]  val    sql_mode value
+  @param[in]  names  names for the different bits
+  @param[out] rep    Result string
+
+  @return
+    0 ok
+    1 end of memory
+*/
+
+bool sys_var::make_set(THD *thd, ulonglong val, TYPELIB *names,
+                       LEX_STRING *rep)
+{
+  /* Strings for typelib may be big; This is reallocated on demand */
+  char buff[256];
+  String tmp(buff, sizeof(buff) - 1, &my_charset_latin1);
+  bool error= 0;
+
+  tmp.length(0);
+  for (uint i= 0; val; val>>= 1, i++)
+  {
+    if (val & 1)
+    {
+      error|= tmp.append(names->type_names[i],
+                 names->type_lengths[i]);
+      error|= tmp.append(',');
+    }
+  }
+
+  if (tmp.length())
+    tmp.length(tmp.length() - 1); /* trim the trailing comma */
+
+  /* Allocate temporary copy of string */
+  if (!(rep->str= thd->strmake(tmp.ptr(), tmp.length())))
+    error= 1;
+  rep->length= tmp.length();
+  return error;                   /* Error in case of out of memory */
+}
+
+
 CHARSET_INFO *sys_var::charset(THD *thd)
 {
   return is_os_charset ? thd->variables.character_set_filesystem : 
@@ -1952,6 +2017,16 @@
   return (uchar*) enum_names->type_names[tmp];
 }
 
+uchar *sys_var_thd_set::value_ptr(THD *thd, enum_var_type type,
+                                  LEX_STRING *base)
+{
+  LEX_STRING sql_mode;
+  ulong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
+              thd->variables.*offset);
+  (void) make_set(thd, val & visible_value_mask, enum_names, &sql_mode);
+  return (uchar *) sql_mode.str;
+}
+
 bool sys_var_thd_bit::check(THD *thd, set_var *var)
 {
   return (check_enum(thd, var, &bool_typelib) ||
@@ -3700,6 +3775,24 @@
 }
 
 /****************************************************************************
+ Functions to handle log_slow_filter
+****************************************************************************/
+  
+/* Ensure that the proper bits are set for easy test of logging */
+static void fix_sys_log_slow_filter(THD *thd, enum_var_type type)
+{
+  /* Maintain everything with filters */
+  opt_log_slow_admin_statements= 1;
+  if (type == OPT_GLOBAL)
+    global_system_variables.log_slow_filter=
+      fix_log_slow_filter(global_system_variables.log_slow_filter);
+  else
+    thd->variables.log_slow_filter=
+      fix_log_slow_filter(thd->variables.log_slow_filter);
+}
+
+
+/****************************************************************************
  Functions to handle table_type
 ****************************************************************************/
 
@@ -3810,67 +3903,6 @@
  Functions to handle sql_mode
 ****************************************************************************/
 
-/**
-  Make string representation of mode.
-
-  @param[in]  thd    thread handler
-  @param[in]  val    sql_mode value
-  @param[out] len    pointer on length of string
-
-  @return
-    pointer to string with sql_mode representation
-*/
-
-bool
-sys_var_thd_sql_mode::
-symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-{
-  char buff[STRING_BUFFER_USUAL_SIZE*8];
-  String tmp(buff, sizeof(buff) - 1, &my_charset_latin1);
-
-  tmp.length(0);
-
-  for (uint i= 0; val; val>>= 1, i++)
-  {
-    if (val & 1)
-    {
-      tmp.append(sql_mode_typelib.type_names[i],
-                 sql_mode_typelib.type_lengths[i]);
-      tmp.append(',');
-    }
-  }
-
-  if (tmp.length())
-    tmp.length(tmp.length() - 1); /* trim the trailing comma */
-
-  rep->str= thd->strmake(tmp.ptr(), tmp.length());
-
-  rep->length= rep->str ? tmp.length() : 0;
-
-  return rep->length != tmp.length();
-}
-
-
-uchar *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
-				      LEX_STRING *base)
-{
-  LEX_STRING sql_mode;
-  ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-                  thd->variables.*offset);
-  (void) symbolic_mode_representation(thd, val, &sql_mode);
-  return (uchar *) sql_mode.str;
-}
-
-
-void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type)
-{
-  if (type == OPT_GLOBAL)
-    global_system_variables.*offset= 0;
-  else
-    thd->variables.*offset= global_system_variables.*offset;
-}
-
-
 void fix_sql_mode_var(THD *thd, enum_var_type type)
 {
   if (type == OPT_GLOBAL)

=== modified file 'sql/set_var.h'
--- sql/set_var.h	2009-04-25 10:05:32 +0000
+++ sql/set_var.h	2009-09-03 14:05:38 +0000
@@ -98,6 +98,8 @@
   virtual bool check(THD *thd, set_var *var);
   bool check_enum(THD *thd, set_var *var, const TYPELIB *enum_names);
   bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
+  static bool make_set(THD *thd, ulonglong sql_mode, TYPELIB *names,
+                       LEX_STRING *rep);
   bool is_written_to_binlog(enum_var_type type)
   {
     return (type == OPT_SESSION || type == OPT_DEFAULT) &&
@@ -532,6 +534,25 @@
 };
 
 
+class sys_var_thd_set :public sys_var_thd_enum
+{
+  ulong visible_value_mask; /* Mask away internal bits */
+public:
+  sys_var_thd_set(sys_var_chain *chain, const char *name_arg, 
+                  ulong SV::*offset_arg, TYPELIB *typelib,
+                  ulong value_mask= ~ (ulong) 0,
+                  sys_after_update_func func= NULL)
+    :sys_var_thd_enum(chain, name_arg, offset_arg, typelib,
+                      func), visible_value_mask(value_mask)
+    {}
+  bool check(THD *thd, set_var *var)
+  {
+    return check_set(thd, var, enum_names);
+  }
+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+};
+
+
 class sys_var_thd_optimizer_switch :public sys_var_thd_enum
 {
 public:
@@ -548,22 +569,14 @@
 
 extern void fix_sql_mode_var(THD *thd, enum_var_type type);
 
-class sys_var_thd_sql_mode :public sys_var_thd_enum
+class sys_var_thd_sql_mode :public sys_var_thd_set
 {
 public:
   sys_var_thd_sql_mode(sys_var_chain *chain, const char *name_arg, 
                        ulong SV::*offset_arg)
-    :sys_var_thd_enum(chain, name_arg, offset_arg, &sql_mode_typelib,
-                      fix_sql_mode_var)
+    :sys_var_thd_set(chain, name_arg, offset_arg, &sql_mode_typelib,
+                     ~(ulong) 0, fix_sql_mode_var)
   {}
-  bool check(THD *thd, set_var *var)
-  {
-    return check_set(thd, var, enum_names);
-  }
-  void set_default(THD *thd, enum_var_type type);
-  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-  static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
-                                           LEX_STRING *rep);
 };
 
 
@@ -1184,7 +1197,6 @@
   bool update(THD *thd, set_var *var);
 };
 
-
 /**
   Handler for setting the system variable --read-only.
 */

=== modified file 'sql/slave.cc'
--- sql/slave.cc	2009-06-11 17:49:51 +0000
+++ sql/slave.cc	2009-09-03 14:05:38 +0000
@@ -1583,6 +1583,7 @@
     + MAX_LOG_EVENT_HEADER;  /* note, incr over the global not session var */
   thd->slave_thread = 1;
   thd->enable_slow_log= opt_log_slow_slave_statements;
+  thd->variables.log_slow_filter= global_system_variables.log_slow_filter;
   set_slave_thread_options(thd);
   thd->client_capabilities = CLIENT_LOCAL_FILES;
   pthread_mutex_lock(&LOCK_thread_count);

=== modified file 'sql/sp_head.cc'
--- sql/sp_head.cc	2009-04-25 10:05:32 +0000
+++ sql/sp_head.cc	2009-09-03 14:05:38 +0000
@@ -1845,7 +1845,7 @@
   uint params = m_pcont->context_var_count();
   sp_rcontext *save_spcont, *octx;
   sp_rcontext *nctx = NULL;
-  bool save_enable_slow_log= false;
+  bool save_enable_slow_log;
   bool save_log_general= false;
   DBUG_ENTER("sp_head::execute_procedure");
   DBUG_PRINT("info", ("procedure %s", m_name.str));
@@ -1956,10 +1956,10 @@
     DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length, 
                        m_name.str));
   }
-  if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
+  save_enable_slow_log= thd->enable_slow_log;
+  if (!(m_flags & LOG_SLOW_STATEMENTS) && save_enable_slow_log)
   {
     DBUG_PRINT("info", ("Disabling slow log for the execution"));
-    save_enable_slow_log= true;
     thd->enable_slow_log= FALSE;
   }
   if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF))
@@ -1982,8 +1982,7 @@
 
   if (save_log_general)
     thd->options &= ~OPTION_LOG_OFF;
-  if (save_enable_slow_log)
-    thd->enable_slow_log= true;
+  thd->enable_slow_log= save_enable_slow_log;
   /*
     In the case when we weren't able to employ reuse mechanism for
     OUT/INOUT paranmeters, we should reallocate memory. This
@@ -2396,8 +2395,7 @@
   if (check_show_routine_access(thd, this, &full_access))
     DBUG_RETURN(TRUE);
 
-  sys_var_thd_sql_mode::symbolic_mode_representation(
-      thd, m_sql_mode, &sql_mode);
+    sys_var::make_set(thd, m_sql_mode, &sql_mode_typelib, &sql_mode);
 
   /* Send header. */
 

=== modified file 'sql/sql_cache.cc'
--- sql/sql_cache.cc	2009-04-25 10:05:32 +0000
+++ sql/sql_cache.cc	2009-09-03 14:05:38 +0000
@@ -1530,6 +1530,7 @@
 
   thd->limit_found_rows = query->found_rows();
   thd->status_var.last_query_cost= 0.0;
+  thd->query_plan_flags= (thd->query_plan_flags & ~QPLAN_QC_NO) | QPLAN_QC;
   thd->main_da.disable_status();
 
   BLOCK_UNLOCK_RD(query_block);
@@ -1538,6 +1539,10 @@
 err_unlock:
   STRUCT_UNLOCK(&structure_guard_mutex);
 err:
+  /*
+    query_plan_flags doesn't have to be changed here as it contains
+    QPLAN_QC_NO by default
+  */
   DBUG_RETURN(0);				// Query was not cached
 }
 

=== modified file 'sql/sql_class.cc'
--- sql/sql_class.cc	2009-05-19 09:28:05 +0000
+++ sql/sql_class.cc	2009-09-03 14:05:38 +0000
@@ -3007,6 +3007,7 @@
   backup->options=         options;
   backup->in_sub_stmt=     in_sub_stmt;
   backup->enable_slow_log= enable_slow_log;
+  backup->query_plan_flags= query_plan_flags;
   backup->limit_found_rows= limit_found_rows;
   backup->examined_row_count= examined_row_count;
   backup->sent_row_count=   sent_row_count;
@@ -3071,6 +3072,7 @@
   options=          backup->options;
   in_sub_stmt=      backup->in_sub_stmt;
   enable_slow_log=  backup->enable_slow_log;
+  query_plan_flags= backup->query_plan_flags;
   first_successful_insert_id_in_prev_stmt= 
     backup->first_successful_insert_id_in_prev_stmt;
   first_successful_insert_id_in_cur_stmt= 

=== modified file 'sql/sql_class.h'
--- sql/sql_class.h	2009-04-25 10:05:32 +0000
+++ sql/sql_class.h	2009-09-03 14:05:38 +0000
@@ -349,6 +349,10 @@
   ulong trans_prealloc_size;
   ulong log_warnings;
   ulong group_concat_max_len;
+  /* Flags for slow log filtering */
+  ulong log_slow_rate_limit; 
+  ulong log_slow_filter; 
+  ulong log_slow_verbosity; 
   ulong ndb_autoincrement_prefetch_sz;
   ulong ndb_index_stat_cache_entries;
   ulong ndb_index_stat_update_freq;
@@ -995,6 +999,7 @@
   ulonglong limit_found_rows;
   ha_rows    cuted_fields, sent_row_count, examined_row_count;
   ulong client_capabilities;
+  ulong query_plan_flags; 
   uint in_sub_stmt;
   bool enable_slow_log;
   bool last_insert_id_used;
@@ -1696,6 +1701,8 @@
     create_sort_index(); may differ from examined_row_count.
   */
   ulong      row_count;
+  ulong      query_plan_flags; 
+  ulong      query_plan_fsort_passes; 
   pthread_t  real_id;                           /* For debugging */
   my_thread_id  thread_id;
   uint	     tmp_table, global_read_lock;

=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc	2009-04-25 10:05:32 +0000
+++ sql/sql_parse.cc	2009-09-03 14:05:38 +0000
@@ -1049,6 +1049,7 @@
 
     status_var_increment(thd->status_var.com_other);
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     db.str= (char*) thd->alloc(db_len + tbl_len + 2);
     if (!db.str)
     {
@@ -1404,6 +1405,7 @@
 
       status_var_increment(thd->status_var.com_other);
       thd->enable_slow_log= opt_log_slow_admin_statements;
+      thd->query_plan_flags|= QPLAN_ADMIN;
       if (check_global_access(thd, REPL_SLAVE_ACL))
 	break;
 
@@ -1638,6 +1640,19 @@
   if (unlikely(thd->in_sub_stmt))
     DBUG_VOID_RETURN;                           // Don't set time for sub stmt
 
+  /* Follow the slow log filter configuration. */ 
+  DBUG_ASSERT(thd->variables.log_slow_filter != 0);
+  if (!(thd->variables.log_slow_filter & thd->query_plan_flags))
+    DBUG_VOID_RETURN; 
+ 
+  /* 
+     If rate limiting of slow log writes is enabled, decide whether to log
+     this query to the log or not.
+  */ 
+  if (thd->variables.log_slow_rate_limit > 1 &&
+      (global_query_id % thd->variables.log_slow_rate_limit) != 0)
+    DBUG_VOID_RETURN;
+
   /*
     Do not log administrative statements unless the appropriate option is
     set; do not log into slow log if reading from backup.
@@ -2353,6 +2368,7 @@
 	check_global_access(thd, FILE_ACL))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res = mysql_backup_table(thd, first_table);
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -2365,6 +2381,7 @@
 	check_global_access(thd, FILE_ACL))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res = mysql_restore_table(thd, first_table);
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -2750,6 +2767,7 @@
       ALTER TABLE.
     */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
 
     bzero((char*) &create_info, sizeof(create_info));
     create_info.db_type= 0;
@@ -2869,6 +2887,7 @@
       }
 
       thd->enable_slow_log= opt_log_slow_admin_statements;
+      thd->query_plan_flags|= QPLAN_ADMIN;
       res= mysql_alter_table(thd, select_lex->db, lex->name.str,
                              &create_info,
                              first_table,
@@ -2956,6 +2975,7 @@
                            UINT_MAX, FALSE))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res= mysql_repair_table(thd, first_table, &lex->check_opt);
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
@@ -2976,6 +2996,7 @@
                            UINT_MAX, FALSE))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res = mysql_check_table(thd, first_table, &lex->check_opt);
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -2988,6 +3009,7 @@
                            UINT_MAX, FALSE))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res= mysql_analyze_table(thd, first_table, &lex->check_opt);
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
@@ -3009,6 +3031,7 @@
                            UINT_MAX, FALSE))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
+    thd->query_plan_flags|= QPLAN_ADMIN;
     res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
       mysql_recreate_table(thd, first_table) :
       mysql_optimize_table(thd, first_table, &lex->check_opt);
@@ -5658,6 +5681,8 @@
   thd->total_warn_count=0;			// Warnings for this query
   thd->rand_used= 0;
   thd->sent_row_count= thd->examined_row_count= 0;
+  thd->query_plan_flags= QPLAN_INIT;
+  thd->query_plan_fsort_passes= 0;
 
   /*
     Because we come here only for start of top-statements, binlog format is

=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc	2009-08-31 20:02:09 +0000
+++ sql/sql_select.cc	2009-09-03 14:56:46 +0000
@@ -6612,7 +6612,10 @@
 	  {
 	    join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 	    if (statistics)
+	    {
 	      status_var_increment(join->thd->status_var.select_scan_count);
+	      join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
+	    }
 	  }
 	}
 	else
@@ -6626,7 +6629,10 @@
 	  {
 	    join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 	    if (statistics)
+	    {
 	      status_var_increment(join->thd->status_var.select_full_join_count);
+	      join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
+	    }
 	  }
 	}
 	if (!table->no_keyread)
@@ -9796,6 +9802,7 @@
               (ulong) rows_limit,test(group)));
 
   status_var_increment(thd->status_var.created_tmp_tables);
+  thd->query_plan_flags|= QPLAN_TMP_TABLE;
 
   if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
     temp_pool_slot = bitmap_lock_set_next(&temp_pool);
@@ -10682,6 +10689,7 @@
     goto err;
   }
   status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
+  table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
   share->db_record_offset= 1;
   DBUG_RETURN(0);
  err:

=== modified file 'sql/sql_show.cc'
--- sql/sql_show.cc	2009-04-25 10:05:32 +0000
+++ sql/sql_show.cc	2009-09-03 14:05:38 +0000
@@ -4567,8 +4567,7 @@
   table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
   table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
 
-  sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
-                                                     &sql_mode_rep);
+  sys_var::make_set(thd, sql_mode, &sql_mode_typelib, &sql_mode_rep);
   table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
   table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
   table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
@@ -5161,8 +5160,7 @@
   /* SQL_MODE */
   {
     LEX_STRING sql_mode;
-    sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
-                                                       &sql_mode);
+    sys_var::make_set(thd, et.sql_mode, &sql_mode_typelib, &sql_mode);
     sch_table->field[ISE_SQL_MODE]->
                                 store(sql_mode.str, sql_mode.length, scs);
   }
@@ -6867,9 +6865,7 @@
                              &trg_connection_cl_name,
                              &trg_db_cl_name);
 
-  sys_var_thd_sql_mode::symbolic_mode_representation(thd,
-                                                     trg_sql_mode,
-                                                     &trg_sql_mode_str);
+  sys_var::make_set(thd, trg_sql_mode, &sql_mode_typelib, &trg_sql_mode_str);
 
   /* Resolve trigger client character set. */
 

=== modified file 'sql/strfunc.cc'
--- sql/strfunc.cc	2009-04-25 10:05:32 +0000
+++ sql/strfunc.cc	2009-09-03 14:05:38 +0000
@@ -45,6 +45,7 @@
   CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
   const char *end= str + strip->cset->lengthsp(strip, str, length);
   ulonglong found= 0;
+
   *err_pos= 0;                  // No error yet
   if (str != end)
   {
@@ -74,9 +75,13 @@
                       find_type(lib, start, var_len, (bool) 0);
       if (!find)
       {
-        *err_pos= (char*) start;
-        *err_len= var_len;
-        *set_warning= 1;
+        /* Report first error */
+        if (!*err_pos)
+        {
+          *err_pos= (char*) start;
+          *err_len= var_len;
+          *set_warning= 1;
+        }
       }
       else
         found|= ((longlong) 1 << (find - 1));
@@ -148,8 +153,10 @@
     }
   }
   else
-    for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
-
+  {
+    for (; pos != end && *pos != '=' && *pos !=',' ; pos++)
+      ;
+  }
   uint var_len= (uint) (pos - start);
   /* Determine which flag it is */
   uint find= cs ? find_type2(lib, start, var_len, cs) :

=== modified file 'storage/myisam/mi_extra.c'
--- storage/myisam/mi_extra.c	2008-04-28 16:24:05 +0000
+++ storage/myisam/mi_extra.c	2009-09-03 14:05:38 +0000
@@ -260,9 +260,8 @@
   case HA_EXTRA_PREPARE_FOR_DROP:
     pthread_mutex_lock(&THR_LOCK_myisam);
     share->last_version= 0L;			/* Impossible version */
-#ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND
-    /* Close the isam and data files as Win32 can't drop an open table */
     pthread_mutex_lock(&share->intern_lock);
+    /* Flush pages that we don't need anymore */
     if (flush_key_blocks(share->key_cache, share->kfile,
 			 (function == HA_EXTRA_PREPARE_FOR_DROP ?
                           FLUSH_IGNORE_CHANGED : FLUSH_RELEASE)))
@@ -272,6 +271,8 @@
       mi_print_error(info->s, HA_ERR_CRASHED);
       mi_mark_crashed(info);			/* Fatal error found */
     }
+#ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND
+    /* Close the isam and data files as Win32 can't drop an open table */
     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
     {
       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
@@ -304,8 +305,8 @@
       }
     }
     share->kfile= -1;				/* Files aren't open anymore */
+#endif
     pthread_mutex_unlock(&share->intern_lock);
-#endif
     pthread_mutex_unlock(&THR_LOCK_myisam);
     break;
   case HA_EXTRA_FLUSH:

=== modified file 'storage/myisam/mi_locking.c'
--- storage/myisam/mi_locking.c	2009-04-01 09:34:52 +0000
+++ storage/myisam/mi_locking.c	2009-09-03 14:05:38 +0000
@@ -582,7 +582,7 @@
   {
     uint old_lock=info->lock_type;
     share->global_changed=0;
-    lock_error=mi_lock_database(info,F_WRLCK);
+    lock_error= my_disable_locking ? 0 : mi_lock_database(info,F_WRLCK);
     /* Its not fatal even if we couldn't get the lock ! */
     if (share->state.open_count > 0)
     {
@@ -592,7 +592,7 @@
 			    sizeof(share->state.header),
 			    MYF(MY_NABP));
     }
-    if (!lock_error)
+    if (!lock_error && !my_disable_locking)
       lock_error=mi_lock_database(info,old_lock);
   }
   return test(lock_error || write_error);