List:Commits« Previous MessageNext Message »
From:Tatjana Azundris Nuernberg Date:April 1 2012 10:31am
Subject:bzr push into mysql-trunk branch (tatjana.nuernberg:3827 to 3829)
View as plain text  
 3829 Tatjana Azundris Nuernberg	2012-03-31 [merge]
      manual merge

    modified:
      mysql-test/suite/opt_trace/r/general_no_prot_all.result
      mysql-test/suite/opt_trace/r/general_no_prot_none.result
      mysql-test/suite/opt_trace/r/general_ps_prot_all.result
      mysql-test/suite/opt_trace/r/general_ps_prot_none.result
      sql/mysqld.cc
      sql/mysqld.h
      sql/sp_head.cc
      sql/sql_parse.cc
      sql/sql_parse.h
      sql/sql_plugin.cc
 3828 Tatjana Azundris Nuernberg	2012-03-31 [merge]
      auto merge

    modified:
      mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result
      mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test
      storage/innobase/row/row0mysql.cc
 3827 Serge Kozlov	2012-03-30
      Bug#13869905 post-fix for parts suite

    modified:
      mysql-test/suite/parts/r/rpl-partition-dml-1-1-innodb.result
      mysql-test/suite/parts/r/rpl-partition-dml-1-1-myisam.result
      mysql-test/suite/parts/r/rpl_partition.result
=== modified file 'mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result'
--- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result	2012-02-01 14:09:34 +0000
+++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result	2012-03-30 23:54:01 +0000
@@ -856,3 +856,46 @@ SELECT * FROM t2 WHERE MATCH(fts_field) 
 id	fts_field
 DROP TABLE t1;
 DROP TABLE t2;
+
+BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY
+
+SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
+CREATE TABLE t1 (
+t1_id INT(10) UNSIGNED NOT NULL,
+t2_id INT(10) UNSIGNED DEFAULT NULL,
+PRIMARY KEY (t1_id),
+FOREIGN KEY (t2_id) REFERENCES t2 (t2_id)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+t1_id INT(10) UNSIGNED NOT NULL,
+t2_id INT(10) UNSIGNED NOT NULL,
+t3_id INT(10) UNSIGNED NOT NULL,
+t4_id INT(10) UNSIGNED NOT NULL,
+PRIMARY KEY (t2_id),
+FOREIGN KEY (t1_id) REFERENCES t1 (t1_id),
+FOREIGN KEY (t3_id) REFERENCES t3 (t3_id)
+ON DELETE CASCADE ON UPDATE CASCADE,
+FOREIGN KEY (t4_id) REFERENCES t4 (t4_id)
+) ENGINE=InnoDB;
+CREATE TABLE t3 (
+t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+payload char(3),
+PRIMARY KEY (t3_id)
+) ENGINE=InnoDB;
+INSERT INTO t3 VALUES (1, '100');
+CREATE TABLE t4 (
+t2_id INT(10) UNSIGNED DEFAULT NULL,
+t4_id INT(10) UNSIGNED NOT NULL,
+PRIMARY KEY (t4_id),
+FOREIGN KEY (t2_id) REFERENCES t2 (t2_id)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+SET FOREIGN_KEY_CHECKS=1;
+UPDATE t3 SET payload='101' WHERE t3_id=1;
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;

=== modified file 'mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test'
--- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test	2011-12-20 09:45:15 +0000
+++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test	2012-03-23 08:54:26 +0000
@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# FTS with FK and update casecade
+# FTS with FK and update cascade
 #-------------------------------------------------------------------------------
 --disable_warnings
 drop table if exists t2,t1;
@@ -830,3 +830,60 @@ DROP TABLE t1;
 
 DROP TABLE t2;
 
+
+--echo
+--echo BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY
+--echo
+# FTS setup did not track which tables it had already looked at to see whether
+# they need initialization. Hilarity ensued when hitting circular dependencies.
+
+SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
+
+CREATE TABLE t1 (
+  t1_id INT(10) UNSIGNED NOT NULL,
+  t2_id INT(10) UNSIGNED DEFAULT NULL,
+  PRIMARY KEY (t1_id),
+  FOREIGN KEY (t2_id) REFERENCES t2 (t2_id)
+    ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+  t1_id INT(10) UNSIGNED NOT NULL,
+  t2_id INT(10) UNSIGNED NOT NULL,
+  t3_id INT(10) UNSIGNED NOT NULL,
+  t4_id INT(10) UNSIGNED NOT NULL,
+  PRIMARY KEY (t2_id),
+  FOREIGN KEY (t1_id) REFERENCES t1 (t1_id),
+  FOREIGN KEY (t3_id) REFERENCES t3 (t3_id)
+    ON DELETE CASCADE ON UPDATE CASCADE,
+  FOREIGN KEY (t4_id) REFERENCES t4 (t4_id)
+) ENGINE=InnoDB;
+
+CREATE TABLE t3 (
+  t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  payload char(3),
+  PRIMARY KEY (t3_id)
+) ENGINE=InnoDB;
+
+INSERT INTO t3 VALUES (1, '100');
+
+CREATE TABLE t4 (
+  t2_id INT(10) UNSIGNED DEFAULT NULL,
+  t4_id INT(10) UNSIGNED NOT NULL,
+  PRIMARY KEY (t4_id),
+  FOREIGN KEY (t2_id) REFERENCES t2 (t2_id)
+    ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+SET FOREIGN_KEY_CHECKS=1;
+
+UPDATE t3 SET payload='101' WHERE t3_id=1;
+
+SET FOREIGN_KEY_CHECKS=0;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+
+SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;

=== modified file 'mysql-test/suite/opt_trace/r/general_no_prot_all.result'
--- a/mysql-test/suite/opt_trace/r/general_no_prot_all.result	2012-03-28 13:39:57 +0000
+++ b/mysql-test/suite/opt_trace/r/general_no_prot_all.result	2012-03-31 18:30:05 +0000
@@ -8198,7 +8198,7 @@ set res@1 NULL	{
   "steps": [
   ] /* steps */
 }	0	0
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {
@@ -8838,7 +8838,7 @@ freturn 3 ret@0	{
   "steps": [
   ] /* steps */
 }	0	0
-select d+1 into res from t6 where d= NAME_CONST('res',NULL)+1	{
+select d+1 into res from t6 where d=res+1	{
   "steps": [
     {
       "join_preparation": {
@@ -9772,7 +9772,7 @@ Warnings:
 Warning	1329	No data - zero rows fetched, selected, or processed
 select * from optt|
 QUERY	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	INSUFFICIENT_PRIVILEGES
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {

=== modified file 'mysql-test/suite/opt_trace/r/general_no_prot_none.result'
--- a/mysql-test/suite/opt_trace/r/general_no_prot_none.result	2012-03-28 13:39:57 +0000
+++ b/mysql-test/suite/opt_trace/r/general_no_prot_none.result	2012-03-31 18:30:05 +0000
@@ -7145,7 +7145,7 @@ set res@1 NULL	{
   "steps": [
   ] /* steps */
 }	0	0
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {
@@ -7920,7 +7920,7 @@ freturn 3 ret@0	{
   "steps": [
   ] /* steps */
 }	0	0
-select d+1 into res from t6 where d= NAME_CONST('res',NULL)+1	{
+select d+1 into res from t6 where d=res+1	{
   "steps": [
     {
       "join_preparation": {
@@ -8854,7 +8854,7 @@ Warnings:
 Warning	1329	No data - zero rows fetched, selected, or processed
 select * from optt|
 QUERY	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	INSUFFICIENT_PRIVILEGES
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {

=== modified file 'mysql-test/suite/opt_trace/r/general_ps_prot_all.result'
--- a/mysql-test/suite/opt_trace/r/general_ps_prot_all.result	2012-03-28 13:39:57 +0000
+++ b/mysql-test/suite/opt_trace/r/general_ps_prot_all.result	2012-03-31 18:30:05 +0000
@@ -8159,7 +8159,7 @@ set res@1 NULL	{
   "steps": [
   ] /* steps */
 }	0	0
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {
@@ -8799,7 +8799,7 @@ freturn 3 ret@0	{
   "steps": [
   ] /* steps */
 }	0	0
-select d+1 into res from t6 where d= NAME_CONST('res',NULL)+1	{
+select d+1 into res from t6 where d=res+1	{
   "steps": [
     {
       "join_preparation": {
@@ -9747,7 +9747,7 @@ Warnings:
 Warning	1329	No data - zero rows fetched, selected, or processed
 select * from optt|
 QUERY	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	INSUFFICIENT_PRIVILEGES
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {

=== modified file 'mysql-test/suite/opt_trace/r/general_ps_prot_none.result'
--- a/mysql-test/suite/opt_trace/r/general_ps_prot_none.result	2012-03-28 13:39:57 +0000
+++ b/mysql-test/suite/opt_trace/r/general_ps_prot_none.result	2012-03-31 18:30:05 +0000
@@ -7066,7 +7066,7 @@ set res@1 NULL	{
   "steps": [
   ] /* steps */
 }	0	0
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {
@@ -7841,7 +7841,7 @@ freturn 3 ret@0	{
   "steps": [
   ] /* steps */
 }	0	0
-select d+1 into res from t6 where d= NAME_CONST('res',NULL)+1	{
+select d+1 into res from t6 where d=res+1	{
   "steps": [
     {
       "join_preparation": {
@@ -8789,7 +8789,7 @@ Warnings:
 Warning	1329	No data - zero rows fetched, selected, or processed
 select * from optt|
 QUERY	TRACE	MISSING_BYTES_BEYOND_MAX_MEM_SIZE	INSUFFICIENT_PRIVILEGES
-select d into res from t6 where d in (select f1() from t2 where s= NAME_CONST('arg',_latin1'c' COLLATE 'latin1_swedish_ci'))	{
+select d into res from t6 where d in (select f1() from t2 where s=arg)	{
   "steps": [
     {
       "join_preparation": {

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-03-22 06:25:38 +0000
+++ b/sql/mysqld.cc	2012-03-31 18:30:05 +0000
@@ -402,6 +402,8 @@ ulong slow_start_timeout;
   SQL commands in the init file and in --bootstrap mode.
 */
 bool in_bootstrap= FALSE;
+my_bool opt_bootstrap;
+
 /**
    @brief 'grant_option' is used to indicate if privileges needs
    to be checked, in which case the lock, LOCK_grant, is used
@@ -716,7 +718,7 @@ char *opt_logname, *opt_slow_logname, *o
 static volatile sig_atomic_t kill_in_progress;
 
 
-static my_bool opt_bootstrap, opt_myisam_log;
+static my_bool opt_myisam_log;
 static int cleanup_done;
 static ulong opt_specialflag;
 static char *opt_update_logname;

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2012-03-28 13:39:57 +0000
+++ b/sql/mysqld.h	2012-03-31 18:30:05 +0000
@@ -107,6 +107,7 @@ extern bool opt_ignore_builtin_innodb;
 extern my_bool opt_character_set_client_handshake;
 extern bool volatile abort_loop;
 extern bool in_bootstrap;
+extern my_bool opt_bootstrap;
 extern uint connection_count;
 extern my_bool opt_safe_user_create;
 extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2012-03-21 14:49:40 +0000
+++ b/sql/sp_head.cc	2012-03-31 18:30:05 +0000
@@ -3055,51 +3055,115 @@ int sp_instr::exec_core(THD *thd, uint *
 int
 sp_instr_stmt::execute(THD *thd, uint *nextp)
 {
-  int res;
+  int res= 0;
+  bool need_subst;
+
   DBUG_ENTER("sp_instr_stmt::execute");
   DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
 
   const CSET_STRING query_backup= thd->query_string;
+
 #if defined(ENABLED_PROFILING)
   /* This s-p instr is profilable and will be captured. */
   thd->profiling.set_query_source(m_query.str, m_query.length);
 #endif
-  if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
-      !(res=subst_spvars(thd, this, &m_query)))
+
+  /*
+    If we can't set thd->query_string at all, we give up on this statement.
+  */
+  if (alloc_query(thd, m_query.str, m_query.length))
+    DBUG_RETURN(TRUE);
+
+  /*
+    Check whether we actually need a substitution of SP variables with
+    NAME_CONST(...) (using subst_spvars()).
+    If both of the following apply, we won't need to substitute:
+
+    - general log is off
+
+    - binary logging is off, or not in statement mode
+
+    We don't have to substitute on behalf of the query cache as
+    queries with SP vars are not cached, anyway.
+
+    query_name_consts is used elsewhere in a special case concerning
+    CREATE TABLE, but we do not need to do anything about that here.
+
+    The slow query log is another special case: we won't know whether a
+    query qualifies for the slow query log until after it's been
+    executed. We assume that most queries are not slow, so we do not
+    pre-emptively substitute just for the slow query log. If a query
+    ends up being slow after all and we haven't done the substitution
+    already for any of the above (general log etc.), we'll do the
+    substitution immediately before writing to the log.
+  */
+
+  need_subst= ((thd->variables.option_bits & OPTION_LOG_OFF) &&
+               (!(thd->variables.option_bits & OPTION_BIN_LOG) ||
+                !mysql_bin_log.is_open() ||
+                thd->is_current_stmt_binlog_format_row())) ? FALSE : TRUE;
+
+  /*
+    If we need to do a substitution but can't (OOM), give up.
+  */
+
+  if (need_subst && subst_spvars(thd, this, &m_query))
+    DBUG_RETURN(TRUE);
+
+  /*
+    (the order of query cache and subst_spvars calls is irrelevant because
+    queries with SP vars can't be cached)
+  */
+  if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
+    general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
+
+  if (query_cache_send_result_to_client(thd, thd->query(),
+                                        thd->query_length()) <= 0)
   {
-    /*
-      (the order of query cache and subst_spvars calls is irrelevant because
-      queries with SP vars can't be cached)
-    */
-    if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
-      general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
+    res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
 
-    if (query_cache_send_result_to_client(thd, thd->query(),
-                                          thd->query_length()) <= 0)
+    if (thd->get_stmt_da()->is_eof())
     {
-      res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+      /* Finalize server status flags after executing a statement. */
+      thd->update_server_status();
 
-      if (thd->get_stmt_da()->is_eof())
-      {
-        /* Finalize server status flags after executing a statement. */
-        thd->update_server_status();
-
-        thd->protocol->end_statement();
-      }
+      thd->protocol->end_statement();
+    }
 
-      query_cache_end_of_result(thd);
+    query_cache_end_of_result(thd);
 
-      if (!res && unlikely(thd->enable_slow_log))
-        log_slow_statement(thd);
+    if (!res && unlikely(log_slow_applicable(thd)))
+    {
+      /*
+        We actually need to write the slow log. Check whether we already
+        called subst_spvars() above, otherwise, do it now.  In the highly
+        unlikely event of subst_spvars() failing (OOM), we'll try to log
+        the unmodified statement instead.
+      */
+      if (!need_subst)
+        res= subst_spvars(thd, this, &m_query);
+      log_slow_do(thd);
     }
-    else
-      *nextp= m_ip+1;
-    thd->set_query(query_backup);
-    thd->query_name_consts= 0;
 
-    if (!thd->is_error())
-      thd->get_stmt_da()->reset_diagnostics_area();
+    /*
+      With the current setup, a subst_spvars() and a mysql_rewrite_query()
+      (rewriting passwords etc.) will not both happen to a query.
+      If this ever changes, we give the engineer pause here so they will
+      double-check whether the potential conflict they created is a
+      problem.
+    */
+    DBUG_ASSERT((thd->query_name_consts == 0) ||
+                (thd->rewritten_query.length() == 0));
   }
+  else
+    *nextp= m_ip+1;
+
+  thd->set_query(query_backup);
+  thd->query_name_consts= 0;
+
+  if (!thd->is_error())
+    thd->get_stmt_da()->reset_diagnostics_area();
+
   DBUG_RETURN(res || thd->is_error());
 }
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2012-03-30 15:38:01 +0000
+++ b/sql/sql_parse.cc	2012-03-31 18:30:05 +0000
@@ -1685,9 +1685,22 @@ bool dispatch_command(enum enum_server_c
 }
 
 
-void log_slow_statement(THD *thd)
+/**
+  Check whether we need to write the current statement (or its rewritten
+  version if it exists) to the slow query log.
+  As a side-effect, a digest of suppressed statements may be written.
+
+  @param thd          thread handle
+
+  @retval
+    true              statement needs to be logged
+  @retval
+    false             statement does not need to be logged
+*/
+
+bool log_slow_applicable(THD *thd)
 {
-  DBUG_ENTER("log_slow_statement");
+  DBUG_ENTER("log_slow_applicable");
 
   /*
     The following should never be true with our current code base,
@@ -1695,7 +1708,7 @@ void log_slow_statement(THD *thd)
     statement in a trigger or stored function
   */
   if (unlikely(thd->in_sub_stmt))
-    DBUG_VOID_RETURN;                           // Don't set time for sub stmt
+    DBUG_RETURN(false);                         // Don't set time for sub stmt
 
   /*
     Do not log administrative statements unless the appropriate option is
@@ -1716,18 +1729,57 @@ void log_slow_statement(THD *thd)
     bool suppress_logging= log_throttle_qni.log(thd, warn_no_index);
 
     if (!suppress_logging && log_this_query)
-    {
-      THD_STAGE_INFO(thd, stage_logging_slow_query);
-      thd->status_var.long_query_count++;
-
-      if (thd->rewritten_query.length())
-        slow_log_print(thd,
-                       thd->rewritten_query.c_ptr_safe(),
-                       thd->rewritten_query.length());
-      else
-        slow_log_print(thd, thd->query(), thd->query_length());
-    }
+      DBUG_RETURN(true);
   }
+  DBUG_RETURN(false);
+}
+
+
+/**
+  Unconditionally the current statement (or its rewritten version if it
+  exists) to the slow query log.
+
+  @param thd              thread handle
+*/
+
+void log_slow_do(THD *thd)
+{
+  DBUG_ENTER("log_slow_do");
+
+  THD_STAGE_INFO(thd, stage_logging_slow_query);
+  thd->status_var.long_query_count++;
+
+  if (thd->rewritten_query.length())
+    slow_log_print(thd,
+                   thd->rewritten_query.c_ptr_safe(),
+                   thd->rewritten_query.length());
+  else
+    slow_log_print(thd, thd->query(), thd->query_length());
+
+  DBUG_VOID_RETURN;
+}
+
+
+/**
+  Check whether we need to write the current statement to the slow query
+  log. If so, do so. This is a wrapper for the two functions above;
+  most callers should use this wrapper.  Only use the above functions
+  directly if you have expensive rewriting that you only need to do if
+  the query actually needs to be logged (e.g. SP variables / NAME_CONST
+  substitution when executing a PROCEDURE).
+  A digest of suppressed statements may be logged instead of the current
+  statement.
+
+  @param thd              thread handle
+*/
+
+void log_slow_statement(THD *thd)
+{
+  DBUG_ENTER("log_slow_statement");
+
+  if (log_slow_applicable(thd))
+    log_slow_do(thd);
+
   DBUG_VOID_RETURN;
 }
 

=== modified file 'sql/sql_parse.h'
--- a/sql/sql_parse.h	2012-01-16 22:21:16 +0000
+++ b/sql/sql_parse.h	2012-03-31 18:30:05 +0000
@@ -104,6 +104,8 @@ void do_handle_bootstrap(THD *thd);
 bool dispatch_command(enum enum_server_command command, THD *thd,
 		      char* packet, uint packet_length);
 void log_slow_statement(THD *thd);
+bool log_slow_applicable(THD *thd);
+void log_slow_do(THD *thd);
 bool append_file_to_dir(THD *thd, const char **filename_ptr,
                         const char *table_name);
 bool append_file_to_dir(THD *thd, const char **filename_ptr,

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2012-03-14 01:50:20 +0000
+++ b/sql/sql_plugin.cc	2012-03-31 18:30:05 +0000
@@ -1003,7 +1003,8 @@ static void reap_plugins(void)
   list= reap;
   while ((plugin= *(--list)))
   {
-    sql_print_information("Shutting down plugin '%s'", plugin->name.str);
+    if (!opt_bootstrap)
+      sql_print_information("Shutting down plugin '%s'", plugin->name.str);
     plugin_deinitialize(plugin, true);
   }
 

=== modified file 'storage/innobase/row/row0mysql.cc'
--- a/storage/innobase/row/row0mysql.cc	2012-03-29 11:19:57 +0000
+++ b/storage/innobase/row/row0mysql.cc	2012-03-30 23:54:01 +0000
@@ -1531,16 +1531,18 @@ void
 init_fts_doc_id_for_ref(
 /*====================*/
 	dict_table_t*	table,		/*!< in: table */
-	ulint		depth)		/*!< in: recusive call depth */
+	ulint*		depth)		/*!< in: recusive call depth */
 {
 	dict_foreign_t* foreign;
 
 	foreign = UT_LIST_GET_FIRST(table->referenced_list);
 
-	depth++;
+	table->fk_max_recusive_level = 0;
+
+	(*depth)++;
 
 	/* Limit on tables involved in cascading delete/update */
-	if (depth > FK_MAX_CASCADE_DEL) {
+	if (*depth > FK_MAX_CASCADE_DEL) {
 		return;
 	}
 
@@ -1581,6 +1583,7 @@ row_update_for_mysql(
 	upd_node_t*	node;
 	dict_table_t*	table		= prebuilt->table;
 	trx_t*		trx		= prebuilt->trx;
+	ulint		fk_depth	= 0;
 
 	ut_ad(prebuilt && trx);
 	UT_NOT_USED(mysql_rec);
@@ -1631,7 +1634,7 @@ row_update_for_mysql(
 
 	row_mysql_delay_if_needed();
 
-	init_fts_doc_id_for_ref(table, 0);
+	init_fts_doc_id_for_ref(table, &fk_depth);
 
 	trx_start_if_not_started_xa(trx);
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (tatjana.nuernberg:3827 to 3829) Tatjana Azundris Nuernberg1 Apr