summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h1
-rw-r--r--myisam/mi_create.c6
-rw-r--r--mysql-test/r/create.result17
-rw-r--r--mysql-test/t/create.test31
-rw-r--r--sql/ha_myisam.cc2
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/unireg.cc2
9 files changed, 66 insertions, 2 deletions
diff --git a/include/my_base.h b/include/my_base.h
index d07a4de8e6a..d8732808cee 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -279,6 +279,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
/*
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index ea1d8c7b83e..dd8a5b0d525 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -586,7 +586,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
32 : 0));
linkname_ptr=0;
/* Replace the current file */
- create_flag=MY_DELETE_OLD;
+ if (!(flags & HA_CREATE_KEEP_FILES))
+ create_flag=MY_DELETE_OLD;
}
/*
@@ -647,7 +648,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
fn_format(filename,name,"",MI_NAME_DEXT,4);
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,
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index e692dbf3938..16bc534ba92 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1503,4 +1503,21 @@ 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
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 99f3fea416a..610a208ebf0 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1118,5 +1118,36 @@ 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/ha_myisam.cc b/sql/ha_myisam.cc
index 5e953092436..4efa19bad78 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -1809,6 +1809,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/sql/set_var.cc b/sql/set_var.cc
index 09cdc34f803..b30aa008366 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -592,6 +592,10 @@ sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
/* Global read-only variable containing hostname */
sys_var_const_str sys_hostname("hostname", glob_hostname);
+sys_var_thd_bool sys_keep_files_on_create("keep_files_on_create",
+ &SV::keep_files_on_create);
+
+
/*
@@ -637,6 +641,7 @@ sys_var *sys_variables[]=
&sys_delayed_insert_limit,
&sys_delayed_insert_timeout,
&sys_delayed_queue_size,
+ &sys_keep_files_on_create,
&sys_error_count,
&sys_expire_logs_days,
&sys_flush,
@@ -849,6 +854,7 @@ struct show_var_st init_vars[]= {
{sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
{sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS},
{sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
+ {sys_keep_files_on_create.name,(char*) &sys_keep_files_on_create, SHOW_SYS},
{sys_engine_condition_pushdown.name,
(char*) &sys_engine_condition_pushdown, SHOW_SYS},
{sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a5cbc21684f..112538cbe95 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -566,6 +566,7 @@ struct system_variables
my_bool new_mode;
my_bool query_cache_wlock_invalidate;
my_bool engine_condition_pushdown;
+ my_bool keep_files_on_create;
#ifdef HAVE_INNOBASE_DB
my_bool innodb_table_locks;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 87f23097a66..e02595836ca 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2841,6 +2841,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table,
and temporary tables).
*/
*fn_ext(dst_path)= 0;
+ if (thd->variables.keep_files_on_create)
+ create_info->options|= HA_CREATE_KEEP_FILES;
err= ha_create_table(dst_path, create_info, 1);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
diff --git a/sql/unireg.cc b/sql/unireg.cc
index c01e6a0f00c..d8e63bb78e1 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -285,6 +285,8 @@ int rea_create_table(THD *thd, my_string file_name,
if (mysql_create_frm(thd, file_name, db, table, create_info,
create_fields, keys, key_info, NULL))
DBUG_RETURN(1);
+ if (thd->variables.keep_files_on_create)
+ create_info->options|= HA_CREATE_KEEP_FILES;
if (!create_info->frm_only && ha_create_table(file_name,create_info,0))
{
my_delete(file_name,MYF(0));