summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h1
-rw-r--r--mysql-test/r/create.result17
-rw-r--r--mysql-test/t/create.test31
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/unireg.cc2
-rw-r--r--storage/myisam/ha_myisam.cc2
-rw-r--r--storage/myisam/mi_create.c6
9 files changed, 63 insertions, 2 deletions
diff --git a/include/my_base.h b/include/my_base.h
index bbc0c0f1f5c..04127b81b78 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -299,6 +299,7 @@ enum ha_base_keytype {
#define HA_PACK_RECORD 2 /* Request packed record format */
#define HA_CREATE_TMP_TABLE 4
#define HA_CREATE_CHECKSUM 8
+#define HA_CREATE_KEEP_FILES 16 /* don't overwrite .MYD and MYI */
#define HA_CREATE_DELAY_KEY_WRITE 64
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index cdbb767dd9f..67b1fbae848 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1516,6 +1516,23 @@ t1 CREATE TABLE `t1` (
`c17` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+USE db2;
+INSERT INTO db2.t1 VALUES (1);
+SELECT * FROM db2.t1;
+b
+1
+RESET QUERY CACHE;
+USE db1;
+SET SESSION keep_files_on_create = TRUE;
+CREATE TABLE t1 (a INT) ENGINE MYISAM;
+ERROR HY000: Can't create/write to file './db1/t1.MYD' (Errcode: 17)
+SET SESSION keep_files_on_create = DEFAULT;
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
+USE test;
End of 5.0 tests
CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2);
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index dd3037ce88d..3727cbc30e2 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1122,6 +1122,37 @@ show create table t1;
drop table t1;
+#
+# Bug #29325: create table overwrites .MYD file of other table (datadir)
+#
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+
+USE db2;
+--disable_query_log
+eval CREATE TABLE t1 (b INT) ENGINE MYISAM
+DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/db1/';
+--enable_query_log
+
+INSERT INTO db2.t1 VALUES (1);
+SELECT * FROM db2.t1;
+RESET QUERY CACHE;
+
+USE db1;
+
+#no warning from create table
+SET SESSION keep_files_on_create = TRUE;
+--disable_abort_on_error
+CREATE TABLE t1 (a INT) ENGINE MYISAM;
+--enable_abort_on_error
+SET SESSION keep_files_on_create = DEFAULT;
+
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
+USE test;
+
--echo End of 5.0 tests
diff --git a/sql/set_var.cc b/sql/set_var.cc
index d9869ce6809..bd5234b42be 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -616,6 +616,8 @@ sys_var_thd_time_zone sys_time_zone(&vars, "time_zone");
/* Global read-only variable containing hostname */
static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
+sys_var_thd_bool sys_keep_files_on_create(&vars, "keep_files_on_create",
+ &SV::keep_files_on_create);
/* Read only variables */
static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 292c6776e9a..e436fcd1494 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -305,6 +305,7 @@ struct system_variables
my_bool old_mode;
my_bool query_cache_wlock_invalidate;
my_bool engine_condition_pushdown;
+ my_bool keep_files_on_create;
my_bool ndb_force_send;
my_bool ndb_use_copying_alter_table;
my_bool ndb_use_exact_count;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 047c210d6a5..7f18d8e6dd2 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4697,8 +4697,11 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
+ if (thd->variables.keep_files_on_create)
+ create_info->options|= HA_CREATE_KEEP_FILES;
err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
VOID(pthread_mutex_unlock(&LOCK_open));
+
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 57847bc70c6..f9e8e54439a 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -355,6 +355,8 @@ int rea_create_table(THD *thd, const char *path,
// Make sure mysql_create_frm din't remove extension
DBUG_ASSERT(*fn_rext(frm_name));
+ if (thd->variables.keep_files_on_create)
+ create_info->options|= HA_CREATE_KEEP_FILES;
if (file->create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
goto err_handler;
if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 98f74247707..3614166e97c 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -1889,6 +1889,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= HA_CREATE_TMP_TABLE;
+ if (ha_create_info->options & HA_CREATE_KEEP_FILES)
+ create_flags|= HA_CREATE_KEEP_FILES;
if (options & HA_OPTION_PACK_RECORD)
create_flags|= HA_PACK_RECORD;
if (options & HA_OPTION_CHECKSUM)
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index c177aa8d987..0bea1975f61 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -615,7 +615,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
linkname_ptr=0;
/* Replace the current file */
- create_flag=MY_DELETE_OLD;
+ if (!(flags & HA_CREATE_KEEP_FILES))
+ create_flag=MY_DELETE_OLD;
}
/*
@@ -689,7 +690,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
fn_format(filename,name,"", MI_NAME_DEXT,
MY_UNPACK_FILENAME | MY_APPEND_EXT);
linkname_ptr=0;
- create_flag=MY_DELETE_OLD;
+ if (!(flags & HA_CREATE_KEEP_FILES))
+ create_flag=MY_DELETE_OLD;
}
if ((dfile=
my_create_with_symlink(linkname_ptr, filename, 0, create_mode,