#At file:///home2/mydev/bzrroot/mysql-6.0-backup-merge/
2662 Ingo Struewing 2008-07-14
Bug#38045 - Backup, MyISAM and file system encoding
Table names with non-ASCII characters could not be backed up.
The MyISAM native backup driver used the original, non-translated table name.
Fixed by using the translated name.
modified:
mysql-test/r/backup_myisam2.result
mysql-test/t/backup_myisam2.test
storage/myisam/myisam_backup_engine.cc
per-file messages:
mysql-test/r/backup_myisam2.result
Bug#38045 - Backup, MyISAM and file system encoding
Added test result.
mysql-test/t/backup_myisam2.test
Bug#38045 - Backup, MyISAM and file system encoding
Added test.
storage/myisam/myisam_backup_engine.cc
Using translated table names.
Simplified string copy.
Added error detection for string copy.
=== modified file 'mysql-test/r/backup_myisam2.result'
--- a/mysql-test/r/backup_myisam2.result 2008-07-02 07:53:34 +0000
+++ b/mysql-test/r/backup_myisam2.result 2008-07-14 15:33:03 +0000
@@ -56,6 +56,18 @@ Table Checksum
mysqltest.t1 1728069308
connection default: cleanup
+SET DEBUG_SYNC= 'RESET';
+
+#
+# Bug#38045 - Backup, MyISAM and file system encoding
+#
+CREATE TABLE `äöüߣå` (id SERIAL) ENGINE=MyISAM;
+BACKUP DATABASE mysqltest TO 'test.ba';
+backup_id
+#
+DROP TABLE `äöüߣå`;
+
+# final cleanup
USE test;
DROP DATABASE mysqltest;
SET DEBUG_SYNC= 'RESET';
=== modified file 'mysql-test/t/backup_myisam2.test'
--- a/mysql-test/t/backup_myisam2.test 2008-07-02 07:53:34 +0000
+++ b/mysql-test/t/backup_myisam2.test 2008-07-14 15:33:03 +0000
@@ -75,14 +75,30 @@ SET DEBUG_SYNC= 'now SIGNAL bup_finish';
disconnect backup;
+--echo
+--echo connection default: cleanup
+connection default;
+--remove_file $MYSQLTEST_VARDIR/master-data/test.ba
+SET DEBUG_SYNC= 'RESET';
+
+
+--echo
+--echo #
+--echo # Bug#38045 - Backup, MyISAM and file system encoding
+--echo #
+CREATE TABLE `äöüߣå` (id SERIAL) ENGINE=MyISAM;
+--replace_column 1 #
+BACKUP DATABASE mysqltest TO 'test.ba';
+DROP TABLE `ätest.ba
+
+
#
# Cleanup from this test case
#
--echo
---echo connection default: cleanup
-connection default;
+--echo # final cleanup
USE test;
DROP DATABASE mysqltest;
---remove_file $MYSQLTEST_VARDIR/master-data/test.ba
SET DEBUG_SYNC= 'RESET';
=== modified file 'storage/myisam/myisam_backup_engine.cc'
--- a/storage/myisam/myisam_backup_engine.cc 2008-07-08 20:18:10 +0000
+++ b/storage/myisam/myisam_backup_engine.cc 2008-07-14 15:33:03 +0000
@@ -131,8 +131,9 @@ protected:
Myisam_table_ref::Myisam_table_ref(const Table_ref &tbl)
{
- const char *db_arg= tbl.db().name().ptr();
- const char *name_arg= tbl.name().ptr();
+ int error= 0;
+ char path[FN_REFLEN];
+
/**
We keep local copies of the db and name. This is because during restore,
the Table_ref is apparently modified before the Table_restore is done
@@ -143,22 +144,28 @@ Myisam_table_ref::Myisam_table_ref(const
and this will save memory.
As Rafal is changing relevant code now, it may go away.
*/
- db.append(db_arg);
- name.append(name_arg);
+ if (db.append(tbl.db().name()))
+ error= 1;
+ if (name.append(tbl.name()))
+ error= 1;
+ /*
+ Note: when we repair the table, we use open_temporary_table() which
+ requires db and table name separated. The internal_name is the
+ translated table name with ASCII characters only.
+ */
+ (void) tbl.internal_name(path, sizeof(path));
+ if (file_name.append(path))
+ error= 1;
/*
- Note: this way below will break with non-ASCII characters;
- what driver should be passed is what engine used to create the table, ie
- output of build_table_filename().
- Just replace "building" with "bûilding" in backup.test to see issues.
- This is remembered in WL#4060.
-
- But note, when we repair the table, we use open_temporary_table() which
- requires db and table name separated.
- */
- file_name.append("./");
- file_name.append(db_arg);
- file_name.append("/");
- file_name.append(name_arg);
+ If one of the string allocations failed, clear all. This should be
+ noticed later, when we try to use the information.
+ */
+ if (error)
+ {
+ db.set("", 0, system_charset_info);
+ name.set("", 0, system_charset_info);
+ file_name.set("", 0, system_charset_info);
+ }
}
@@ -538,15 +545,20 @@ result_t Backup::begin(const size_t)
/* Build the hash of tables for the MyISAM layer (mi_backup_log.c etc) */
for (uint n=0 ; n < m_tables.count() ; n++ )
{
+ char path[FN_REFLEN];
char unique_file_name[FN_REFLEN], *str;
size_t str_len;
::LEX_STRING *hash_key;
- my_realpath(unique_file_name,
- fn_format(unique_file_name,m_tables[n].name().ptr(),
- m_tables[n].db().name().ptr(),
- MI_NAME_IEXT,
- MY_UNPACK_FILENAME), MYF(MY_WME));
+ /*
+ The internal_name is the translated table name with ASCII
+ characters only.
+ */
+ (void) m_tables[n].internal_name(path, sizeof(path));
+ if (my_realpath(unique_file_name,
+ fn_format(unique_file_name, path, "", MI_NAME_IEXT,
+ MY_UNPACK_FILENAME), MYF(MY_WME)))
+ SET_STATE_TO_ERROR_AND_DBUG_RETURN;
str_len= strlen(unique_file_name);
my_multi_malloc(MYF(MY_WME),
&hash_key, sizeof(*hash_key),