List:Commits« Previous MessageNext Message »
From:Ramil Kalimullin Date:December 19 2008 11:45am
Subject:bzr commit into mysql-5.1-bugteam branch (ramil:2765) Bug#33094
View as plain text  
#At file:///home/ram/mysql/b33094-5.1-bugteam/ based on revid:timothy.smith@stripped58-hpycivk90zab4hw7

 2765 Ramil Kalimullin	2008-12-19
      Fix for
      bug#33094: Error in upgrading from 5.0 to 5.1 when table contains
      triggers
      and
      #41385: Crash when attempting to repair a #mysql50# upgraded table
      #with
      triggers.
      
      Problem:
      1. trigger code didn't assume a table name may have
      a "#mysql50#" prefix, that may lead to a failing ASSERT().
      2. mysqlcheck --fix-table-name doesn't use UTF8 as a default
      character set that results in (parsing) errors for tables with
      non-latin symbols in their names.
      
      Fix:
      1. properly handle table names with "#mysql50#" prefix.
      2. handle --default-character-set mysqlcheck option;
      if mysqlcheck is launched with --fix-table-name or --fix-db-name
      set default character set to UTF8 if no --default-character-set 
      option given.
      
      Note: if given --fix-table-name or --fix-db-name option,
      without --default-character-set mysqlcheck option
      default character set is UTF8.
      
      There's no test case from the bug report as it may fail on
      some filesystems.
modified:
  client/mysqlcheck.c
  mysql-test/r/mysqlcheck.result
  mysql-test/t/mysqlcheck.test
  sql/sql_trigger.cc

per-file messages:
  client/mysqlcheck.c
    Fix for
    bug#33094: Error in upgrading from 5.0 to 5.1 when table contains
    triggers
    and
    #41385: Crash when attempting to repair a #mysql50# upgraded table with
    triggers.
      - check and set default charset if --default-character-set option
    given.
      - set default charset to "utf8" if there's
    --fix-table-name or --fix-db-name and no --default-character-set.
  mysql-test/r/mysqlcheck.result
    Fix for
    bug#33094: Error in upgrading from 5.0 to 5.1 when table contains
    triggers
    and
    #41385: Crash when attempting to repair a #mysql50# upgraded table with
    triggers.
      - test result.
  mysql-test/t/mysqlcheck.test
    Fix for
    bug#33094: Error in upgrading from 5.0 to 5.1 when table contains
    triggers
    and
    #41385: Crash when attempting to repair a #mysql50# upgraded table with
    triggers.
      - test case.
  sql/sql_trigger.cc
    Fix for
    bug#33094: Error in upgrading from 5.0 to 5.1 when table contains
    triggers
    and
    #41385: Crash when attempting to repair a #mysql50# upgraded table with
    triggers.
      - checking triggers assume a table name given may have "#mysql50#"
    prefix in some cases.
=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c	2008-11-14 09:48:01 +0000
+++ b/client/mysqlcheck.c	2008-12-19 10:45:19 +0000
@@ -40,15 +40,13 @@ static uint verbose = 0, opt_mysql_port=
 static int my_end_arg;
 static char * opt_mysql_unix_port = 0;
 static char *opt_password = 0, *current_user = 0, 
-	    *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME,
-	    *current_host = 0;
+	    *default_charset= 0, *current_host= 0;
 static int first_error = 0;
 DYNAMIC_ARRAY tables4repair;
 #ifdef HAVE_SMEM
 static char *shared_memory_base_name=0;
 #endif
 static uint opt_protocol=0;
-static CHARSET_INFO *charset_info= &my_charset_latin1;
 
 enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
 
@@ -282,12 +280,10 @@ get_one_option(int optid, const struct m
     break;
   case OPT_FIX_DB_NAMES:
     what_to_do= DO_UPGRADE;
-    default_charset= (char*) "utf8";
     opt_databases= 1;
     break;
   case OPT_FIX_TABLE_NAMES:
     what_to_do= DO_UPGRADE;
-    default_charset= (char*) "utf8";
     break;
   case 'p':
     if (argument)
@@ -367,11 +363,20 @@ static int get_options(int *argc, char *
       what_to_do = DO_CHECK;
   }
 
-  /* TODO: This variable is not yet used */
-  if (strcmp(default_charset, charset_info->csname) &&
-      !(charset_info= get_charset_by_csname(default_charset, 
-  					    MY_CS_PRIMARY, MYF(MY_WME))))
-      exit(1);
+  /*
+    If there's no --default-character-set option given with
+    --fix-table-name or --fix-db-name set the default character set to "utf8".
+  */
+  if (!default_charset && (opt_fix_db_names || opt_fix_table_names))
+  {
+    default_charset= (char*) "utf8";
+  }
+  if (default_charset && !get_charset_by_csname(default_charset, MY_CS_PRIMARY,
+                                                MYF(MY_WME)))
+  {
+    printf("Unsupported character set: %s\n", default_charset);
+    return 1;
+  }
   if (*argc > 0 && opt_alldbs)
   {
     printf("You should give only options, no arguments at all, with option\n");
@@ -779,6 +784,8 @@ static int dbConnect(char *host, char *u
   if (shared_memory_base_name)
     mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 #endif
+  if (default_charset)
+    mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
   if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
          NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
   {

=== modified file 'mysql-test/r/mysqlcheck.result'
--- a/mysql-test/r/mysqlcheck.result	2008-11-14 09:48:01 +0000
+++ b/mysql-test/r/mysqlcheck.result	2008-12-19 10:45:19 +0000
@@ -130,3 +130,27 @@ v1
 v-1
 drop view v1, `v-1`;
 drop table t1;
+SET NAMES utf8;
+CREATE TABLE `#mysql50#@` (a INT);
+SHOW TABLES;
+Tables_in_test
+#mysql50#@
+SET NAMES DEFAULT;
+mysqlcheck --fix-table-names --databases test
+SET NAMES utf8;
+SHOW TABLES;
+Tables_in_test
+@
+DROP TABLE `@`;
+CREATE TABLE `я` (a INT);
+SET NAMES DEFAULT;
+mysqlcheck --default-character-set="latin1" --databases test
+test.?
+Error    : Table 'test.?' doesn't exist
+error    : Corrupt
+mysqlcheck --default-character-set="utf8" --databases test
+test.я                                            OK
+SET NAMES utf8;
+DROP TABLE `я`;
+SET NAMES DEFAULT;
+End of 5.1 tests

=== modified file 'mysql-test/t/mysqlcheck.test'
--- a/mysql-test/t/mysqlcheck.test	2008-11-14 09:48:01 +0000
+++ b/mysql-test/t/mysqlcheck.test	2008-12-19 10:45:19 +0000
@@ -112,3 +112,30 @@ show tables;
 show tables;
 drop view v1, `v-1`;
 drop table t1;
+
+#
+# Bug #33094: Error in upgrading from 5.0 to 5.1 when table contains triggers
+# Bug #41385: Crash when attempting to repair a #mysql50# upgraded table with
+#             triggers
+#
+SET NAMES utf8;
+CREATE TABLE `#mysql50#@` (a INT);
+SHOW TABLES;
+SET NAMES DEFAULT;
+--echo mysqlcheck --fix-table-names --databases test
+--exec $MYSQL_CHECK --fix-table-names --databases test
+SET NAMES utf8;
+SHOW TABLES;
+DROP TABLE `@`;
+
+CREATE TABLE `я` (a INT);
+SET NAMES DEFAULT;
+--echo mysqlcheck --default-character-set="latin1" --databases test
+--exec $MYSQL_CHECK --default-character-set="latin1" --databases test
+--echo mysqlcheck --default-character-set="utf8" --databases test
+--exec $MYSQL_CHECK --default-character-set="utf8" --databases test
+SET NAMES utf8;
+DROP TABLE `я`;
+SET NAMES DEFAULT;
+
+--echo End of 5.1 tests

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2008-11-14 17:37:27 +0000
+++ b/sql/sql_trigger.cc	2008-12-19 10:45:19 +0000
@@ -1368,15 +1368,23 @@ bool Table_triggers_list::check_n_load(T
 
         if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root))
           goto err_with_lex_cleanup;
-
+#ifndef DBUG_OFF
         /*
           Let us check that we correctly update trigger definitions when we
           rename tables with triggers.
+          
+          There's a special case when given a table name with "#mysql50#" prefix
+          (e.g. processing "RENAME TABLE #mysql50#somename TO somename"),
+          we have to take it away, a tablename_to_filename() call does the trick.
         */
-        DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) &&
-                    !my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
-                                   table_name));
 
+        char fname[NAME_LEN + 1];
+        DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) &&
+                    (!my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
+                                    table_name) ||
+                     (tablename_to_filename(table_name, fname, sizeof(fname)) &&
+                      !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, fname))));
+#endif
         if (names_only)
         {
           lex_end(&lex);

Thread
bzr commit into mysql-5.1-bugteam branch (ramil:2765) Bug#33094Ramil Kalimullin19 Dec
  • Re: bzr commit into mysql-5.1-bugteam branch (ramil:2765) Bug#33094Dmitry Lenev12 Jan 2009