List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:January 5 2010 9:34am
Subject:bzr commit into mysql-6.0-codebase-bugfixing branch (Li-Bing.Song:3798)
Bug#47442
View as plain text  
#At file:///home/anders/work/bzrwork/worktree4/mysql-6.0-codebase-bugfixing/ based on revid:dao-gang.qu@stripped

 3798 Li-Bing.Song@stripped	2010-01-05
      BUG#47442 BR breaks on CREATE TABLE IF EXISTS <existing VIEW> AS SELECT
      
      'CREATE TABLE IF NOT EXIST ... SELECT' statement is binlogged as 
      'CREATE TEMPORARY TABLE ...' with a wrong table name when a view exists 
      with the same name. 
      
      Base table is in the same name space with view. when excuting 
      open_and_lock_tables_derived, create_table is initialized as the
      existing view. and create_table->table is now a temporary table or base
      table which the view is derived. This cause a wrong binlog query which 
      leads slave crash.
      
      After a long time of discussion, we ultimately decided to do the following
      in this patch.
      about 'CREATE TABLE IF EXISTS <existing VIEW>(COLUMNS) AS SELECT ...' and
            'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...',
      the {COLUMNS and SELECT | LIKE} part are binlogged when a view exists with
      the same name.
      In another words, the binlog query is same as the binlog query
      which was binlogged when the table does not exist and it is
      created succefully.
      
      To implement the resolution, source table is used to binlog the query of 
      'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...'. A temporary table which is
      created by using the same query of 'CREATE TABLE IF EXISTS <existing VIEW>
      (COLUMNS) AS SELECT ...' is used to binlog 'CREATE TABLE IF EXISTS <existing VIEW>
      (COLUMNS) AS SELECT ...' statement.

    modified:
      mysql-test/suite/rpl/r/rpl_create_if_not_exists.result
      mysql-test/suite/rpl/t/rpl_create_if_not_exists.test
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_show.cc
      sql/sql_show.h
      sql/sql_table.cc
=== modified file 'mysql-test/suite/rpl/r/rpl_create_if_not_exists.result'
--- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result	2009-08-29 08:52:22 +0000
+++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result	2010-01-05 09:34:46 +0000
@@ -31,3 +31,124 @@ SHOW EVENTS in mysqltest;
 Db	Name	Definer	Time zone	Type	Execute at	Interval value	Interval field	Starts	Ends	Status	Originator	character_set_client	collation_connection	Database Collation
 mysqltest	e	root@localhost	SYSTEM	ONE TIME	#	NULL	NULL	NULL	NULL	SLAVESIDE_DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
 DROP DATABASE IF EXISTS mysqltest;
+#
+# BUG#47442
+#
+# 'CREATE TABLE IF NOT EXISTS ... SELECT' statement is binlogged as a
+# TEMPORARY table if the object exists as a view. At the same time a
+# wrong table name is binlogged, this caused that slave crashed.
+#
+# For solving the bug, if the object exist as a view,
+# 'CREATE TABLE IF NOT EXISTS ... SELECT[LIKE]'
+# is binlogged just same as what is binlogged when the view does not
+# exist and the table is created.
+USE test;
+DROP VIEW IF EXISTS t2;
+DROP TABLE IF EXISTS t1, t2, t3, t4, t5;
+CREATE TABLE t1(c1 INT KEY, c2 CHAR(100), c3 INT, INDEX(c2));
+CREATE TABLE t4(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE TABLE t5(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE VIEW t2 AS SELECT * FROM t1;
+INSERT INTO t4 VALUES(1, 'aa', 1, 'aa');
+INSERT INTO t4 VALUES(2, 'bb', 2, 'bb');
+DROP VIEW t2;
+
+# There is not base table in SELECT part
+CREATE TABLE IF NOT EXISTS t3 SELECT 2 AS c1, 'abc' AS c2;
+CREATE TABLE IF NOT EXISTS t2 SELECT 2 AS c1, 'abc' AS c2;
+# t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `c1` int(1) NOT NULL DEFAULT '0',
+  `c2` varchar(3) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `c1` int(1) NOT NULL DEFAULT '0',
+  `c2` varchar(3) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+# There is only one base table in SELECT part
+DROP TABLE t2;
+DROP TABLE t3;
+CREATE TABLE IF NOT EXISTS t3(c1 CHAR(10) KEY, c3 INT) SELECT c1, c2 FROM t4;
+CREATE TABLE IF NOT EXISTS t2(c1 CHAR(10) KEY, c3 INT) IGNORE SELECT c1, c2 FROM t4;
+# t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `c3` int(11) DEFAULT NULL,
+  `c1` char(10) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  PRIMARY KEY (`c1`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `c3` int(11) DEFAULT NULL,
+  `c1` char(10) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  PRIMARY KEY (`c1`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+# There is two base table in SELECT part
+DROP TABLE t2;
+DROP TABLE t3;
+CREATE TABLE IF NOT EXISTS t3(c1 CHAR(10) KEY, c3 INT, INDEX (c3)) SELECT t4.c1, t4.c2, t5.c4 FROM t4, t5;
+CREATE TABLE IF NOT EXISTS t2(c1 CHAR(10) KEY, c3 INT, INDEX (c3)) IGNORE SELECT t4.c1, t4.c2, t5.c4 FROM t4, t5;
+# t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `c3` int(11) DEFAULT NULL,
+  `c1` char(10) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  `c4` char(50) DEFAULT NULL,
+  PRIMARY KEY (`c1`),
+  KEY `c3` (`c3`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `c3` int(11) DEFAULT NULL,
+  `c1` char(10) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  `c4` char(50) DEFAULT NULL,
+  PRIMARY KEY (`c1`),
+  KEY `c3` (`c3`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+# CREATE TABLE IF NOT EXISTS LIKE test case
+DROP TABLE t2;
+DROP TABLE t3;
+CREATE TEMPORARY TABLE t4(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE TABLE IF NOT EXISTS t3 LIKE t4;
+CREATE TABLE IF NOT EXISTS t2 LIKE t4;
+DROP TEMPORARY TABLE t4;
+# t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `c1` int(11) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  `c3` int(11) DEFAULT NULL,
+  `c4` char(50) DEFAULT NULL,
+  PRIMARY KEY (`c1`),
+  KEY `c2` (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `c1` int(11) NOT NULL,
+  `c2` char(100) DEFAULT NULL,
+  `c3` int(11) DEFAULT NULL,
+  `c4` char(50) DEFAULT NULL,
+  PRIMARY KEY (`c1`),
+  KEY `c2` (`c2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1, t3, t4, t5;
+# the view t2 has been deleted from slave
+DROP VIEW IF EXISTS t2;

=== modified file 'mysql-test/suite/rpl/t/rpl_create_if_not_exists.test'
--- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test	2009-08-13 02:48:57 +0000
+++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test	2010-01-05 09:34:46 +0000
@@ -64,7 +64,97 @@ SHOW TABLES in mysqltest;
 replace_column 6 #;
 SHOW EVENTS in mysqltest;
 
-
 connection master;
 DROP DATABASE IF EXISTS mysqltest;
+
+--echo #
+--echo # BUG#47442
+--echo #
+--echo # 'CREATE TABLE IF NOT EXISTS ... SELECT' statement is binlogged as a
+--echo # TEMPORARY table if the object exists as a view. At the same time a
+--echo # wrong table name is binlogged, this caused that slave crashed.
+--echo #
+--echo # For solving the bug, if the object exist as a view,
+--echo # 'CREATE TABLE IF NOT EXISTS ... SELECT[LIKE]'
+--echo # is binlogged just same as what is binlogged when the view does not
+--echo # exist and the table is created.
+
+connection master;
+USE test;
+--disable_warnings
+DROP VIEW IF EXISTS t2;
+DROP TABLE IF EXISTS t1, t2, t3, t4, t5;
+--enable_warnings
+
+CREATE TABLE t1(c1 INT KEY, c2 CHAR(100), c3 INT, INDEX(c2));
+CREATE TABLE t4(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE TABLE t5(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE VIEW t2 AS SELECT * FROM t1;
+
+INSERT INTO t4 VALUES(1, 'aa', 1, 'aa');
+INSERT INTO t4 VALUES(2, 'bb', 2, 'bb');
+sync_slave_with_master;
+DROP VIEW t2;
+
+--echo
+--echo # There is not base table in SELECT part
+connection master;
+CREATE TABLE IF NOT EXISTS t3 SELECT 2 AS c1, 'abc' AS c2;
+--disable_warnings
+CREATE TABLE IF NOT EXISTS t2 SELECT 2 AS c1, 'abc' AS c2;
+--enable_warnings
+sync_slave_with_master;
+--echo # t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+SHOW CREATE TABLE t2;
+
+--echo
+--echo # There is only one base table in SELECT part
+DROP TABLE t2;
+connection master;
+DROP TABLE t3;
+CREATE TABLE IF NOT EXISTS t3(c1 CHAR(10) KEY, c3 INT) SELECT c1, c2 FROM t4;
+--disable_warnings
+CREATE TABLE IF NOT EXISTS t2(c1 CHAR(10) KEY, c3 INT) IGNORE SELECT c1, c2 FROM t4;
+--enable_warnings
+sync_slave_with_master;
+--echo # t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+SHOW CREATE TABLE t2;
+
+--echo
+--echo # There is two base table in SELECT part
+DROP TABLE t2;
+connection master;
+DROP TABLE t3;
+CREATE TABLE IF NOT EXISTS t3(c1 CHAR(10) KEY, c3 INT, INDEX (c3)) SELECT t4.c1, t4.c2, t5.c4 FROM t4, t5;
+--disable_warnings
+CREATE TABLE IF NOT EXISTS t2(c1 CHAR(10) KEY, c3 INT, INDEX (c3)) IGNORE SELECT t4.c1, t4.c2, t5.c4 FROM t4, t5;
+--enable_warnings
+sync_slave_with_master;
+--echo # t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+SHOW CREATE TABLE t2;
+
+--echo
+--echo # CREATE TABLE IF NOT EXISTS LIKE test case
+DROP TABLE t2;
+connection master;
+DROP TABLE t3;
+CREATE TEMPORARY TABLE t4(c1 INT KEY, c2 CHAR(100), c3 INT, c4 CHAR(50), INDEX(c2));
+CREATE TABLE IF NOT EXISTS t3 LIKE t4;
+--disable_warnings
+CREATE TABLE IF NOT EXISTS t2 LIKE t4;
+--enable_warnings
+DROP TEMPORARY TABLE t4;
+sync_slave_with_master;
+--echo # t2 and t3 have the same structure
+SHOW CREATE TABLE t3;
+SHOW CREATE TABLE t2;
+
+DROP TABLE t2;
+connection master;
+DROP TABLE t1, t3, t4, t5;
+--echo # the view t2 has been deleted from slave
+DROP VIEW IF EXISTS t2;
 source include/master-slave-end.inc;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-12-19 08:37:36 +0000
+++ b/sql/sql_class.h	2010-01-05 09:34:46 +0000
@@ -2890,6 +2890,8 @@ class select_create: public select_inser
   MYSQL_LOCK *m_lock;
   /* m_lock or thd->extra_lock */
   MYSQL_LOCK **m_plock;
+
+  TABLE *create_temporary_table(List<Item> *items);
 public:
   select_create (TABLE_LIST *table_arg,
 		 HA_CREATE_INFO *create_info_par,

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-12-19 08:37:36 +0000
+++ b/sql/sql_insert.cc	2010-01-05 09:34:46 +0000
@@ -3693,6 +3693,76 @@ static TABLE *create_table_from_items(TH
   DBUG_RETURN(table);
 }
 
+TABLE *
+select_create::create_temporary_table(List<Item> *items)
+{
+  char table_name[NAME_CHAR_LEN];
+  char path[FN_REFLEN];
+  bool error;
+  TABLE tmp_table;
+  TABLE_SHARE share;
+  Field *tmp_field;
+  Item *item;
+  List_iterator_fast<Item> it(*items);
+
+  tmp_table.alias= 0;
+  tmp_table.timestamp_field= 0;
+  tmp_table.s= &share;
+  init_tmp_table_share(thd, &share, "", 0, "", "");
+
+  tmp_table.s->db_create_options= 0;
+  tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
+  tmp_table.s->db_low_byte_first=
+        test(create_info->db_type == myisam_hton ||
+             create_info->db_type == heap_hton);
+  tmp_table.null_row= 0;
+  tmp_table.maybe_null= 0;
+
+  /* Add selected items to field list */
+  while ((item=it++))
+  {
+    Create_field *cr_field;
+    Field *field, *def_field;
+    if (item->type() == Item::FUNC_ITEM)
+      if (item->result_type() != STRING_RESULT)
+        field= item->tmp_table_field(&tmp_table);
+      else
+        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
+    else
+      field= create_tmp_field(thd, &tmp_table, item, item->type(),
+                              (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
+                              0);
+    if (!field ||
+	!(cr_field=new Create_field(field,(item->type() == Item::FIELD_ITEM ?
+					   ((Item_field *)item)->field :
+					   (Field*) 0))))
+      return NULL;
+    if (item->maybe_null)
+      cr_field->flags &= ~NOT_NULL_FLAG;
+    alter_info->create_list.push_back(cr_field);
+  }
+
+  bzero(table_name, sizeof(table_name));
+  my_snprintf(table_name, sizeof(table_name), "%s-%lx_%lx_create_select", tmp_file_prefix,
+              current_pid, thd->thread_id);
+  /* Safety fix for innodb */
+  if (lower_case_table_names)
+    my_casedn_str(files_charset_info, table_name);
+
+  // We don't log the statement.
+  tmp_disable_binlog(thd);
+  error= mysql_create_table_no_lock(thd, create_table->db, table_name,
+                                    create_info, alter_info, 1, items->elements);
+  reenable_binlog(thd);
+  if (error)
+    return NULL;
+
+  bzero(path, sizeof(path));
+  build_table_filename(path, sizeof(path), create_table->db, table_name, "",
+                       FN_IS_TMP);
+  return open_temporary_table(thd, path, create_table->db, table_name, 1,
+                              OTM_OPEN);
+}
 
 int
 select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
@@ -3785,14 +3855,49 @@ select_create::prepare(List<Item> &value
     /* Table already exists and was open at open_and_lock_tables() stage. */
     if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
     {
-      /* Mark that table existed */
-      create_info->table_existed= 1;
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                           ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
                           create_table->table_name);
-      if (thd->current_stmt_binlog_row_based)
-        binlog_show_create_table(&(create_table->table), 1);
+      if (thd->current_stmt_binlog_row_based && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
+      {
+        /*
+          BUG#47442 'CREATE TABLE IF NOT EXIST ... SELECT' statement is
+          binlogged as 'CREATE TEMPORARY TABLE ...' with a wrong table name
+          when a view exists with the same name.
+
+          To solve the bug, the structure of 'SELECT' part is binlogged
+          when the table exists as a view.
+          In another words, the binlog query is same as the binlog query
+          which was binlogged when the table does not exist and it is
+          created succefully.
+         */
+        if (create_table->view)
+        {
+          TABLE *tmp_table= create_temporary_table(&values);
+          if (tmp_table)
+          {
+            LEX_STRING table_name;
+            const char *alias;
+            alias= tmp_table->alias;
+            table_name= tmp_table->s->table_name;
+            tmp_table->alias= create_table->view_name.str;
+            tmp_table->s->table_name= create_table->view_name;
+            binlog_show_create_table(&tmp_table, 1);
+            tmp_table->alias= alias;
+            tmp_table->s->table_name= table_name;
+            close_temporary_table(thd, tmp_table, 1, 1);
+          }
+          else
+          {
+            // Should we generate an error ?
+          }
+        }
+        else
+          binlog_show_create_table(&(create_table->table), 1);
+      }
       table= create_table->table;
+      /* Mark that table existed */
+      create_info->table_existed= 1;
     }
     else
     {

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-12-19 08:44:59 +0000
+++ b/sql/sql_show.cc	2010-01-05 09:34:46 +0000
@@ -1091,7 +1091,8 @@ static bool get_field_default_value(THD 
                       prepended to the table name if either the
                       current database is not set, or if it is set and
                       it is different from the database for the table.
-
+    table_name        if not NULL, it is the table name which will be
+                      binlogged(used in CREATE TABLE ... LIKE).
   NOTE
     Currently always return 0, but might return error code in the
     future.
@@ -1101,7 +1102,8 @@ static bool get_field_default_value(THD 
  */
 
 int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
-                      HA_CREATE_INFO *create_info_arg, bool show_database)
+                      HA_CREATE_INFO *create_info_arg, bool show_database,
+                      const char *table_name)
 {
   List<Item> field_list;
   char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
@@ -1131,14 +1133,17 @@ int store_create_info(THD *thd, TABLE_LI
 
   restore_record(table, s->default_values); // Get empty record
 
-  if (share->tmp_table)
+  if ((create_info_arg && create_info_arg->options & HA_LEX_CREATE_TMP_TABLE)
+      || (!create_info_arg && share->tmp_table))
     packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
   else
     packet->append(STRING_WITH_LEN("CREATE TABLE "));
   if (create_info_arg &&
       (create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
     packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
-  if (table_list->schema_table)
+  if (table_name != NULL)
+    alias= table_name;
+  else if (table_list->schema_table)
     alias= table_list->schema_table->table_name;
   else
   {

=== modified file 'sql/sql_show.h'
--- a/sql/sql_show.h	2009-10-12 09:08:34 +0000
+++ b/sql/sql_show.h	2010-01-05 09:34:46 +0000
@@ -33,7 +33,8 @@ find_files_result find_files(THD *thd, L
                              const char *path, const char *wild, bool dir);
 
 int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
-                      HA_CREATE_INFO  *create_info_arg, bool show_database);
+                      HA_CREATE_INFO  *create_info_arg, bool show_database,
+                      const char *table_name= NULL);
 bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
                           HA_CREATE_INFO *create_info, const char *orig_dbname);
 int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2009-12-19 08:37:36 +0000
+++ b/sql/sql_table.cc	2010-01-05 09:34:46 +0000
@@ -5280,42 +5280,49 @@ bool mysql_create_like_table(THD* thd, T
         String query(buf, sizeof(buf), system_charset_info);
         query.length(0);  // Have to zero it since constructor doesn't
         Open_table_context ot_ctx_unused(thd);
+        TABLE_LIST *binlog_table;
 
         /*
-          The condition avoids a crash as described in BUG#48506. Other
-          binlogging problems related to CREATE TABLE IF NOT EXISTS LIKE
-          when the existing object is a view will be solved by BUG 47442.
-        */
-        if (!table->view)
-        {
-          /*
-            Here we open the destination table, on which we already have
-            exclusive metadata lock. This is needed for store_create_info()
-            to work. The table will be closed by close_thread_table() at
-            the end of this branch.
-          */
-          if (open_table(thd, table, thd->mem_root, &ot_ctx_unused,
+          Here we open the destination table, on which we already have
+          exclusive metadata lock. This is needed for store_create_info()
+          to work. The table will be closed by close_thread_table() at
+          the end of this branch.
+         */
+        if (open_table(thd, table, thd->mem_root, &ot_ctx_unused,
                        MYSQL_OPEN_REOPEN))
-            goto err;
+          goto err;
 
-          int result __attribute__((unused))=
-            store_create_info(thd, table, &query,
-                              create_info, FALSE /* show_database */);
-
-          DBUG_ASSERT(result == 0); // store_create_info() always return 0
-          if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
-            goto err;
-
-          DBUG_ASSERT(thd->open_tables == table->table);
-          mysql_mutex_lock(&LOCK_open);
-          /*
-            When opening the table, we ignored the locked tables
-            (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table without
-            risking to close some locked table.
-          */
-          close_thread_table(thd, &thd->open_tables);
-          mysql_mutex_unlock(&LOCK_open);
-        }
+        /*
+          The structure of source table is binlogged with the table name
+          which user wants to create when the table exists as a view.
+          In another words, the binlog query is same as the binlog query
+          which was binlogged when the table does not exist and it is
+          created succefully.
+         */
+        if (table->view)
+          binlog_table= src_table;
+        else
+          binlog_table= table;
+
+        int result __attribute__((unused))=
+          store_create_info(thd, binlog_table, &query,
+                            create_info, FALSE,
+                            (lower_case_table_names ?
+                             table->alias : table->table_name));
+
+        DBUG_ASSERT(result == 0); // store_create_info() always return 0
+        if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
+          goto err;
+
+//        DBUG_ASSERT(thd->open_tables == table->table);
+        mysql_mutex_lock(&LOCK_open);
+        /*
+          When opening the table, we ignored the locked tables
+          (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table without
+          risking to close some locked table.
+         */
+        close_thread_table(thd, &thd->open_tables);
+        mysql_mutex_unlock(&LOCK_open);
       }
       else                                      // Case 1
         if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20100105093446-og2gg3w8x4u91sne.bundle
Thread
bzr commit into mysql-6.0-codebase-bugfixing branch (Li-Bing.Song:3798)Bug#47442Li-Bing.Song5 Jan
  • Re: bzr commit into mysql-6.0-codebase-bugfixing branch(Li-Bing.Song:3798) Bug#47442Sven Sandberg11 Jan
  • Re: bzr commit into mysql-6.0-codebase-bugfixing branch(Li-Bing.Song:3798) Bug#47442Sven Sandberg12 Jan
    • Re: bzr commit into mysql-6.0-codebase-bugfixing branch(Li-Bing.Song:3798) Bug#47442Libing Song21 Jan