List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:November 2 2007 5:28pm
Subject:bk commit into 5.1 tree (istruewing:1.2595) BUG#26379
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-02 17:28:19+01:00, istruewing@stripped +34 -0
  Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
              corrupts a MERGE table
  Bug 26867 - LOCK TABLES + REPAIR + merge table result in
              memory/cpu hogging
  Bug 26377 - Deadlock with MERGE and FLUSH TABLE
  Bug 25038 - Waiting TRUNCATE
  Bug 25700 - merge base tables get corrupted by
              optimize/analyze/repair table
  Bug 30275 - Merge tables: flush tables or unlock tables
              causes server to crash
  Bug 19627 - temporary merge table locking
  Bug 27660 - Falcon: merge table possible
  Bug 30273 - merge tables: Can't lock file (errno: 155)
  
  The problems were:
  
  Bug 26379 - Combination of FLUSH TABLE and REPAIR TABLE
                  corrupts a MERGE table
  
    1. A thread trying to lock a MERGE table performs busy waiting while
       REPAIR TABLE or a similar table administration task is ongoing on
       one or more of its MyISAM tables.
    
    2. A thread trying to lock a MERGE table performs busy waiting until all
       threads that did REPAIR TABLE or similar table administration tasks
       on one or more of its MyISAM tables in LOCK TABLES segments do UNLOCK
       TABLES. The difference against problem #1 is that the busy waiting
       takes place *after* the administration task. It is terminated by
       UNLOCK TABLES only.
    
    3. Two FLUSH TABLES within a LOCK TABLES segment can invalidate the
       lock. This does *not* require a MERGE table. The first FLUSH TABLES
       can be replaced by any statement that requires other threads to
       reopen the table. In 5.0 and 5.1 a single FLUSH TABLES can provoke
       the problem.
  
  Bug 26867 - LOCK TABLES + REPAIR + merge table result in
              memory/cpu hogging
  
    Trying DML on a MERGE table, which has a child locked and
    repaired by another thread, made an infinite loop in the server.
  
  Bug 26377 - Deadlock with MERGE and FLUSH TABLE
  
    Locking a MERGE table and its children in parent-child order
    and flushing the child deadlocked the server.
  
  Bug 25038 - Waiting TRUNCATE
  
    Truncating a MERGE child, while the MERGE table was in use,
    let the truncate fail instead of waiting for the table to
    become free.
  
  Bug 25700 - merge base tables get corrupted by
              optimize/analyze/repair table
  
    Repairing a child of an open MERGE table corrupted the child.
    It was necessary to FLUSH the child first.
  
  Bug 30275 - Merge tables: flush tables or unlock tables
              causes server to crash
  
    Flushing and optimizing locked MERGE children crashed the server.
  
  Bug 19627 - temporary merge table locking
  
    Use of a temporary MERGE table with non-temporary children
    could corrupt the children.
  
    Temporary tables are never locked. So we do now prohibit
    non-temporary chidlren of a temporary MERGE table.
  
  Bug 27660 - Falcon: merge table possible
  
    It was possible to create a MERGE table with non-MyISAM children.
  
  Bug 30273 - merge tables: Can't lock file (errno: 155)
  
    This was a Windows-only bug. Table administration statements
    sometimes failed with "Can't lock file (errno: 155)".
  
  These bugs are fixed by a new implementation of MERGE table open.
  
  When opening a MERGE table in open_tables() we do now add the
  child tables to the list of tables to be opened by open_tables()
  (the "query_list"). The children are not opened in the handler at
  this stage.
  
  After opening the parent, open_tables() opens each child from the
  now extended query_list. When the last child is opened, we remove
  the children from the query_list again and attach the children to
  the parent. This behaves similar to the old open. However it does
  not open the MyISAM tables directly, but grabs them from the already
  open children.
  
  When closing a MERGE table in close_thread_table() we detach the
  children only. Closing of the children is done implicitly because
  they are in thd->open_tables.
  
  For more detail see the comment at the top of ha_myisammrg.cc.
  
  Changed from open_ltable() to open_and_lock_tables() in all places
  that can be relevant for MERGE tables. The latter can handle tables
  added to the list on the fly. When open_ltable() was used in a loop
  over a list of tables, the list must be temporarily terminated
  after every table for open_and_lock_tables().
  table_list->required_type is set to FRMTYPE_TABLE to avoid open of
  special tables. Handling of derived tables is suppressed.
  These details are handled by the new function
  open_n_lock_single_table(), which has nearly the same signature as
  open_ltable() and can replace it in most cases.
  
  In reopen_tables() some of the tables open by a thread can be
  closed and reopened. When a MERGE child is affected, the parent
  must be closed and reopened too. Closing of the parent is forced
  before the first child is closed. Reopen happens in the order of
  thd->open_tables. MERGE parents do not attach their children
  automatically at open. This is done after all tables are reopened.
  So all children are open when attaching them.
  
  Special lock handling like mysql_lock_abort() or mysql_lock_remove()
  needs to be suppressed for MERGE children or forwarded to the parent.
  This depends on the situation. In loops over all open tables one
  suppresses child lock handling. When a single table is touched,
  forwarding is done.
  
  This patch changes the behavior of temporary MERGE tables.
  Temporary MERGE must have temporary children.
  The old behavior was wrong. A temporary table is not locked. Hence
  even non-temporary children were not locked. See
  Bug 19627 - temporary merge table locking.

  include/my_base.h@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +7 -1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added HA_EXTRA_ATTACH_CHILDREN and HA_EXTRA_DETACH_CHILDREN.

  include/myisammrg.h@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +9 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added element 'children_attached' to MYRG_INFO.
    Added declarations for myrg_parent_open(),
    myrg_attach_children() and myrg_detach_children()
    for the new MERGE table open approach.

  mysql-test/extra/binlog_tests/blackhole.test@stripped, 2007-11-02 17:28:15+01:00,
istruewing@stripped +9 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Preliminarily added new error message with a comment.

  mysql-test/r/merge-big.result@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped
+77 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    New test result

  mysql-test/r/merge-big.result@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +0
-0

  mysql-test/r/merge.result@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +931
-11
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added test results.

  mysql-test/r/myisam.result@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +0
-18
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Moved test result for bug 8306 from here to merge.result.

  mysql-test/suite/binlog/r/binlog_stm_blackhole.result@stripped, 2007-11-02 17:28:15+01:00,
istruewing@stripped +1 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Fixed test result.

  mysql-test/suite/rpl/r/rpl_merge.result@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +176 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    New test result

  mysql-test/suite/rpl/r/rpl_merge.result@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +0 -0

  mysql-test/suite/rpl/t/rpl_merge.test@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +84 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    New test case

  mysql-test/suite/rpl/t/rpl_merge.test@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +0 -0

  mysql-test/t/delayed.test@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +1 -1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Exchanged error number by symbolic code.

  mysql-test/t/merge-big.test@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +150
-0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    New test case

  mysql-test/t/merge-big.test@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +0
-0

  mysql-test/t/merge.test@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +723 -3
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Fixed test for new temporary MERGE table behavior.
    Exchanged error numbers by symbolic codes.
    Added tests. Included are tests for bugs
    8306 (moved from myisam.test), 26379, 19627, 25038, 25700, 26377,
    26867, 27660, 30275, and 30273.

  mysql-test/t/myisam.test@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +0 -26
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Moved test for bug 8306 from here to merge.test.

  mysys/thr_lock.c@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +23 -10
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added code to let the owner of a high priority lock (TL_WRITE_ONLY)
    to bypass its own lock.

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +1
-1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added 'thd' argument to init_tmp_table_share().

  sql/handler.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +6 -5
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added 'thd' argument to init_tmp_table_share().

  sql/mysql_priv.h@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +20 -4
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Removed declaration of check_merge_table_access(). It is now static
    in sql_parse.cc.
    Added declaration for fix_merge_after_open().
    Renamed open_and_lock_tables() to open_and_lock_tables_derived()
    with additional parameter 'derived'.
    Added inline functions simple_open_n_lock_tables() and
    open_and_lock_tables(), which call open_and_lock_tables_derived()
    and add the argument for 'derived'.
    Added new function open_n_lock_single_table(), which can be used
    as an replacement for open_ltable() in most situations. Internally
    it calls simple_open_n_lock_tables() so hat it is appropriate for
    MERGE tables.
    Added 'thd' argument to init_tmp_table_share().

  sql/slave.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +2 -2
    ug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added initialization for TABLE_LIST::table.
    Changed from open_ltable() to open_n_lock_single_table().

  sql/sql_base.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +908 -89
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    
    Defined new functions add_merge_table_list(),
    attach_merge_children(), detach_merge_children(), and
    fix_merge_after_open() for the new MERGE table open approach.
    
    Added calls of the new functions to
    close_handle_and_leave_table_as_lock(), close_thread_tables(),
    close_thread_table(), unlink_open_table(), reopen_name_locked_table(),
    reopen_table(), drop_locked_tables(), close_temporary_table(),
    and open_tables() respectively.
    
    Prevented special lock handling of merge children (like
    mysql_lock_remove, mysql_lock_merge or mysql_lock_abort)
    at many places. Some of these calls are forwarded to the
    parent table instead.
    
    Added code to set thd->some_tables_deleted for every thread that has
    a table open that we are flushing.
    Added code for MERGE tables to unlink_open_table().
    Added MERGE children to the list of unusable tables in open_table().
    Added MERGE table handling to reopen_table().
    Added lock handling and closing of a parent before the children
    in close_data_files_and_morph_locks().
    Added code for re-attaching children in reopen_tables().
    Added MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN to the locking flags and
    error reporting after mysql_lock_tables() in reopen_tables().
    Added lock handling and closing of a parent before the children
    in close_old_data_files().
    Added lock handling and detaching in drop_locked_tables().
    Added code for removing the children list from the statement list
    to prepare for a repetition in open_tables().
    Added new function open_n_lock_single_table(), which can be used
    as an replacement for open_ltable() in most situations. Internally
    it calls simple_open_n_lock_tables() so hat it is appropriate for
    MERGE tables.
    Disabled use of open_ltable() for MERGE tables.
    Removed function simple_open_n_lock_tables(). It is now inline
    declared in mysql_priv.h.
    Renamed open_and_lock_tables() to open_and_lock_tables_derived()
    with additional parameter 'derived'. open_and_lock_tables() is now
    inline declared in mysql_priv.h.
    Added a check for end-of-list in two loops in lock_tables().
    Added 'thd' argument to init_tmp_table_share().

  sql/sql_insert.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +94 -3
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Changed from open_ltable() to open_n_lock_single_table() in
    handle_delayed_insert().
    Added 'thd' argument to init_tmp_table_share().
    Added MERGE handling to create_table_from_items().

  sql/sql_parse.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +58 -39
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Renamed check_merge_table_access() to
    check_merge_table_access_fix_locks(), made it a static function,
    and added setting ot TL_WRITE for the children.
    Changed from open_ltable() to open_n_lock_single_table() in
    mysql_table_dump().
    Removed condition for calling close_thread_tables() from
    dispatch_command() (in COM_QUERY after every mysql_parse() and
    after the big switch).

  sql/sql_partition.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +1 -1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Fixed comment typo.

  sql/sql_select.cc@stripped, 2007-11-02 17:28:15+01:00, istruewing@stripped +1 -1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added 'thd' argument to init_tmp_table_share().

  sql/sql_table.cc@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +76 -5
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Optimized use of mysql_ha_flush() in mysql_rm_table_part2().
    Disabled the use of MERGE tables with prepare_for_restore() and
    prepare_for_repair().
    Changed from open_ltable() to open_n_lock_single_table() in
    mysql_alter_table() and mysql_checksum_table().
    Initialized table_list->table in mysql_recreate_table().

  sql/sql_trigger.cc@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +39 -5
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added code for allowing CREATE TRIGGER under LOCK TABLE, to be able
    to test it with MERGE tables.

  sql/table.cc@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +8 -2
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added 'thd' argument to init_tmp_table_share().
    Setting table_map_id from query_id in init_tmp_table_share().

  sql/table.h@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +32 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added access method get_table_def_version() to TABLE_SHARE.
    Added elements for MERGE tables to TABLE and TABLE_LIST.

  storage/myisam/ha_myisam.cc@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped
+27 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added new function myisam_engine_handle() to extract a MI_INFO
    pointer from a handler object.
    Added an unrelated comment to the function comment of table2myisam().

  storage/myisam/ha_myisam.h@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped +4
-0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Declared new function myisam_engine_handle() as friend of
    class ha_myisam.

  storage/myisammrg/ha_myisammrg.cc@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +570 -90
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added callback functions to support parent open and children attach
    of MERGE tables.
    Changed ha_myisammrg::open() to initialize storage engine structures
    and create a list of child tables only. Child tables are not opened.
    Added ha_myisammrg::attach_children(), which does now the main part
    of MERGE open.
    Added ha_myisammrg::detach_children().
    Added calls to ::attach_children() and ::detach_children() to
    ::extra() on HA_EXTRA_ATTACH_CHILDREN and HA_EXTRA_DETACH_CHILDREN
    respectively.
    Added a check for matching TEMPORARY type for children against
    parent.
    Added a check for table def version.
    Added support for thd->open_options to attach_children().
    Changed child path name generation for temporary tables so that
    it does nothing special for temporary tables.

  storage/myisammrg/ha_myisammrg.h@stripped, 2007-11-02 17:28:16+01:00,
istruewing@stripped +8 -1
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added elements to class ha_myisammrg to support the new
    open approach.
    Changed empty destructor definition to a declaration.
    Implemented in ha_myisammrg.cc.
    Added declaration for methods attach_children() and
    detach_children().
    Added definition for method table_ptr() for use with
    callback functions.

  storage/myisammrg/myrg_close.c@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped
+31 -3
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Added a check to avoid closing of MyISAM tables when the
    child tables are not attached.
    Added freeing of rec_per_key_part when the child tables
    are not attached.

  storage/myisammrg/myrg_extra.c@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped
+4 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    Some ::extra() functions and ::reset() can be called when
    children are detached.

  storage/myisammrg/myrg_open.c@stripped, 2007-11-02 17:28:16+01:00, istruewing@stripped
+326 -8
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
                corrupts a MERGE table
    
    Kept old myrg_open() for MERGE use independent from MySQL.
    Removed an always true condition in myrg_open().
    Set children_attached for independent MERGE use in myrg_open().
    
    Added myrg_parent_open(), myrg_attach_children(), and
    myrg_detach_children() for the new MERGE table open approach.

diff -Nrup a/include/my_base.h b/include/my_base.h
--- a/include/my_base.h	2007-07-25 00:58:05 +02:00
+++ b/include/my_base.h	2007-11-02 17:28:15 +01:00
@@ -187,7 +187,13 @@ enum ha_extra_function {
     Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be
     executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY.
   */
-  HA_EXTRA_INSERT_WITH_UPDATE
+  HA_EXTRA_INSERT_WITH_UPDATE,
+  /*
+    Orders MERGE handler to attach or detach its child tables. Used at
+    begin and end of a statement.
+  */
+  HA_EXTRA_ATTACH_CHILDREN,
+  HA_EXTRA_DETACH_CHILDREN
 };
 
 	/* The following is parameter to ha_panic() */
diff -Nrup a/include/myisammrg.h b/include/myisammrg.h
--- a/include/myisammrg.h	2007-05-10 11:59:24 +02:00
+++ b/include/myisammrg.h	2007-11-02 17:28:15 +01:00
@@ -69,6 +69,8 @@ typedef struct st_myrg_info
   uint	 merge_insert_method;
   uint	 tables,options,reclength,keys;
   my_bool cache_in_use;
+  /* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
+  my_bool children_attached;
   LIST	 open_list;
   QUEUE  by_key;
   ulong *rec_per_key_part;			/* for sql optimizing */
@@ -80,6 +82,13 @@ typedef struct st_myrg_info
 extern int myrg_close(MYRG_INFO *file);
 extern int myrg_delete(MYRG_INFO *file,const uchar *buff);
 extern MYRG_INFO *myrg_open(const char *name,int mode,int wait_if_locked);
+extern MYRG_INFO *myrg_parent_open(const char *parent_name,
+                                   int (*callback)(void*, const char*),
+                                   void *callback_param);
+extern int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
+                                MI_INFO *(*callback)(void*),
+                                void *callback_param);
+extern int myrg_detach_children(MYRG_INFO *m_info);
 extern int myrg_panic(enum ha_panic_function function);
 extern int myrg_rfirst(MYRG_INFO *file,uchar *buf,int inx);
 extern int myrg_rlast(MYRG_INFO *file,uchar *buf,int inx);
diff -Nrup a/mysql-test/extra/binlog_tests/blackhole.test
b/mysql-test/extra/binlog_tests/blackhole.test
--- a/mysql-test/extra/binlog_tests/blackhole.test	2007-06-15 18:35:09 +02:00
+++ b/mysql-test/extra/binlog_tests/blackhole.test	2007-11-02 17:28:15 +01:00
@@ -134,6 +134,15 @@ drop table t1,t2,t3;
 #             table
 #
 CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
+# NOTE: After exchanging open_ltable() by open_and_lock_tables() in
+# handle_delayed_insert() to fix problems with MERGE tables (Bug#26379),
+# problems with INSERT DELAYED and BLACKHOLE popped up. open_ltable()
+# does not check if the binlogging capabilities of the statement and the
+# table match. So the below used to succeed. But since INSERT DELAYED
+# switches to row-based logging in mixed-mode and BLACKHOLE cannot do
+# row-based logging, it could not really work. Until this problem is
+# correctly fixed, we have that error here.
+--error ER_BINLOG_LOGGING_IMPOSSIBLE
 INSERT DELAYED INTO t1 VALUES(1);
 DROP TABLE t1;
 
diff -Nrup a/mysql-test/r/merge-big.result b/mysql-test/r/merge-big.result
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/merge-big.result	2007-11-02 17:28:16 +01:00
@@ -0,0 +1,77 @@
+drop table if exists t1,t2,t3,t4,t5,t6;
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
+#             corrupts a MERGE table
+# Problem #3
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+# connection con1
+SET SESSION debug="+d,sleep_open_and_lock_after_open";
+INSERT INTO t1 VALUES (1);
+# connection default
+# Let INSERT go into thr_multi_lock().
+# Kick INSERT out of thr_multi_lock().
+FLUSH TABLES;
+# Let INSERT go through open_tables() where it sleeps.
+# Unlock and close table and wait for con1 to close too.
+FLUSH TABLES;
+# This should give no result.
+SELECT * FROM t1;
+c1
+UNLOCK TABLES;
+# connection con1
+SET SESSION debug="-d,sleep_open_and_lock_after_open";
+# connection default
+DROP TABLE t1;
+#
+# Extra tests for Bug#26379 - Combination of FLUSH TABLE and
+#                             REPAIR TABLE corrupts a MERGE table
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+#
+# CREATE ... SELECT
+# try to access parent from another thread.
+#
+# connection con1
+SET SESSION debug="+d,sleep_create_select_before_lock";
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=FIRST SELECT * FROM t3;
+# connection default
+# Now try to access the parent.
+# If 3 is in table, SELECT had to wait.
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+# connection con1
+SET SESSION debug="-d,sleep_create_select_before_lock";
+# connection default
+# Cleanup for next test.
+DROP TABLE t4;
+DELETE FROM t1 WHERE c1 != 1;
+#
+# CREATE ... SELECT
+# try to access child from another thread.
+#
+# connection con1
+SET SESSION debug="+d,sleep_create_select_before_lock";
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=FIRST SELECT * FROM t3;
+# connection default
+# Now try to access a child.
+# If 3 is in table, SELECT had to wait.
+SELECT * FROM t1 ORDER BY c1;
+c1
+1
+3
+# connection con1
+SET SESSION debug="-d,sleep_create_select_before_lock";
+# connection default
+DROP TABLE t1, t2, t3, t4;
diff -Nrup a/mysql-test/r/merge.result b/mysql-test/r/merge.result
--- a/mysql-test/r/merge.result	2007-10-09 14:18:07 +02:00
+++ b/mysql-test/r/merge.result	2007-11-02 17:28:15 +01:00
@@ -584,9 +584,7 @@ insert into t1 values (1);
 insert into t2 values (2);
 create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
 select * from t3;
-a
-1
-2
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
 create temporary table t4 (a int not null);
 create temporary table t5 (a int not null);
 insert into t4 values (1);
@@ -597,6 +595,51 @@ a
 1
 2
 drop table t6, t3, t1, t2, t4, t5;
+create temporary table t1 (a int not null);
+create temporary table t2 (a int not null);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+select * from t3;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+drop table t3, t2, t1;
+create table t1 (a int not null);
+create temporary table t2 (a int not null);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+select * from t3;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+drop table t3;
+create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+select * from t3;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+drop table t3, t2, t1;
+CREATE TEMPORARY TABLE t1 (c1 INT NOT NULL);
+CREATE TEMPORARY TABLE t2 (c1 INT NOT NULL);
+CREATE TABLE t3 (c1 INT NOT NULL);
+INSERT INTO t3 VALUES (3), (33);
+LOCK TABLES t3 READ;
+CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL) ENGINE=MERGE UNION=(t1,t2)
+INSERT_METHOD=LAST SELECT * FROM t3;
+SELECT * FROM t4;
+c1
+3
+33
+UNLOCK TABLES;
+# Alter temporary MERGE table.
+ALTER TABLE t4 UNION=(t1);
+LOCK TABLES t4 WRITE;
+# Alter temporary MERGE table under LOCk tables.
+ALTER TABLE t4 UNION=(t1,t2);
+UNLOCK TABLES;
+# MERGE table and function.
+CREATE FUNCTION f1 () RETURNS INT RETURN (SELECT max(c1) FROM t3);
+SELECT * FROM t4 WHERE c1 < f1();
+c1
+3
+DROP FUNCTION f1;
+DROP TABLE t4, t3, t2, t1;
 CREATE TABLE t1 (
 fileset_id tinyint(3) unsigned NOT NULL default '0',
 file_code varchar(32) NOT NULL default '',
@@ -784,7 +827,7 @@ ERROR HY000: Unable to open underlying t
 DROP TABLE t1, t2;
 CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
 SELECT * FROM t2;
-ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+ERROR 42S02: Table 'test.t3' doesn't exist
 DROP TABLE t2;
 CREATE TABLE t1(a INT, b TEXT);
 CREATE TABLE tm1(a TEXT, b INT) ENGINE=MERGE UNION=(t1);
@@ -849,20 +892,17 @@ drop table t2;
 drop table t1;
 CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
 SELECT * FROM tm1;
-ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+ERROR 42S02: Table 'test.t1' doesn't exist
 CHECK TABLE tm1;
 Table	Op	Msg_type	Msg_text
-test.tm1	check	Error	Table 'test.t1' is differently defined or of non-MyISAM type or
doesn't exist
-test.tm1	check	Error	Table 'test.t2' is differently defined or of non-MyISAM type or
doesn't exist
-test.tm1	check	Error	Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+test.tm1	check	Error	Table 'test.t1' doesn't exist
 test.tm1	check	error	Corrupt
 CREATE TABLE t1(a INT);
 SELECT * FROM tm1;
-ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+ERROR 42S02: Table 'test.t2' doesn't exist
 CHECK TABLE tm1;
 Table	Op	Msg_type	Msg_text
-test.tm1	check	Error	Table 'test.t2' is differently defined or of non-MyISAM type or
doesn't exist
-test.tm1	check	Error	Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+test.tm1	check	Error	Table 'test.t2' doesn't exist
 test.tm1	check	error	Corrupt
 CREATE TABLE t2(a BLOB);
 SELECT * FROM tm1;
@@ -885,3 +925,883 @@ CREATE TABLE IF NOT EXISTS t1 SELECT * F
 ERROR HY000: You can't specify target table 't1' for update in FROM clause
 DROP TABLE t1, t2;
 End of 5.0 tests
+create table t1 (c1 int, index(c1));
+create table t2 (c1 int, index(c1)) engine=merge union=(t1);
+insert into t1 values (1);
+flush tables;
+select * from t2;
+c1
+1
+flush tables;
+truncate table t1;
+insert into t1 values (1);
+flush tables;
+select * from t2;
+c1
+1
+truncate table t1;
+insert into t1 values (1);
+drop table t1,t2;
+#
+# Extra tests for TRUNCATE.
+#
+# Truncate MERGE table.
+CREATE TABLE t1 (c1 INT, INDEX(c1));
+CREATE TABLE t2 (c1 INT, INDEX(c1));
+CREATE TABLE t3 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1,t2);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t3;
+c1
+1
+2
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+c1
+#
+# Truncate child table.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+c1
+2
+#
+# Truncate MERGE table under locked tables.
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+TRUNCATE TABLE t3;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3;
+c1
+1
+2
+#
+# Truncate child table under locked tables.
+TRUNCATE TABLE t1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3;
+c1
+1
+2
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3;
+#
+# Truncate temporary MERGE table.
+CREATE TEMPORARY TABLE t1 (c1 INT, INDEX(c1));
+CREATE TEMPORARY TABLE t2 (c1 INT, INDEX(c1));
+CREATE TEMPORARY TABLE t3 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1,t2);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t3;
+c1
+1
+2
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+c1
+#
+# Truncate temporary child table.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+c1
+2
+#
+# Truncate temporary MERGE table under locked tables.
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t4 (c1 INT, INDEX(c1));
+LOCK TABLE t4 WRITE;
+TRUNCATE TABLE t3;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3;
+c1
+1
+2
+#
+# Truncate temporary child table under locked tables.
+TRUNCATE TABLE t1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3;
+c1
+1
+2
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3, t4;
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
+REPAIR TABLE t1;
+INSERT INTO t2 VALUES (1);
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+DROP TABLE t1, t2;
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
+LOCK TABLE t1 WRITE;
+INSERT INTO t2 VALUES (1);
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (1);
+FLUSH TABLES;
+FLUSH TABLES;
+SELECT * FROM t1;
+c1
+UNLOCK TABLES;
+DROP TABLE t1;
+#
+# Extra tests for Bug#26379 - Combination of FLUSH TABLE and
+#                             REPAIR TABLE corrupts a MERGE table
+#
+# CREATE ... SELECT
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+# Show that LAST table is opened.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=LAST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+DROP TABLE t4;
+# Show that FIRST table is opened.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=FIRST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`)
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+3
+DROP TABLE t4;
+# Show that CREATE..SELECT is not possible under LOCK TABLES
+# for non-temporary tables.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 READ;
+# Normal CREATE works.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+DROP TABLE t4;
+# CREATE...SELECT is rejected.
+CREATE TABLE t4 (c1 INT) SELECT * FROM t3;
+ERROR HY000: Table 't4' was not locked with LOCK TABLES
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=LAST SELECT * FROM t3;
+ERROR HY000: Table 't4' was not locked with LOCK TABLES
+UNLOCK TABLES;
+# LOCK on parent table does not include children.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+LOCK TABLES t4 READ;
+SELECT * from t1, t4 ORDER BY c1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+# Show that dropping a locked MERGE table works.
+DROP TABLE t4;
+UNLOCK TABLES;
+DROP TABLE t3;
+#
+# CREATE ... LIKE
+#
+# 1. Create like.
+CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+INSERT INTO t3 VALUES (3);
+CREATE TABLE t4 LIKE t3;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
+INSERT INTO t4 VALUES (4);
+ERROR HY000: Table 't4' is read only
+DROP TABLE t4;
+#
+# 1. Create like with locked tables.
+LOCK TABLES t3 WRITE, t2 WRITE, t1 WRITE;
+CREATE TABLE t4 LIKE t3;
+SHOW CREATE TABLE t4;
+ERROR HY000: Table 't4' was not locked with LOCK TABLES
+INSERT INTO t4 VALUES (4);
+ERROR HY000: Table 't4' was not locked with LOCK TABLES
+UNLOCK TABLES;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
+INSERT INTO t4 VALUES (4);
+ERROR HY000: Table 't4' is read only
+DROP TABLE t4;
+#
+# Rename child.
+#
+# 1. Normal rename of non-MERGE table.
+CREATE TABLE t4 (c1 INT);
+INSERT INTO t4 VALUES (4);
+SELECT * FROM t4 ORDER BY c1;
+c1
+4
+RENAME TABLE t4 TO t5;
+SELECT * FROM t5 ORDER BY c1;
+c1
+4
+RENAME TABLE t5 TO t4;
+SELECT * FROM t4 ORDER BY c1;
+c1
+4
+DROP TABLE t4;
+#
+# 2. Normal rename.
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+RENAME TABLE t2 TO t5;
+SELECT * FROM t3 ORDER BY c1;
+ERROR 42S02: Table 'test.t2' doesn't exist
+RENAME TABLE t5 TO t2;
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+#
+# 3. Normal rename with locked tables.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+RENAME TABLE t2 TO t5;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+RENAME TABLE t5 TO t2;
+ERROR HY000: Can't execute the given command because you have active locked tables or an
active transaction
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+UNLOCK TABLES;
+#
+# 4. Alter table rename.
+ALTER TABLE t2 RENAME TO t5;
+SELECT * FROM t3 ORDER BY c1;
+ERROR 42S02: Table 'test.t2' doesn't exist
+ALTER TABLE t5 RENAME TO t2;
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+#
+# 5. Alter table rename with locked tables.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
+ALTER TABLE t2 RENAME TO t5;
+SELECT * FROM t3 ORDER BY c1;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+ALTER TABLE t5 RENAME TO t2;
+ERROR HY000: Table 't5' was not locked with LOCK TABLES
+UNLOCK TABLES;
+ALTER TABLE t5 RENAME TO t2;
+SELECT * FROM t3 ORDER BY c1;
+c1
+1
+2
+3
+3
+3
+DROP TABLE t1, t2, t3;
+#
+# Drop locked tables.
+#
+# 1. Drop parent.
+CREATE TABLE t1 (c1 INT, INDEX(c1));
+CREATE TABLE t2 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+LOCK TABLES t1 WRITE, t2 WRITE;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t2;
+SELECT * FROM t2;
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+SELECT * FROM t1;
+c1
+1
+UNLOCK TABLES;
+# 2. Drop child.
+CREATE TABLE t2 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+LOCK TABLES t1 WRITE, t2 WRITE;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t1;
+SELECT * FROM t2;
+ERROR 42S02: Table 'test.t1' doesn't exist
+SELECT * FROM t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+UNLOCK TABLES;
+DROP TABLE t2;
+#
+# ALTER TABLE under LOCK TABLES. Grave change, table re-creation.
+#
+CREATE TABLE t1 (c1 INT, INDEX(c1));
+CREATE TABLE t2 (c1 INT, INDEX(c1));
+CREATE TABLE t3 (c1 INT, INDEX(c1));
+CREATE TABLE t4 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1,t2,t3)
+INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+# Lock parent first and then children.
+LOCK TABLES t4 WRITE, t3 WRITE, t2 WRITE, t1 WRITE;
+ALTER TABLE t4 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock children first and then parent.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE;
+ALTER TABLE t4 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock parent between children.
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+ALTER TABLE t4 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 DROP INDEX c1, ADD UNIQUE INDEX (c1);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3, t4;
+#
+# ALTER TABLE under LOCK TABLES. Simple change, no re-creation.
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3)
+INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+# Lock parent first and then children.
+LOCK TABLES t4 WRITE, t3 WRITE, t2 WRITE, t1 WRITE;
+ALTER TABLE t4 ALTER COLUMN c1 SET DEFAULT 44;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 ALTER COLUMN c1 SET DEFAULT 22;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock children first and then parent.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE;
+ALTER TABLE t4 ALTER COLUMN c1 SET DEFAULT 44;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 ALTER COLUMN c1 SET DEFAULT 22;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock parent between children.
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+ALTER TABLE t4 ALTER COLUMN c1 SET DEFAULT 44;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+ALTER TABLE t2 ALTER COLUMN c1 SET DEFAULT 22;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+#
+# FLUSH TABLE under LOCK TABLES.
+#
+# Lock parent first and then children.
+LOCK TABLES t4 WRITE, t3 WRITE, t2 WRITE, t1 WRITE;
+FLUSH TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLE t2;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLES;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock children first and then parent.
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE;
+FLUSH TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLE t2;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLES;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+# Lock parent between children.
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+FLUSH TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLE t2;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+FLUSH TABLES;
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+UNLOCK TABLES;
+#
+# Triggers
+#
+CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1;
+SET @a=0;
+INSERT INTO t4 VALUES (4);
+SELECT @a;
+@a
+1
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+DROP TRIGGER t4_ai;
+# Create trigger with LOCK
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1;
+SET @a=0;
+INSERT INTO t4 VALUES (4);
+SELECT @a;
+@a
+1
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+DROP TRIGGER t4_ai;
+UNLOCK TABLES;
+#
+# Repair
+#
+REPAIR TABLE t4;
+Table	Op	Msg_type	Msg_text
+test.t4	repair	note	The storage engine for the table doesn't support repair
+REPAIR TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	repair	status	OK
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+REPAIR TABLE t4;
+Table	Op	Msg_type	Msg_text
+test.t4	repair	note	The storage engine for the table doesn't support repair
+REPAIR TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	repair	status	OK
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+UNLOCK TABLES;
+#
+# Optimize
+#
+OPTIMIZE TABLE t4;
+Table	Op	Msg_type	Msg_text
+test.t4	optimize	note	The storage engine for the table doesn't support optimize
+OPTIMIZE TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	optimize	status	OK
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+OPTIMIZE TABLE t4;
+Table	Op	Msg_type	Msg_text
+test.t4	optimize	note	The storage engine for the table doesn't support optimize
+OPTIMIZE TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	optimize	status	Table is already up to date
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+UNLOCK TABLES;
+#
+# Checksum
+#
+CHECKSUM TABLE t4;
+Table	Checksum
+test.t4	46622073
+CHECKSUM TABLE t2;
+Table	Checksum
+test.t2	3700403066
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+CHECKSUM TABLE t4;
+Table	Checksum
+test.t4	46622073
+CHECKSUM TABLE t2;
+Table	Checksum
+test.t2	3700403066
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+UNLOCK TABLES;
+#
+# Insert delayed
+#
+INSERT DELAYED INTO t4 VALUES(44);
+ERROR HY000: Table storage engine for 't4' doesn't have this option
+INSERT DELAYED INTO t3 VALUES(33);
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+33
+LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE;
+INSERT DELAYED INTO t4 VALUES(444);
+Got one of the listed errors
+INSERT DELAYED INTO t3 VALUES(333);
+Got one of the listed errors
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+4
+4
+33
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3, t4;
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t3;
+c1
+1
+2
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+c1
+2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (id INTEGER, grp TINYINT, id_rev INTEGER);
+SET @rnd_max= 2147483647;
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+SET @rnd= RAND();
+SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
+SET @id_rev= @rnd_max - @id;
+SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
+INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
+set @@read_buffer_size=2*1024*1024;
+CREATE TABLE t2 SELECT * FROM t1;
+INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
+INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
+INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
+INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
+INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
+CREATE TABLE t3 (id INTEGER, grp TINYINT, id_rev INTEGER)
+ENGINE= MRG_MYISAM UNION= (t1, t2);
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+130
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+80
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+210
+SELECT COUNT(DISTINCT a1.id) FROM t3 AS a1, t3 AS a2
+WHERE a1.id = a2.id GROUP BY a2.grp;
+TRUNCATE TABLE t1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+0
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+80
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+80
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t2;
+c1
+1
+LOCK TABLES t2 WRITE, t1 WRITE;
+FLUSH TABLES;
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+UNLOCK TABLES;
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+LOCK TABLES t2 WRITE, t1 WRITE;
+SELECT * FROM t2;
+c1
+1
+LOCK TABLES t2 WRITE, t1 WRITE;
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+UNLOCK TABLES;
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+DROP TABLE t1, t2;
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+CREATE TABLE m1 ( a INT ) ENGINE=MRG_MYISAM UNION=(t1);
+LOCK TABLES t1 WRITE, m1 WRITE;
+FLUSH TABLE t1;
+UNLOCK TABLES;
+DROP TABLE m1, t1;
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+CREATE TABLE m1 ( a INT ) ENGINE=MRG_MYISAM UNION=(t1);
+LOCK TABLES m1 WRITE, t1 WRITE;
+FLUSH TABLE t1;
+UNLOCK TABLES;
+DROP TABLE m1, t1;
+CREATE TABLE t1 (c1 INT, c2 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT, c2 INT) ENGINE= MyISAM;
+CREATE TABLE t3 (c1 INT, c2 INT) ENGINE= MRG_MYISAM UNION(t1, t2);
+INSERT INTO t1 VALUES (1, 1);
+INSERT INTO t2 VALUES (2, 2);
+SELECT * FROM t3;
+c1	c2
+1	1
+2	2
+ALTER TABLE t1 ENGINE= MEMORY;
+INSERT INTO t1 VALUES (0, 0);
+SELECT * FROM t3;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (c1 INT, KEY(c1));
+CREATE TABLE t2 (c1 INT, KEY(c1)) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=FIRST;
+LOCK TABLE t1 WRITE, t2 WRITE;
+FLUSH TABLES t2, t1;
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	Table is already up to date
+FLUSH TABLES t1;
+UNLOCK TABLES;
+FLUSH TABLES;
+INSERT INTO t1 VALUES (1);
+LOCK TABLE t1 WRITE, t2 WRITE;
+FLUSH TABLES t2, t1;
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+FLUSH TABLES t1;
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+CREATE TABLE t1 (ID INT) ENGINE=MYISAM;
+CREATE TABLE m1 (ID INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=FIRST;
+INSERT INTO t1 VALUES ();
+INSERT INTO m1 VALUES ();
+LOCK TABLE t1 WRITE, m1 WRITE;
+FLUSH TABLES m1, t1;
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+FLUSH TABLES m1, t1;
+UNLOCK TABLES;
+DROP TABLE t1, m1;
diff -Nrup a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
--- a/mysql-test/r/myisam.result	2007-05-29 14:57:33 +02:00
+++ b/mysql-test/r/myisam.result	2007-11-02 17:28:15 +01:00
@@ -606,24 +606,6 @@ select count(*) from t1 where a is null;
 count(*)
 2
 drop table t1;
-create table t1 (c1 int, index(c1));
-create table t2 (c1 int, index(c1)) engine=merge union=(t1);
-insert into t1 values (1);
-flush tables;
-select * from t2;
-c1
-1
-flush tables;
-truncate table t1;
-insert into t1 values (1);
-flush tables;
-select * from t2;
-c1
-1
-truncate table t1;
-ERROR HY000: MyISAM table 't1' is in use (most likely by a MERGE table). Try FLUSH
TABLES.
-insert into t1 values (1);
-drop table t1,t2;
 create table t1 (c1 int, c2 varchar(4) not null default '',
 key(c2(3))) default charset=utf8;
 insert into t1 values (1,'A'), (2, 'B'), (3, 'A');
diff -Nrup a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
--- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result	2007-06-27 14:27:27 +02:00
+++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result	2007-11-02 17:28:15 +01:00
@@ -124,6 +124,7 @@ master-bin.000001	#	Query	#	#	use `test`
 drop table t1,t2,t3;
 CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
 INSERT DELAYED INTO t1 VALUES(1);
+ERROR HY000: Binary logging not possible. Message: Row-based format required for this
statement, but not allowed by this combination of engines
 DROP TABLE t1;
 CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
 DELETE FROM t1 WHERE a=10;
diff -Nrup a/mysql-test/suite/rpl/r/rpl_merge.result
b/mysql-test/suite/rpl/r/rpl_merge.result
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/suite/rpl/r/rpl_merge.result	2007-11-02 17:28:16 +01:00
@@ -0,0 +1,176 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+# connection master
+#
+# CREATE ... SELECT
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=LAST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+# connection slave
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+2
+3
+# connection master
+DROP TABLE t1, t2, t3, t4;
+# connection slave
+show slave status;;
+Slave_IO_State	#
+Master_Host	127.0.0.1
+Master_User	root
+Master_Port	MASTER_PORT
+Connect_Retry	1
+Master_Log_File	master-bin.000001
+Read_Master_Log_Pos	#
+Relay_Log_File	#
+Relay_Log_Pos	#
+Relay_Master_Log_File	master-bin.000001
+Slave_IO_Running	Yes
+Slave_SQL_Running	Yes
+Replicate_Do_DB	
+Replicate_Ignore_DB	
+Replicate_Do_Table	
+Replicate_Ignore_Table	
+Replicate_Wild_Do_Table	
+Replicate_Wild_Ignore_Table	
+Last_Errno	0
+Last_Error	
+Skip_Counter	0
+Exec_Master_Log_Pos	#
+Relay_Log_Space	#
+Until_Condition	None
+Until_Log_File	
+Until_Log_Pos	0
+Master_SSL_Allowed	No
+Master_SSL_CA_File	
+Master_SSL_CA_Path	
+Master_SSL_Cert	
+Master_SSL_Cipher	
+Master_SSL_Key	
+Seconds_Behind_Master	#
+Master_SSL_Verify_Server_Cert	No
+Last_IO_Errno	0
+Last_IO_Error	
+Last_SQL_Errno	0
+Last_SQL_Error	
+# connection master
+#
+# CREATE ... SELECT from temporary table
+#
+CREATE TEMPORARY TABLE t1 (c1 INT);
+CREATE           TABLE t2 (c1 INT);
+CREATE TEMPORARY TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+CREATE TEMPORARY TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST SELECT * FROM t3;
+INSERT INTO t4 VALUES (4);
+CREATE TABLE t5 (c1 INT) ENGINE=MRG_MYISAM UNION=(t2)
+INSERT_METHOD=LAST SELECT * FROM t4;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TEMPORARY TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST
UNION=(`tmp`.`#sql-temporary`)
+SHOW CREATE TABLE t5;
+Table	Create Table
+t5	CREATE TABLE `t5` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t2`)
+SELECT * FROM t4 ORDER BY c1;
+c1
+1
+3
+4
+SELECT * FROM t5 ORDER BY c1;
+c1
+1
+2
+3
+4
+# connection slave
+SHOW CREATE TABLE t4;
+ERROR 42S02: Table 'test.t4' doesn't exist
+SHOW CREATE TABLE t5;
+Table	Create Table
+t5	CREATE TABLE `t5` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t2`)
+SELECT * FROM t4 ORDER BY c1;
+ERROR 42S02: Table 'test.t4' doesn't exist
+SELECT * FROM t5 ORDER BY c1;
+c1
+1
+2
+3
+4
+# connection master
+DROP TABLE t1, t2, t3, t4, t5;
+# connection slave
+show slave status;;
+Slave_IO_State	#
+Master_Host	127.0.0.1
+Master_User	root
+Master_Port	MASTER_PORT
+Connect_Retry	1
+Master_Log_File	master-bin.000001
+Read_Master_Log_Pos	#
+Relay_Log_File	#
+Relay_Log_Pos	#
+Relay_Master_Log_File	master-bin.000001
+Slave_IO_Running	Yes
+Slave_SQL_Running	Yes
+Replicate_Do_DB	
+Replicate_Ignore_DB	
+Replicate_Do_Table	
+Replicate_Ignore_Table	
+Replicate_Wild_Do_Table	
+Replicate_Wild_Ignore_Table	
+Last_Errno	0
+Last_Error	
+Skip_Counter	0
+Exec_Master_Log_Pos	#
+Relay_Log_Space	#
+Until_Condition	None
+Until_Log_File	
+Until_Log_Pos	0
+Master_SSL_Allowed	No
+Master_SSL_CA_File	
+Master_SSL_CA_Path	
+Master_SSL_Cert	
+Master_SSL_Cipher	
+Master_SSL_Key	
+Seconds_Behind_Master	#
+Master_SSL_Verify_Server_Cert	No
+Last_IO_Errno	0
+Last_IO_Error	
+Last_SQL_Errno	0
+Last_SQL_Error	
+# connection master
diff -Nrup a/mysql-test/suite/rpl/t/rpl_merge.test b/mysql-test/suite/rpl/t/rpl_merge.test
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/suite/rpl/t/rpl_merge.test	2007-11-02 17:28:16 +01:00
@@ -0,0 +1,84 @@
+# t/rpl_merge.test
+#
+# Replication of MERGE tables
+
+# This is a replication test.
+--source include/master-slave.inc
+
+## --source include/have_myisam.inc
+## --source include/have_merge.inc
+
+--echo # connection master
+connection master;
+
+--echo #
+--echo # CREATE ... SELECT
+--echo #
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+  INSERT_METHOD=LAST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+sync_slave_with_master;
+    --echo # connection slave
+    connection slave;
+    SHOW CREATE TABLE t4;
+    SELECT * FROM t4 ORDER BY c1;
+--echo # connection master
+connection master;
+DROP TABLE t1, t2, t3, t4;
+sync_slave_with_master;
+    --echo # connection slave
+    connection slave;
+    --replace_result $MASTER_MYPORT MASTER_PORT
+    --replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
+    --query_vertical show slave status;
+--echo # connection master
+connection master;
+
+--echo #
+--echo # CREATE ... SELECT from temporary table
+--echo #
+CREATE TEMPORARY TABLE t1 (c1 INT);
+CREATE           TABLE t2 (c1 INT);
+CREATE TEMPORARY TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+CREATE TEMPORARY TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+  INSERT_METHOD=LAST SELECT * FROM t3;
+INSERT INTO t4 VALUES (4);
+# Temporary t4 cannot be seen on slave
+CREATE TABLE t5 (c1 INT) ENGINE=MRG_MYISAM UNION=(t2)
+  INSERT_METHOD=LAST SELECT * FROM t4;
+--replace_regex /#sql[0-9a-z_]+/#sql-temporary/
+SHOW CREATE TABLE t4;
+SHOW CREATE TABLE t5;
+SELECT * FROM t4 ORDER BY c1;
+SELECT * FROM t5 ORDER BY c1;
+sync_slave_with_master;
+    --echo # connection slave
+    connection slave;
+    --error ER_NO_SUCH_TABLE
+    SHOW CREATE TABLE t4;
+    SHOW CREATE TABLE t5;
+    --error ER_NO_SUCH_TABLE
+    SELECT * FROM t4 ORDER BY c1;
+    SELECT * FROM t5 ORDER BY c1;
+--echo # connection master
+connection master;
+DROP TABLE t1, t2, t3, t4, t5;
+sync_slave_with_master;
+    --echo # connection slave
+    connection slave;
+    --replace_result $MASTER_MYPORT MASTER_PORT
+    --replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
+    --query_vertical show slave status;
+--echo # connection master
+connection master;
+
diff -Nrup a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
--- a/mysql-test/t/delayed.test	2007-09-10 11:37:48 +02:00
+++ b/mysql-test/t/delayed.test	2007-11-02 17:28:15 +01:00
@@ -248,7 +248,7 @@ DROP TABLE t1;
 #
 CREATE TABLE t1(c1 INT) ENGINE=MyISAM;
 CREATE TABLE t2(c1 INT) ENGINE=MERGE UNION=(t1);
---error 1031
+--error ER_ILLEGAL_HA
 INSERT DELAYED INTO t2 VALUES(1);
 DROP TABLE t1, t2;
 #
diff -Nrup a/mysql-test/t/merge-big.test b/mysql-test/t/merge-big.test
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/merge-big.test	2007-11-02 17:28:16 +01:00
@@ -0,0 +1,150 @@
+#
+# Test of MERGE tables with multisession and many waits.
+#
+# This test takes rather long time so let us run it only in --big-test mode
+--source include/big_test.inc
+# We are using some debug-only features in this test
+--source include/have_debug.inc
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4,t5,t6;
+--enable_warnings
+
+--echo #
+--echo # Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
+--echo #             corrupts a MERGE table
+--echo # Problem #3
+--echo #
+# Two FLUSH TABLES within a LOCK TABLES segment could invalidate the lock.
+# This did *not* require a MERGE table.
+#
+# To increase reproducibility it was necessary to enter a sleep of 2
+# seconds at the end of wait_for_tables() after unlock of LOCK_open. In
+# 5.0 and 5.1 the sleep must be inserted in open_and_lock_tables() after
+# open_tables() instead. wait_for_tables() is not used in this case. The
+# problem was that FLUSH TABLES releases LOCK_open while having unlocked
+# and closed all tables. When this happened while a thread was in the
+# loop in mysql_lock_tables() right after wait_for_tables()
+# (open_tables()) and before retrying to lock, the thread got the lock.
+# And it did not notice that the table needed a refresh after the
+# [re-]open. So it executed its statement on the table.
+#
+# The first FLUSH TABLES kicked the INSERT out of thr_multi_lock() and
+# let it wait in wait_for_tables() (open_table()). The second FLUSH
+# TABLES must happen while the INSERT was on its way from
+# wait_for_tables() (open_table()) to the next call of thr_multi_lock().
+# This needed to be supported by a sleep to make it repeatable.
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+#SELECT NOW();
+    --echo # connection con1
+    connect (con1,localhost,root,,);
+    let $con1_id= `SELECT CONNECTION_ID()`;
+    SET SESSION debug="+d,sleep_open_and_lock_after_open";
+    send INSERT INTO t1 VALUES (1);
+--echo # connection default
+connection default;
+--echo # Let INSERT go into thr_multi_lock().
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+    WHERE ID = $con1_id AND STATE = 'Locked';
+--source include/wait_condition.inc
+#SELECT NOW();
+--echo # Kick INSERT out of thr_multi_lock().
+FLUSH TABLES;
+#SELECT NOW();
+--echo # Let INSERT go through open_tables() where it sleeps.
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+    WHERE ID = $con1_id AND STATE = 'DBUG sleep';
+--source include/wait_condition.inc
+#SELECT NOW();
+--echo # Unlock and close table and wait for con1 to close too.
+FLUSH TABLES;
+#SELECT NOW();
+--echo # This should give no result.
+SELECT * FROM t1;
+#SELECT NOW();
+UNLOCK TABLES;
+    --echo # connection con1
+    connection con1;
+    reap;
+    SET SESSION debug="-d,sleep_open_and_lock_after_open";
+    disconnect con1;
+--echo # connection default
+connection default;
+DROP TABLE t1;
+
+--echo #
+--echo # Extra tests for Bug#26379 - Combination of FLUSH TABLE and
+--echo #                             REPAIR TABLE corrupts a MERGE table
+--echo #
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+--echo #
+--echo # CREATE ... SELECT
+--echo # try to access parent from another thread.
+--echo #
+#SELECT NOW();
+    --echo # connection con1
+    connect (con1,localhost,root,,);
+    let $con1_id= `SELECT CONNECTION_ID()`;
+    SET SESSION debug="+d,sleep_create_select_before_lock";
+    send CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+         INSERT_METHOD=FIRST SELECT * FROM t3;
+--echo # connection default
+connection default;
+# wait for the other query to start executing
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+    WHERE ID = $con1_id AND STATE = 'DBUG sleep';
+--source include/wait_condition.inc
+#SELECT NOW();
+--echo # Now try to access the parent.
+--echo # If 3 is in table, SELECT had to wait.
+SELECT * FROM t4 ORDER BY c1;
+#SELECT NOW();
+    --echo # connection con1
+    connection con1;
+    reap;
+    #SELECT NOW();
+    SET SESSION debug="-d,sleep_create_select_before_lock";
+    disconnect con1;
+--echo # connection default
+connection default;
+--echo # Cleanup for next test.
+DROP TABLE t4;
+DELETE FROM t1 WHERE c1 != 1;
+--echo #
+--echo # CREATE ... SELECT
+--echo # try to access child from another thread.
+--echo #
+#SELECT NOW();
+    --echo # connection con1
+    connect (con1,localhost,root,,);
+    let $con1_id= `SELECT CONNECTION_ID()`;
+    SET SESSION debug="+d,sleep_create_select_before_lock";
+    send CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+         INSERT_METHOD=FIRST SELECT * FROM t3;
+--echo # connection default
+connection default;
+# wait for the other query to start executing
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+    WHERE ID = $con1_id AND STATE = 'DBUG sleep';
+--source include/wait_condition.inc
+#SELECT NOW();
+--echo # Now try to access a child.
+--echo # If 3 is in table, SELECT had to wait.
+SELECT * FROM t1 ORDER BY c1;
+#SELECT NOW();
+    --echo # connection con1
+    connection con1;
+    reap;
+    #SELECT NOW();
+    SET SESSION debug="-d,sleep_create_select_before_lock";
+    disconnect con1;
+--echo # connection default
+connection default;
+DROP TABLE t1, t2, t3, t4;
diff -Nrup a/mysql-test/t/merge.test b/mysql-test/t/merge.test
--- a/mysql-test/t/merge.test	2007-10-09 14:18:07 +02:00
+++ b/mysql-test/t/merge.test	2007-11-02 17:28:15 +01:00
@@ -221,6 +221,7 @@ create table t2 (a int not null);
 insert into t1 values (1);
 insert into t2 values (2);
 create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+--error ER_WRONG_MRG_TABLE
 select * from t3;
 create temporary table t4 (a int not null);
 create temporary table t5 (a int not null);
@@ -229,6 +230,53 @@ insert into t5 values (2);
 create temporary table t6 (a int not null) ENGINE=MERGE UNION=(t4,t5);
 select * from t6;
 drop table t6, t3, t1, t2, t4, t5;
+#
+# Bug#19627 - temporary merge table locking
+# MERGE table and its children must match in temporary type.
+# Forbid temporary merge on non-temporary children: shown above.
+# Forbid non-temporary merge on temporary children:
+create temporary table t1 (a int not null);
+create temporary table t2 (a int not null);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+--error ER_WRONG_MRG_TABLE
+select * from t3;
+drop table t3, t2, t1;
+# Forbid children mismatch in temporary:
+create table t1 (a int not null);
+create temporary table t2 (a int not null);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+--error ER_WRONG_MRG_TABLE
+select * from t3;
+drop table t3;
+create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+--error ER_WRONG_MRG_TABLE
+select * from t3;
+drop table t3, t2, t1;
+# Show CREATE...SELECT under LOCK TABLES:
+CREATE TEMPORARY TABLE t1 (c1 INT NOT NULL);
+CREATE TEMPORARY TABLE t2 (c1 INT NOT NULL);
+CREATE TABLE t3 (c1 INT NOT NULL);
+INSERT INTO t3 VALUES (3), (33);
+LOCK TABLES t3 READ;
+CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL) ENGINE=MERGE UNION=(t1,t2)
+  INSERT_METHOD=LAST SELECT * FROM t3;
+SELECT * FROM t4;
+UNLOCK TABLES;
+--echo # Alter temporary MERGE table.
+ALTER TABLE t4 UNION=(t1);
+LOCK TABLES t4 WRITE;
+--echo # Alter temporary MERGE table under LOCk tables.
+ALTER TABLE t4 UNION=(t1,t2);
+UNLOCK TABLES;
+--echo # MERGE table and function.
+CREATE FUNCTION f1 () RETURNS INT RETURN (SELECT max(c1) FROM t3);
+SELECT * FROM t4 WHERE c1 < f1();
+DROP FUNCTION f1;
+DROP TABLE t4, t3, t2, t1;
 
 #
 # testing merge::records_in_range and optimizer
@@ -403,7 +451,7 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNIO
 SELECT * FROM t2;
 DROP TABLE t1, t2;
 CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
---error 1168
+--error ER_NO_SUCH_TABLE
 SELECT * FROM t2;
 DROP TABLE t2;
 
@@ -495,11 +543,11 @@ drop table t1;
 #             CREATE TABLE fails
 #
 CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
---error 1168
+--error ER_NO_SUCH_TABLE
 SELECT * FROM tm1;
 CHECK TABLE tm1;
 CREATE TABLE t1(a INT);
---error 1168
+--error ER_NO_SUCH_TABLE
 SELECT * FROM tm1;
 CHECK TABLE tm1;
 CREATE TABLE t2(a BLOB);
@@ -526,3 +574,675 @@ CREATE TABLE IF NOT EXISTS t1 SELECT * F
 DROP TABLE t1, t2;
 
 --echo End of 5.0 tests
+
+#
+# Bug #8306: TRUNCATE leads to index corruption 
+#
+create table t1 (c1 int, index(c1));
+create table t2 (c1 int, index(c1)) engine=merge union=(t1);
+insert into t1 values (1);
+# Close all tables.
+flush tables;
+# Open t2 and (implicitly) t1.
+select * from t2;
+# Truncate after flush works (unless another threads reopens t2 in between).
+flush tables;
+truncate table t1;
+insert into t1 values (1);
+# Close all tables.
+flush tables;
+# Open t2 and (implicitly) t1.
+select * from t2;
+# Truncate t1, wich was not recognized as open without the bugfix.
+# After fix for Bug#8306 and before fix for Bug#26379,
+# it should fail with a table-in-use error message, otherwise succeed.
+truncate table t1;
+# The insert used to fail on the crashed table.
+insert into t1 values (1);
+drop table t1,t2;
+--echo #
+--echo # Extra tests for TRUNCATE.
+--echo #
+--echo # Truncate MERGE table.
+CREATE TABLE t1 (c1 INT, INDEX(c1));
+CREATE TABLE t2 (c1 INT, INDEX(c1));
+CREATE TABLE t3 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1,t2);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t3;
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate child table.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate MERGE table under locked tables.
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate child table under locked tables.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3;
+--echo #
+--echo # Truncate temporary MERGE table.
+CREATE TEMPORARY TABLE t1 (c1 INT, INDEX(c1));
+CREATE TEMPORARY TABLE t2 (c1 INT, INDEX(c1));
+CREATE TEMPORARY TABLE t3 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1,t2);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t3;
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate temporary child table.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate temporary MERGE table under locked tables.
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t4 (c1 INT, INDEX(c1));
+LOCK TABLE t4 WRITE;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+TRUNCATE TABLE t3;
+SELECT * FROM t3;
+--echo #
+--echo # Truncate temporary child table under locked tables.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+TRUNCATE TABLE t1;
+SELECT * FROM t3;
+UNLOCK TABLES;
+DROP TABLE t1, t2, t3, t4;
+
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
+# Preparation
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connection default;
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
+# Problem #1
+# A thread trying to lock a MERGE table performed busy waiting while
+# REPAIR TABLE or a similar table administration task was ongoing on one or
+# more of its MyISAM tables.
+# To allow for observability it was necessary to enter a multi-second sleep
+# in mysql_admin_table() after remove_table_from_cache(), which comes after
+# mysql_abort_lock(). The sleep faked a long running operation. One could
+# watch a high CPU load during the sleep time.
+# The problem was that mysql_abort_lock() upgrades the write lock to
+# TL_WRITE_ONLY. This lock type persisted until the final unlock at the end
+# of the administration task. The effect of TL_WRITE_ONLY is to reject any
+# attempt to lock the table. The trying thread must close the table and wait
+# until it is no longer used. Unfortunately there is no way to detect that
+# one of the MyISAM tables of a MERGE table is in use. When trying to lock
+# the MERGE table, all MyISAM tables are locked. If one fails on
+# TL_WRITE_ONLY, all locks are aborted and wait_for_tables() is entered.
+# But this doesn't see the MERGE table as used, so it seems appropriate to
+# retry a lock...
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
+send REPAIR TABLE t1;
+    connection con1;
+    sleep 1; # let repair run into its sleep
+    INSERT INTO t2 VALUES (1);
+connection default;
+reap;
+DROP TABLE t1, t2;
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
+# Problem #2
+# A thread trying to lock a MERGE table performed busy waiting until all
+# threads that did REPAIR TABLE or similar table administration tasks on
+# one or more of its MyISAM tables in LOCK TABLES segments did
+# UNLOCK TABLES.
+# The difference against problem #1 is that the busy waiting took place
+# *after* the administration task. It was terminated by UNLOCK TABLES only.
+#
+# This is the same test case as for
+# Bug#26867 - LOCK TABLES + REPAIR + merge table result in memory/cpu hogging
+#
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
+LOCK TABLE t1 WRITE;
+    connection con1;
+    send INSERT INTO t2 VALUES (1);
+connection default;
+sleep 1; # Let INSERT go into thr_multi_lock().
+REPAIR TABLE t1;
+sleep 2; # con1 performs busy waiting during this sleep.
+UNLOCK TABLES;
+    connection con1;
+    reap;
+connection default;
+DROP TABLE t1, t2;
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
+# Problem #3
+# Two FLUSH TABLES within a LOCK TABLES segment could invalidate the lock.
+# This did *not* require a MERGE table.
+# To increase reproducibility it was necessary to enter a sleep of 2 seconds
+# at the end of wait_for_tables() after unlock of LOCK_open. In 5.0 and 5.1
+# the sleep must be inserted in open_and_lock_tables() after open_tables()
+# instead. wait_for_tables() is not used in this case.
+# The problem was that FLUSH TABLES releases LOCK_open while having unlocked
+# and closed all tables. When this happened while a thread was in the loop in
+# mysql_lock_tables() right after wait_for_tables() and before retrying to
+# lock, the thread got the lock.  (Translate to similar code places in 5.0
+# and 5.1). And it did not notice that the table needed a refresh. So it
+# executed its statement on the table.
+# The first FLUSH TABLES kicked the INSERT out of thr_multi_lock() and let
+# it wait in wait_for_tables(). (open_table() in 5.0 and 5.1). The second
+# FLUSH TABLES must happen while the INSERT was on its way from
+# wait_for_tables() to the next call of thr_multi_lock(). This needed to be
+# supported by a sleep to make it repeatable.
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+    connection con1;
+    send INSERT INTO t1 VALUES (1);
+connection default;
+sleep 1; # Let INSERT go into thr_multi_lock().
+FLUSH TABLES;
+sleep 1; # Let INSERT go through wait_for_tables() where it sleeps.
+FLUSH TABLES;
+# This should give no result. But it will with sleep(2) at the right place.
+SELECT * FROM t1;
+UNLOCK TABLES;
+    connection con1;
+    reap;
+connection default;
+DROP TABLE t1;
+#
+# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
+# Cleanup
+disconnect con1;
+disconnect con2;
+--echo #
+--echo # Extra tests for Bug#26379 - Combination of FLUSH TABLE and
+--echo #                             REPAIR TABLE corrupts a MERGE table
+--echo #
+--echo # CREATE ... SELECT
+--echo #
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (3);
+--echo # Show that LAST table is opened.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+  INSERT_METHOD=LAST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+DROP TABLE t4;
+--echo # Show that FIRST table is opened.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+  INSERT_METHOD=FIRST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+SELECT * FROM t4 ORDER BY c1;
+DROP TABLE t4;
+--echo # Show that CREATE..SELECT is not possible under LOCK TABLES
+--echo # for non-temporary tables.
+LOCK TABLE