summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_sys.h1
-rw-r--r--myisammrg/myrg_open.c2
-rw-r--r--mysys/my_getwd.c22
-rw-r--r--sql/ha_myisammrg.cc28
4 files changed, 48 insertions, 5 deletions
diff --git a/include/my_sys.h b/include/my_sys.h
index b54e2581bd4..7ead643a9c6 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -609,6 +609,7 @@ extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name);
+extern my_bool has_path(const char *name);
extern char *convert_dirname(char *to, const char *from, const char *from_end);
extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name);
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index a59ccb7d966..0dc2f4f9768 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -80,7 +80,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
continue; /* Skip comments */
}
- if (!test_if_hard_path(buff))
+ if (!has_path(buff))
{
VOID(strmake(name_buff+dir_length,buff,
sizeof(name_buff)-1-dir_length));
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index d6f647254e8..89f949eca27 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -192,3 +192,25 @@ int test_if_hard_path(register const char *dir_name)
return FALSE;
#endif
} /* test_if_hard_path */
+
+
+/*
+ Test if a name contains an (absolute or relative) path.
+
+ SYNOPSIS
+ has_path()
+ name The name to test.
+
+ RETURN
+ TRUE name contains a path.
+ FALSE name does not contain a path.
+*/
+
+my_bool has_path(const char *name)
+{
+ return test(strchr(name, FN_LIBCHAR))
+#ifdef FN_DEVCHAR
+ || test(strchr(name, FN_DEVCHAR))
+#endif
+ ;
+}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index bf47b4625e0..7a5d4fcf0a1 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -381,6 +381,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
char buff[FN_REFLEN],**table_names,**pos;
TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
THD *thd= current_thd;
+ uint dirlgt= dirname_length(name);
DBUG_ENTER("ha_myisammrg::create");
if (!(table_names= (char**) thd->alloc((create_info->merge_list.elements+1)*
@@ -394,11 +395,30 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
tbl= find_temporary_table(thd, tables->db, tables->real_name);
if (!tbl)
{
- uint length= my_snprintf(buff,FN_REFLEN,"%s%s/%s",
- mysql_real_data_home,
+ /*
+ Construct the path to the MyISAM table. Try to meet two conditions:
+ 1.) Allow to include MyISAM tables from different databases, and
+ 2.) allow for moving DATADIR around in the file system.
+ The first means that we need paths in the .MRG file. The second
+ means that we should not have absolute paths in the .MRG file.
+ The best, we can do, is to use 'mysql_data_home', which is '.'
+ in mysqld and may be an absolute path in an embedded server.
+ This means that it might not be possible to move the DATADIR of
+ an embedded server without changing the paths in the .MRG file.
+ */
+ uint length= my_snprintf(buff, FN_REFLEN, "%s/%s/%s", mysql_data_home,
tables->db, tables->real_name);
- if (!(table_name= thd->strmake(buff, length)))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ /*
+ If a MyISAM table is in the same directory as the MERGE table,
+ we use the table name without a path. This means that the
+ DATADIR can easily be moved even for an embedded server as long
+ as the MyISAM tables are from the same database as the MERGE table.
+ */
+ if ((dirname_length(buff) == dirlgt) && ! memcmp(buff, name, dirlgt))
+ table_name= tables->real_name;
+ else
+ if (! (table_name= thd->strmake(buff, length)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
else
table_name=(*tbl)->path;