List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:March 8 2011 9:22am
Subject:bzr push into mysql-5.5 branch (jon.hauglid:3375 to 3376) Bug#11755431
View as plain text  
 3376 Jon Olav Hauglid	2011-03-08
      Bug #11755431 (former 47205)
      MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT
      SUPPORTING NATIVE REPAIR
      
      Executing 'mysqlcheck --check-upgrade --auto-repair ...' will first issue
      'CHECK TABLE FOR UPGRADE' for all tables in the database in order to check if the
      tables are compatible with the current version of MySQL. Any tables that are
      found incompatible are then upgraded using 'REPAIR TABLE'.
      
      The problem was that some engines (e.g. InnoDB) do not support 'REPAIR TABLE'.
      This caused any such tables to be left incompatible. As a result such tables were
      not properly fixed by the mysql_upgrade tool.
      
      This patch fixes the problem by first changing 'CHECK TABLE FOR UPGRADE' to return
      a different error message if the engine does not support REPAIR. Instead of
      "Table upgrade required. Please do "REPAIR TABLE ..." it will report
      "Table rebuild required. Please do "ALTER TABLE ... FORCE ..."
      
      Second, the patch changes mysqlcheck to do 'ALTER TABLE ... FORCE' instead of
      'REPAIR TABLE' in these cases.
      
      This patch also fixes 'ALTER TABLE ... FORCE' to actually rebuild the table.
      This change should be reflected in the documentation. Before this patch,
      'ALTER TABLE ... FORCE' was unused (See Bug#11746162)
      
      Test case added to mysqlcheck.test
     @ client/mysqlcheck.c
        Changed mysqlcheck to do 'ALTER TABLE ... FORCE' if
        'CHECK TABLE FOR UPGRADE' reports ER_TABLE_NEEDS_REBUILD
        and not ER_TABLE_NEEDS_UPGRADE.
     @ mysql-test/r/mysqlcheck.result
        Added regression test.
     @ mysql-test/std_data/bug47205.frm
        InnoDB 5.0 FRM which contains a varchar primary key using
        utf8_general_ci. This is an incompatible FRM for 5.5.
     @ mysql-test/t/mysqlcheck.test
        Added regression test.
     @ sql/handler.h
        Added new HA_CAN_REPAIR flag.
     @ sql/share/errmsg-utf8.txt
        Added new error message ER_TABLE_NEEDS_REBUILD
     @ sql/sql_admin.cc
        Changed 'CHECK TABLE FOR UPDATE' to give ER_TABLE_NEEDS_REBUILD
        instead of ER_TABLE_NEEDS_UPGRADE if the engine does not support
        REPAIR (as indicated by the new HA_CAN_REPAIR flag).
     @ sql/sql_lex.h
        Remove unused ALTER_FORCE flag.
     @ sql/sql_yacc.yy
        Make sure ALTER TABLE ... FORCE recreates the table
        by setting the ALTER_RECREATE flag as the ALTER_FORCE
        flag was unused.
     @ storage/archive/ha_archive.h
        Added new HA_CAN_REPAIR flag to Archive
     @ storage/csv/ha_tina.h
        Added new HA_CAN_REPAIR flag to CSV
     @ storage/federated/ha_federated.h
        Added new HA_CAN_REPAIR flag to Federated
     @ storage/myisam/ha_myisam.cc
        Added new HA_CAN_REPAIR flag to MyISAM

    added:
      mysql-test/std_data/bug47205.frm
    modified:
      client/mysqlcheck.c
      mysql-test/r/mysqlcheck.result
      mysql-test/t/mysqlcheck.test
      sql/handler.cc
      sql/handler.h
      sql/share/errmsg-utf8.txt
      sql/sql_admin.cc
      sql/sql_lex.h
      sql/sql_yacc.yy
      storage/archive/ha_archive.h
      storage/csv/ha_tina.h
      storage/federated/ha_federated.h
      storage/myisam/ha_myisam.cc
 3375 Jon Olav Hauglid	2011-03-07
      Bug #11784056 ENABLE CONCURRENT READS WHILE CREATING
                    NON-PRIMARY UNIQUE INDEX USING INNODB
      
      This patch adds the HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE
      capability flag to InnoDB, indicating that concurrent reads
      can be allowed while non-primary unique indexes are created.
      
      This is an follow-up to Bug #11751388 which enabled concurrent
      reads when creating non-primary non-unique indexes.
      
      Test case added to innodb_mysql_sync.test.

    modified:
      mysql-test/r/innodb_mysql_sync.result
      mysql-test/t/innodb_mysql_sync.test
      storage/innobase/handler/ha_innodb.cc
=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c	2011-01-16 03:59:05 +0000
+++ b/client/mysqlcheck.c	2011-03-08 08:41:57 +0000
@@ -42,7 +42,7 @@ static char *opt_password = 0, *current_
 	    *default_charset= 0, *current_host= 0;
 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
 static int first_error = 0;
-DYNAMIC_ARRAY tables4repair;
+DYNAMIC_ARRAY tables4repair, tables4rebuild;
 #ifdef HAVE_SMEM
 static char *shared_memory_base_name=0;
 #endif
@@ -626,6 +626,27 @@ static int fix_database_storage_name(con
   return rc;
 }
 
+static int rebuild_table(char *name)
+{
+  char *query, *ptr;
+  int rc= 0;
+  query= (char*)my_malloc(sizeof(char) * (12 + fixed_name_length(name) + 6 + 1),
+                          MYF(MY_WME));
+  if (!query)
+    return 1;
+  ptr= strmov(query, "ALTER TABLE ");
+  ptr= fix_table_name(ptr, name);
+  ptr= strxmov(ptr, " FORCE", NullS);
+  if (mysql_real_query(sock, query, (uint)(ptr - query)))
+  {
+    fprintf(stderr, "Failed to %s\n", query);
+    fprintf(stderr, "Error: %s\n", mysql_error(sock));
+    rc= 1;
+  }
+  my_free(query);
+  return rc;
+}
+
 static int process_one_db(char *database)
 {
   if (what_to_do == DO_UPGRADE)
@@ -739,7 +760,7 @@ static void print_result()
   MYSQL_ROW row;
   char prev[NAME_LEN*2+2];
   uint i;
-  my_bool found_error=0;
+  my_bool found_error=0, table_rebuild=0;
 
   res = mysql_use_result(sock);
 
@@ -758,8 +779,14 @@ static void print_result()
       */
       if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
 	  strcmp(row[3],"OK"))
-	insert_dynamic(&tables4repair, (uchar*) prev);
+      {
+        if (table_rebuild)
+          insert_dynamic(&tables4rebuild, (uchar*) prev);
+        else
+          insert_dynamic(&tables4repair, (uchar*) prev);
+      }
       found_error=0;
+      table_rebuild=0;
       if (opt_silent)
 	continue;
     }
@@ -769,7 +796,11 @@ static void print_result()
     {
       printf("%s\n%-9s: %s", row[0], row[2], row[3]);
       if (strcmp(row[2],"note"))
+      {
 	found_error=1;
+        if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL)
+          table_rebuild=1;
+      }
     }
     else
       printf("%-9s: %s", row[2], row[3]);
@@ -778,7 +809,12 @@ static void print_result()
   }
   /* add the last table to be repaired to the list */
   if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
-    insert_dynamic(&tables4repair, (uchar*) prev);
+  {
+    if (table_rebuild)
+      insert_dynamic(&tables4rebuild, (uchar*) prev);
+    else
+      insert_dynamic(&tables4repair, (uchar*) prev);
+  }
   mysql_free_result(res);
 }
 
@@ -876,7 +912,8 @@ int main(int argc, char **argv)
   }
 
   if (opt_auto_repair &&
-      my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
+      (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64) ||
+       my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64)))
   {
     first_error = 1;
     goto end;
@@ -894,7 +931,7 @@ int main(int argc, char **argv)
   {
     uint i;
 
-    if (!opt_silent && tables4repair.elements)
+    if (!opt_silent && (tables4repair.elements || tables4rebuild.elements))
       puts("\nRepairing tables");
     what_to_do = DO_REPAIR;
     for (i = 0; i < tables4repair.elements ; i++)
@@ -902,11 +939,16 @@ int main(int argc, char **argv)
       char *name= (char*) dynamic_array_ptr(&tables4repair, i);
       handle_request_for_tables(name, fixed_name_length(name));
     }
+    for (i = 0; i < tables4rebuild.elements ; i++)
+      rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i));
   }
  end:
   dbDisconnect(current_host);
   if (opt_auto_repair)
+  {
     delete_dynamic(&tables4repair);
+    delete_dynamic(&tables4rebuild);
+  }
   my_free(opt_password);
 #ifdef HAVE_SMEM
   my_free(shared_memory_base_name);

=== modified file 'mysql-test/r/mysqlcheck.result'
--- a/mysql-test/r/mysqlcheck.result	2010-12-17 11:11:34 +0000
+++ b/mysql-test/r/mysqlcheck.result	2011-03-08 08:41:57 +0000
@@ -109,7 +109,7 @@ mysql.time_zone_name
 mysql.time_zone_transition                         Table is already up to date
 mysql.time_zone_transition_type                    Table is already up to date
 mysql.user                                         Table is already up to date
-create table t1 (a int);
+create table t1 (a int) engine=myisam;
 create view v1 as select * from t1;
 test.t1                                            OK
 test.t1                                            Table is already up to date
@@ -117,14 +117,14 @@ test.t1
 test.t1                                            Table is already up to date
 drop view v1;
 drop table t1;
-create table `t``1`(a int);
-create table `t 1`(a int);
+create table `t``1`(a int) engine=myisam;
+create table `t 1`(a int) engine=myisam;
 test.t 1                                           OK
 test.t`1                                           OK
 drop table `t``1`, `t 1`;
 create database d_bug25347;
 use d_bug25347;
-create table t_bug25347 (a int);
+create table t_bug25347 (a int) engine=myisam;
 create view v_bug25347 as select * from t_bug25347;
 insert into t_bug25347 values (1),(2),(3);
 flush tables;
@@ -164,15 +164,15 @@ Table	Op	Msg_type	Msg_text
 test.v1	check	status	OK
 information_schema.routines	check	note	The storage engine for the table doesn't support check
 drop view v1;
-CREATE TABLE t1(a INT);
-CREATE TABLE t2(a INT);
+CREATE TABLE t1(a INT) engine=myisam;
+CREATE TABLE t2(a INT) engine=myisam;
 test.t1
 Error    : Incorrect information in file: './test/t1.frm'
 error    : Corrupt
 test.t2                                            OK
 DROP TABLE t1, t2;
 End of 5.0 tests
-create table t1(a int);
+create table t1(a int) engine=myisam;
 create view v1 as select * from t1;
 show tables;
 Tables_in_test
@@ -192,7 +192,7 @@ v-1
 drop view v1, `v-1`;
 drop table t1;
 SET NAMES utf8;
-CREATE TABLE `#mysql50#@` (a INT);
+CREATE TABLE `#mysql50#@` (a INT) engine=myisam;
 SHOW TABLES;
 Tables_in_test
 #mysql50#@
@@ -203,7 +203,7 @@ SHOW TABLES;
 Tables_in_test
 @
 DROP TABLE `@`;
-CREATE TABLE `я` (a INT);
+CREATE TABLE `я` (a INT) engine=myisam;
 SET NAMES DEFAULT;
 mysqlcheck --default-character-set="latin1" --databases test
 test.?
@@ -216,8 +216,8 @@ DROP TABLE `я`;
 SET NAMES DEFAULT;
 CREATE DATABASE `#mysql50#a@b`;
 USE `#mysql50#a@b`;
-CREATE TABLE `#mysql50#c@d` (a INT);
-CREATE TABLE t1 (a INT);
+CREATE TABLE `#mysql50#c@d` (a INT) engine=myisam;
+CREATE TABLE t1 (a INT) engine=myisam;
 SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
 WHERE TRIGGER_SCHEMA="#mysql50#a@b" ORDER BY trigger_name;
 TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER	CHARACTER_SET_CLIENT	COLLATION_CONNECTION	DATABASE_COLLATION
@@ -246,12 +246,12 @@ USE test;
 # Bug #31821: --all-in-1 and --fix-table-names don't work together
 #
 drop table if exists `#mysql50#t1-1`;
-create table `#mysql50#t1-1` (a int);
+create table `#mysql50#t1-1` (a int) engine=myisam;
 show tables like 't1-1';
 Tables_in_test (t1-1)
 t1-1
 drop table `t1-1`;
-create table `#mysql50#t1-1` (a int);
+create table `#mysql50#t1-1` (a int) engine=myisam;
 show tables like 't1-1';
 Tables_in_test (t1-1)
 t1-1
@@ -260,3 +260,67 @@ End of 5.1 tests
 #
 # Bug #35269: mysqlcheck behaves different depending on order of parameters
 #
+#
+# Bug#11755431 47205: MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR
+#              ENGINES NOT SUPPORTING NATIVE
+#
+DROP TABLE IF EXISTS bug47205;
+#
+# Test 1: Check that ALTER TABLE ... rebuilds the table
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+INSERT INTO bug47205 VALUES ("foobar");
+FLUSH TABLE bug47205;
+# Replace the FRM with a 5.0 FRM that will require upgrade
+# Should indicate that ALTER TABLE ... FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	error	Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
+# ALTER TABLE ... FORCE should rebuild the table
+# and therefore output "affected rows: 1"
+ALTER TABLE bug47205 FORCE;
+affected rows: 1
+info: Records: 1  Duplicates: 0  Warnings: 0
+# Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	status	OK
+DROP TABLE bug47205;
+#
+# Test 2: InnoDB - REPAIR not supported
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+FLUSH TABLE bug47205;
+# Replace the FRM with a 5.0 FRM that will require upgrade
+# Should indicate that ALTER TABLE .. FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	error	Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
+# Running mysqlcheck to check and upgrade
+test.bug47205
+error    : Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
+
+Repairing tables
+# Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	status	OK
+DROP TABLE bug47205;
+#
+# Test 3: MyISAM - REPAIR supported
+# Use an old FRM that will require upgrade
+# Should indicate that REPAIR TABLE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	error	Table upgrade required. Please do "REPAIR TABLE `bug47205`" or dump/reload to fix it!
+# Running mysqlcheck to check and upgrade
+test.bug47205
+error    : Table upgrade required. Please do "REPAIR TABLE `bug47205`" or dump/reload to fix it!
+
+Repairing tables
+test.bug47205                                      OK
+# Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.bug47205	check	status	OK
+DROP TABLE bug47205;

=== added file 'mysql-test/std_data/bug47205.frm'
Binary files a/mysql-test/std_data/bug47205.frm	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47205.frm	2011-03-08 08:41:57 +0000 differ

=== modified file 'mysql-test/t/mysqlcheck.test'
--- a/mysql-test/t/mysqlcheck.test	2010-10-08 07:09:47 +0000
+++ b/mysql-test/t/mysqlcheck.test	2011-03-08 08:41:57 +0000
@@ -2,6 +2,8 @@
 # Embedded server doesn't support external clients
 --source include/not_embedded.inc
 
+--source include/have_innodb.inc
+
 # check that CSV engine was compiled in, as the result of the test
 # depends on the presence of the log tables (which are CSV-based).
 --source include/have_csv.inc
@@ -34,7 +36,7 @@ drop database if exists client_test_db;
 #
 # Bug #16502: mysqlcheck tries to check views
 #
-create table t1 (a int);
+create table t1 (a int) engine=myisam;
 create view v1 as select * from t1;
 --replace_result 'Table is already up to date' OK
 --exec $MYSQL_CHECK --analyze --databases test
@@ -48,8 +50,8 @@ drop table t1;
 #
 # Bug #30654: mysqlcheck fails during upgrade of tables whose names include backticks
 #
-create table `t``1`(a int);
-create table `t 1`(a int);
+create table `t``1`(a int) engine=myisam;
+create table `t 1`(a int) engine=myisam;
 --replace_result 'Table is already up to date' OK
 --exec $MYSQL_CHECK --databases test
 drop table `t``1`, `t 1`;
@@ -59,7 +61,7 @@ drop table `t``1`, `t 1`;
 #
 create database d_bug25347;
 use d_bug25347;
-create table t_bug25347 (a int);
+create table t_bug25347 (a int) engine=myisam;
 create view v_bug25347 as select * from t_bug25347;
 insert into t_bug25347 values (1),(2),(3);
 flush tables;
@@ -91,8 +93,8 @@ drop view v1;
 # Bug#37527: mysqlcheck fails to report entire database 
 # when frm file corruption
 #
-CREATE TABLE t1(a INT);
-CREATE TABLE t2(a INT);
+CREATE TABLE t1(a INT) engine=myisam;
+CREATE TABLE t2(a INT) engine=myisam;
 # backup then null t1.frm
 --copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/t1.frm.bak
 --remove_file $MYSQLD_DATADIR/test/t1.frm
@@ -112,7 +114,7 @@ DROP TABLE t1, t2;
 #
 # Bug #30679: 5.1 name encoding not performed for views during upgrade
 #
-create table t1(a int);
+create table t1(a int) engine=myisam;
 create view v1 as select * from t1;
 show tables;
 let $MYSQLD_DATADIR= `select @@datadir`;
@@ -131,7 +133,7 @@ drop table t1;
 #             triggers
 #
 SET NAMES utf8;
-CREATE TABLE `#mysql50#@` (a INT);
+CREATE TABLE `#mysql50#@` (a INT) engine=myisam;
 SHOW TABLES;
 SET NAMES DEFAULT;
 --echo mysqlcheck --fix-table-names --databases test
@@ -140,7 +142,7 @@ SET NAMES utf8;
 SHOW TABLES;
 DROP TABLE `@`;
 
-CREATE TABLE `я` (a INT);
+CREATE TABLE `qlcheck --default-character-set="latin1" --databases test
 # Error returned depends on platform, replace it with "Table doesn't exist"
@@ -154,8 +156,8 @@ SET NAMES DEFAULT;
 
 CREATE DATABASE `#mysql50#a@b`;
 USE `#mysql50#a@b`;
-CREATE TABLE `#mysql50#c@d` (a INT);
-CREATE TABLE t1 (a INT);
+CREATE TABLE `#mysql50#c@d` (a INT) engine=myisam;
+CREATE TABLE t1 (a INT) engine=myisam;
 
 # Create 5.0 like triggers
 let $MYSQLTEST_VARDIR= `select @@datadir`;
@@ -207,12 +209,12 @@ USE test;
 drop table if exists `#mysql50#t1-1`;
 --enable_warnings
 
-create table `#mysql50#t1-1` (a int);
+create table `#mysql50#t1-1` (a int) engine=myisam;
 --exec $MYSQL_CHECK --all-in-1 --fix-table-names --databases test
 show tables like 't1-1';
 drop table `t1-1`;
 
-create table `#mysql50#t1-1` (a int);
+create table `#mysql50#t1-1` (a int) engine=myisam;
 --exec $MYSQL_CHECK --all-in-1 --fix-table-names test "#mysql50#t1-1"
 show tables like 't1-1';
 drop table `t1-1`;
@@ -229,3 +231,83 @@ drop table `t1-1`;
 --error 1
 --exec $MYSQL_CHECK -aoc test "#mysql50#t1-1"
 
+
+--echo #
+--echo # Bug#11755431 47205: MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR
+--echo #              ENGINES NOT SUPPORTING NATIVE
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS bug47205;
+--enable_warnings
+
+--echo #
+--echo # Test 1: Check that ALTER TABLE ... rebuilds the table
+
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+
+INSERT INTO bug47205 VALUES ("foobar");
+FLUSH TABLE bug47205;
+
+--echo # Replace the FRM with a 5.0 FRM that will require upgrade
+let $MYSQLD_DATADIR= `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/test/bug47205.frm
+--copy_file std_data/bug47205.frm $MYSQLD_DATADIR/test/bug47205.frm
+
+--echo # Should indicate that ALTER TABLE ... FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+
+--echo # ALTER TABLE ... FORCE should rebuild the table
+--echo # and therefore output "affected rows: 1"
+--enable_info
+ALTER TABLE bug47205 FORCE;
+--disable_info
+
+--echo # Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+
+DROP TABLE bug47205;
+
+--echo #
+--echo # Test 2: InnoDB - REPAIR not supported
+
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+
+FLUSH TABLE bug47205;
+
+--echo # Replace the FRM with a 5.0 FRM that will require upgrade
+let $MYSQLD_DATADIR= `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/test/bug47205.frm
+--copy_file std_data/bug47205.frm $MYSQLD_DATADIR/test/bug47205.frm
+
+--echo # Should indicate that ALTER TABLE .. FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+
+--echo # Running mysqlcheck to check and upgrade
+--exec $MYSQL_CHECK --check-upgrade --auto-repair test
+
+--echo # Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+
+DROP TABLE bug47205;
+
+--echo #
+--echo # Test 3: MyISAM - REPAIR supported
+
+--echo # Use an old FRM that will require upgrade
+--copy_file std_data/bug36055.frm $MYSQLD_DATADIR/test/bug47205.frm
+--copy_file std_data/bug36055.MYD $MYSQLD_DATADIR/test/bug47205.MYD
+--copy_file std_data/bug36055.MYI $MYSQLD_DATADIR/test/bug47205.MYI
+
+--echo # Should indicate that REPAIR TABLE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+
+--echo # Running mysqlcheck to check and upgrade
+--exec $MYSQL_CHECK --check-upgrade --auto-repair test
+
+--echo # Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+
+DROP TABLE bug47205;

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-03-01 14:42:37 +0000
+++ b/sql/handler.cc	2011-03-08 08:41:57 +0000
@@ -3214,9 +3214,13 @@ int handler::ha_repair(THD* thd, HA_CHEC
 
   mark_trx_read_write();
 
-  if ((result= repair(thd, check_opt)))
-    return result;
-  return update_frm_version(table);
+  result= repair(thd, check_opt);
+  DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED ||
+              ha_table_flags() & HA_CAN_REPAIR);
+
+  if (result == HA_ADMIN_OK)
+    result= update_frm_version(table);
+  return result;
 }
 
 

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2011-01-26 13:23:29 +0000
+++ b/sql/handler.h	2011-03-08 08:41:57 +0000
@@ -153,6 +153,12 @@
     ordered.
 */
 #define HA_DUPLICATE_KEY_NOT_IN_ORDER    (LL(1) << 36)
+/*
+  Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
+  incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
+  will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
+*/
+#define HA_CAN_REPAIR                    (LL(1) << 37)
 
 /*
   Set of all binlog flags. Currently only contain the capabilities
@@ -2010,7 +2016,10 @@ private:
      upon the table.
   */
   virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
-  { return HA_ADMIN_NOT_IMPLEMENTED; }
+  {
+    DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
+    return HA_ADMIN_NOT_IMPLEMENTED;
+  }
   virtual void start_bulk_insert(ha_rows rows) {}
   virtual int end_bulk_insert() { return 0; }
   virtual int index_read(uchar * buf, const uchar * key, uint key_len,

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2011-02-21 15:49:03 +0000
+++ b/sql/share/errmsg-utf8.txt	2011-03-08 08:41:57 +0000
@@ -6397,3 +6397,8 @@ ER_STMT_CACHE_FULL
 
 ER_MULTI_UPDATE_KEY_CONFLICT
   eng "Primary key/partition key update is not allowed since the table is updated both as '%-.192s' and '%-.192s'."
+
+# When translating this error message make sure to include "ALTER TABLE" in the
+# message as mysqlcheck parses the error message looking for ALTER TABLE.
+ER_TABLE_NEEDS_REBUILD
+        eng "Table rebuild required. Please do \"ALTER TABLE `%-.32s` FORCE\" or dump/reload to fix it!"

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2011-01-10 13:12:23 +0000
+++ b/sql/sql_admin.cc	2011-03-08 08:41:57 +0000
@@ -771,8 +771,12 @@ send_result_message:
       size_t length;
 
       protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-      length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
-                         table->table_name);
+      if (table->table->file->ha_table_flags() & HA_CAN_REPAIR)
+        length= my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
+                            table->table_name);
+      else
+        length= my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_REBUILD),
+                            table->table_name);
       protocol->store(buf, length, system_charset_info);
       fatal_error=1;
       break;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-03-01 14:42:37 +0000
+++ b/sql/sql_lex.h	2011-03-08 08:41:57 +0000
@@ -944,20 +944,19 @@ inline bool st_select_lex_unit::is_union
 #define ALTER_CHANGE_COLUMN_DEFAULT (1L << 8)
 #define ALTER_KEYS_ONOFF        (1L << 9)
 #define ALTER_CONVERT           (1L << 10)
-#define ALTER_FORCE		(1L << 11)
-#define ALTER_RECREATE          (1L << 12)
-#define ALTER_ADD_PARTITION     (1L << 13)
-#define ALTER_DROP_PARTITION    (1L << 14)
-#define ALTER_COALESCE_PARTITION (1L << 15)
-#define ALTER_REORGANIZE_PARTITION (1L << 16) 
-#define ALTER_PARTITION          (1L << 17)
-#define ALTER_ADMIN_PARTITION    (1L << 18)
-#define ALTER_TABLE_REORG        (1L << 19)
-#define ALTER_REBUILD_PARTITION  (1L << 20)
-#define ALTER_ALL_PARTITION      (1L << 21)
-#define ALTER_REMOVE_PARTITIONING (1L << 22)
-#define ALTER_FOREIGN_KEY        (1L << 23)
-#define ALTER_TRUNCATE_PARTITION (1L << 24)
+#define ALTER_RECREATE          (1L << 11)
+#define ALTER_ADD_PARTITION     (1L << 12)
+#define ALTER_DROP_PARTITION    (1L << 13)
+#define ALTER_COALESCE_PARTITION (1L << 14)
+#define ALTER_REORGANIZE_PARTITION (1L << 15)
+#define ALTER_PARTITION          (1L << 16)
+#define ALTER_ADMIN_PARTITION    (1L << 17)
+#define ALTER_TABLE_REORG        (1L << 18)
+#define ALTER_REBUILD_PARTITION  (1L << 19)
+#define ALTER_ALL_PARTITION      (1L << 20)
+#define ALTER_REMOVE_PARTITIONING (1L << 21)
+#define ALTER_FOREIGN_KEY        (1L << 22)
+#define ALTER_TRUNCATE_PARTITION (1L << 23)
 
 enum enum_alter_table_change_level
 {

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-02-16 16:27:35 +0000
+++ b/sql/sql_yacc.yy	2011-03-08 08:41:57 +0000
@@ -6747,7 +6747,7 @@ alter_list_item:
           }
         | FORCE_SYM
           {
-            Lex->alter_info.flags|= ALTER_FORCE;
+            Lex->alter_info.flags|= ALTER_RECREATE;
           }
         | alter_order_clause
           {

=== modified file 'storage/archive/ha_archive.h'
--- a/storage/archive/ha_archive.h	2010-10-06 14:34:28 +0000
+++ b/storage/archive/ha_archive.h	2011-03-08 08:41:57 +0000
@@ -90,7 +90,7 @@ public:
     return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD |
             HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
             HA_STATS_RECORDS_IS_EXACT |
-            HA_HAS_RECORDS |
+            HA_HAS_RECORDS | HA_CAN_REPAIR |
             HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY);
   }
   ulong index_flags(uint idx, uint part, bool all_parts) const

=== modified file 'storage/csv/ha_tina.h'
--- a/storage/csv/ha_tina.h	2010-07-08 21:20:08 +0000
+++ b/storage/csv/ha_tina.h	2011-03-08 08:41:57 +0000
@@ -106,7 +106,8 @@ public:
   ulonglong table_flags() const
   {
     return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
-            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
+            HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
+            HA_CAN_REPAIR);
   }
   ulong index_flags(uint idx, uint part, bool all_parts) const
   {

=== modified file 'storage/federated/ha_federated.h'
--- a/storage/federated/ha_federated.h	2010-10-06 14:34:28 +0000
+++ b/storage/federated/ha_federated.h	2011-03-08 08:41:57 +0000
@@ -149,7 +149,8 @@ public:
             HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
             HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
             HA_NO_TRANSACTIONS /* until fixed by WL#2952 */ |
-            HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
+            HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY |
+            HA_CAN_REPAIR);
   }
   /*
     This is a bitmap of flags that says how the storage engine

=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc	2011-01-11 09:07:37 +0000
+++ b/storage/myisam/ha_myisam.cc	2011-03-08 08:41:57 +0000
@@ -639,7 +639,7 @@ ha_myisam::ha_myisam(handlerton *hton, T
                   HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
                   HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
                   HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
-                  HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT),
+                  HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT | HA_CAN_REPAIR),
    can_enable_indexes(1)
 {}
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5 branch (jon.hauglid:3375 to 3376) Bug#11755431Jon Olav Hauglid8 Mar