summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-10-13 22:24:27 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-10-14 20:11:03 +0300
commitc64fbbf1603274606c03d4ecfd55f5cabfdc50a4 (patch)
tree75fcfc27b59c9390014b0bd668c3898479360fbd
parent4511e7e462d941631a3eacb0d005b93b4a7a01bd (diff)
downloadmariadb-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.result26
-rw-r--r--mysql-test/main/create_or_replace.test27
-rw-r--r--sql/sql_table.cc17
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;