diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2022-10-13 22:24:27 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2022-10-14 20:11:03 +0300 |
commit | c64fbbf1603274606c03d4ecfd55f5cabfdc50a4 (patch) | |
tree | 75fcfc27b59c9390014b0bd668c3898479360fbd | |
parent | 4511e7e462d941631a3eacb0d005b93b4a7a01bd (diff) | |
download | mariadb-git-c64fbbf1603274606c03d4ecfd55f5cabfdc50a4.tar.gz |
MDEV-29787 CREATE OR REPLACE does not work with custom DATA/INDEX DIRECTORY
When data_file_name and/or index_file_name setting is defined we must
update it for atomic C-O-R. The first update for any CREATE TABLE is in
Sql_cmd_create_table_like::execute(THD *thd):
/* Fix names if symlinked or relocated tables */
if (append_file_to_dir(thd, &create_info.data_file_name,
&create_table->table_name) ||
append_file_to_dir(thd, &create_info.index_file_name,
&create_table->table_name))
goto end_with_restore_list;
At the beginning of "if" data_file_name/index_file_name contain
directory path (or NULL). Then we add table_name to it.
In the second update in make_tmp_table_list() (which is done for
atomic C-O-R only) we return data_file_name/index_file_name back to
directory state and then append temporary table name.
-rw-r--r-- | mysql-test/main/create_or_replace.result | 26 | ||||
-rw-r--r-- | mysql-test/main/create_or_replace.test | 27 | ||||
-rw-r--r-- | sql/sql_table.cc | 17 |
3 files changed, 67 insertions, 3 deletions
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 4f762ac2fb9..542db523968 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -938,3 +938,29 @@ create table t (a int) engine=myisam; create temporary table tm (a int) engine=merge union=(t); create or replace table tt like tm; drop tables tt, tm, t; +# +# MDEV-29787 CREATE OR REPLACE does not work with custom DATA/INDEX DIRECTORY +# +create table t1 (a int) engine=MyISAM +data directory 'MYSQL_TMP_DIR' +index directory 'MYSQL_TMP_DIR'; +MYSQLD_DATADIR/test: +t1.MYD +t1.MYI +t1.frm +MYSQL_TMP_DIR: +t1.MYD +t1.MYI +create or replace table t1 (b int) engine=MyISAM +data directory 'MYSQL_TMP_DIR' +index directory 'MYSQL_TMP_DIR'; +MYSQLD_DATADIR/test: +t1.MYD +t1.MYI +t1.frm +MYSQL_TMP_DIR: +t1.MYD +t1.MYI +drop table t1; +MYSQLD_DATADIR/test: +MYSQL_TMP_DIR: diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 6f62ddc588b..dc75b72bb9b 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -730,3 +730,30 @@ create table t (a int) engine=myisam; create temporary table tm (a int) engine=merge union=(t); create or replace table tt like tm; drop tables tt, tm, t; + +--echo # +--echo # MDEV-29787 CREATE OR REPLACE does not work with custom DATA/INDEX DIRECTORY +--echo # +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval create table t1 (a int) engine=MyISAM +data directory '$MYSQL_TMP_DIR' +index directory '$MYSQL_TMP_DIR'; +--echo MYSQLD_DATADIR/test: +--list_files $MYSQLD_DATADIR/test *t1* +--echo MYSQL_TMP_DIR: +--list_files $MYSQL_TMP_DIR *t1* +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval create or replace table t1 (b int) engine=MyISAM +data directory '$MYSQL_TMP_DIR' +index directory '$MYSQL_TMP_DIR'; +--echo MYSQLD_DATADIR/test: +--list_files $MYSQLD_DATADIR/test *t1* +--echo MYSQL_TMP_DIR: +--list_files $MYSQL_TMP_DIR *t1* +# Cleanup +drop table t1; +--echo MYSQLD_DATADIR/test: +--list_files $MYSQLD_DATADIR/test *t1* +--echo MYSQL_TMP_DIR: +--list_files $MYSQL_TMP_DIR *t1* diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ca887aa875d..015960bdc47 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1298,13 +1298,24 @@ bool HA_CREATE_INFO::make_tmp_table_list(THD *thd, TABLE_LIST **create_table, if (make_tmp_name(thd, "create", *create_table, &tmp_name) || make_tmp_name(thd, "backup", *create_table, &backup_name) || !(new_table= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST)))) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); return true; - } (*create_table_mode)|= C_ALTER_TABLE; DBUG_ASSERT(!(options & HA_CREATE_TMP_ALTER)); options|= HA_CREATE_TMP_ALTER; + if (data_file_name) + { + size_t dir_len= strlen(data_file_name) - (*create_table)->table_name.length; + const_cast<char *>(data_file_name)[dir_len]= 0; + if (append_file_to_dir(thd, &data_file_name, &tmp_name.table_name)) + return true; + } + if (index_file_name) + { + size_t dir_len= strlen(index_file_name) - (*create_table)->table_name.length; + const_cast<char *>(index_file_name)[dir_len]= 0; + if (append_file_to_dir(thd, &index_file_name, &tmp_name.table_name)) + return true; + } new_table->init_one_table(&tmp_name.db, &tmp_name.table_name, &tmp_name.alias, (*create_table)->lock_type); *create_table= new_table; |