summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2001-06-01 04:27:59 +0300
committerunknown <monty@hundin.mysql.fi>2001-06-01 04:27:59 +0300
commite59d0778ecfb52f367d2bde43542dcde6a9c4aa1 (patch)
treeffdc7daed643167b8c8097cf1b60e75151d39eb9
parentef678c6ab4b1dbbb47b558e4fc1594cdd2a74f69 (diff)
downloadmariadb-git-e59d0778ecfb52f367d2bde43542dcde6a9c4aa1.tar.gz
Added support for symlinked tables.
myisamchk: Don't force a repair if the only problem was that the open count wasn't correct. Added missing error messages. include/my_sys.h: Cleanup comments libmysql/Makefile.shared: Added symlink library. myisam/mi_check.c: Added support for symlinked tables myisam/mi_delete_table.c: Added support for symlinked tables myisam/mi_open.c: Added support for symlinked tables myisam/mi_rename.c: Added support for symlinked tables myisam/myisamchk.c: Added support for symlinked tables. Don't force a repair if the only problem was that the open count wasn't correct. pstack/bucomm.c: use mkstemp() instead of mytemp() sql/ha_myisam.cc: Added support for symlinked tables sql/ha_myisam.h: Added support for symlinked tables sql/ha_myisammrg.cc: Added support for symlinked tables sql/handler.cc: Added support for symlinked tables sql/handler.h: Added support for symlinked tables sql/lex.h: Added support for symlinked tables sql/share/czech/errmsg.txt: Added missing error messages sql/share/danish/errmsg.txt: Added missing error messages sql/share/dutch/errmsg.txt: Added missing error messages sql/share/estonian/errmsg.txt: Added missing error messages sql/share/french/errmsg.txt: Added missing error messages sql/share/german/errmsg.txt: Added missing error messages sql/share/greek/errmsg.txt: Added missing error messages sql/share/hungarian/errmsg.txt: Added missing error messages sql/share/italian/errmsg.txt: Added missing error messages sql/share/japanese/errmsg.txt: Added missing error messages sql/share/korean/errmsg.txt: Added missing error messages sql/share/norwegian-ny/errmsg.txt: Added missing error messages sql/share/norwegian/errmsg.txt: Added missing error messages sql/share/polish/errmsg.txt: Added missing error messages sql/share/portuguese/errmsg.txt: Added missing error messages sql/share/romanian/errmsg.txt: Added missing error messages sql/share/russian/errmsg.txt: Added missing error messages sql/share/slovak/errmsg.txt: Added missing error messages sql/share/spanish/errmsg.txt: Added missing error messages sql/share/swedish/errmsg.OLD: Added missing error messages sql/share/swedish/errmsg.txt: Added missing error messages sql/sql_db.cc: Added support for symlinked tables sql/sql_parse.cc: Added support for symlinked tables sql/sql_table.cc: Added support for symlinked tables with ALTER TABLE sql/sql_yacc.yy: Added option to create symlinked tables.
-rw-r--r--include/my_sys.h5
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--myisam/mi_check.c35
-rw-r--r--myisam/mi_delete_table.c4
-rw-r--r--myisam/mi_open.c6
-rw-r--r--myisam/mi_rename.c4
-rw-r--r--myisam/myisamchk.c24
-rw-r--r--pstack/bucomm.c2
-rw-r--r--sql/ha_myisam.cc19
-rw-r--r--sql/ha_myisam.h1
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h1
-rw-r--r--sql/lex.h1
-rw-r--r--sql/share/czech/errmsg.txt2
-rw-r--r--sql/share/danish/errmsg.txt2
-rw-r--r--sql/share/dutch/errmsg.txt2
-rw-r--r--sql/share/estonian/errmsg.txt2
-rw-r--r--sql/share/french/errmsg.txt2
-rw-r--r--sql/share/german/errmsg.txt2
-rw-r--r--sql/share/greek/errmsg.txt2
-rw-r--r--sql/share/hungarian/errmsg.txt2
-rw-r--r--sql/share/italian/errmsg.txt2
-rw-r--r--sql/share/japanese/errmsg.txt2
-rw-r--r--sql/share/korean/errmsg.txt2
-rw-r--r--sql/share/norwegian-ny/errmsg.txt2
-rw-r--r--sql/share/norwegian/errmsg.txt2
-rw-r--r--sql/share/polish/errmsg.txt2
-rw-r--r--sql/share/portuguese/errmsg.txt2
-rw-r--r--sql/share/romanian/errmsg.txt2
-rw-r--r--sql/share/russian/errmsg.txt2
-rw-r--r--sql/share/slovak/errmsg.txt2
-rw-r--r--sql/share/spanish/errmsg.txt2
-rw-r--r--sql/share/swedish/errmsg.OLD5
-rw-r--r--sql/share/swedish/errmsg.txt8
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_parse.cc39
-rw-r--r--sql/sql_table.cc53
-rw-r--r--sql/sql_yacc.yy6
39 files changed, 214 insertions, 47 deletions
diff --git a/include/my_sys.h b/include/my_sys.h
index dc4eff7bda5..489015d42e2 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -110,10 +110,7 @@ extern int NEAR my_errno; /* Last error in mysys */
/* root_alloc flags */
#define MY_KEEP_PREALLOC 1
-#define MY_MARK_BLOCKS_FREE 2 /* do not my_free() blocks,
- just move used into free list
- and mark all blocks as fully free
- */
+#define MY_MARK_BLOCKS_FREE 2 /* move used to free list and reuse them */
/* defines when allocating data */
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 7b220e12346..3bb73b87aab 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -54,7 +54,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
mf_format.lo mf_path.lo mf_unixpath.lo my_fopen.lo \
- my_fstream.lo \
+ my_symlink.lo my_fstream.lo \
mf_loadpath.lo my_pthread.lo my_thr_init.lo \
thr_mutex.lo mulalloc.lo string.lo default.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 75bc7aa876c..0aa9081e996 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -1130,7 +1130,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ /* Get real path for data file */
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
DATA_TMP_EXT,
2+4),
0,param->tmpfile_createflag,
@@ -1476,8 +1479,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (!(param->testflag & T_SILENT))
printf("- Sorting index for MyISAM-table '%s'\n",name);
- if ((new_file=my_create(fn_format(param->temp_filename,name,"",
- INDEX_TMP_EXT,2+4),
+ /* Get real path for index file */
+ fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32);
+ if ((new_file=my_create(fn_format(param->temp_filename,param->temp_filename,
+ "", INDEX_TMP_EXT,2+4),
0,param->tmpfile_createflag,MYF(0))) <= 0)
{
mi_check_print_error(param,"Can't create new tempfile: '%s'",
@@ -1497,7 +1502,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (share->state.key_root[key] != HA_OFFSET_ERROR)
{
- index_pos[key]=param->new_file_pos; /* Write first block here */
+ index_pos[key]=param->new_file_pos; /* Write first block here */
if (sort_one_index(param,info,keyinfo,share->state.key_root[key],
new_file))
goto err;
@@ -1618,9 +1623,14 @@ err:
} /* sort_one_index */
- /* Change to use new file */
- /* Copy stats from old file to new file, deletes orginal and */
- /* changes new file name to old file name */
+ /*
+ Let temporary file replace old file.
+ This assumes that the new file was created in the same
+ directory as given by realpath(filename).
+ This will ensure that any symlinks that are used will still work.
+ Copy stats from old file to new file, deletes orignal and
+ changes new file name to old file name
+ */
int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext,
@@ -1635,8 +1645,10 @@ int change_to_newfile(const char * filename, const char * old_ext,
raid_chunks,
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
#endif
- return my_redel(fn_format(old_filename,filename,"",old_ext,2+4),
- fn_format(new_filename,filename,"",new_ext,2+4),
+ /* Get real path to filename */
+ (void) fn_format(old_filename,filename,"",old_ext,2+4+32);
+ return my_redel(old_filename,
+ fn_format(new_filename,old_filename,"",new_ext,2+4),
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
} /* change_to_newfile */
@@ -1753,7 +1765,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
}
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ /* Get real path for data file */
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename, "",
DATA_TMP_EXT,
2+4),
0,param->tmpfile_createflag,
diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c
index 995106160ef..d8fff51acb6 100644
--- a/myisam/mi_delete_table.c
+++ b/myisam/mi_delete_table.c
@@ -50,12 +50,12 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,4);
- if (my_delete(from, MYF(MY_WME)))
+ if (my_delete_with_symlink(from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,name,"",MI_NAME_DEXT,4);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif
- DBUG_RETURN(my_delete(from, MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 3ecc1cb8475..da4a6aff6fb 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -132,10 +132,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
/* Don't call realpath() if the name can't be a link */
if (strcmp(name_buff, org_name))
- my_readlink(index_name, org_name, MYF(0));
+ (void) my_readlink(index_name, org_name, MYF(0));
else
- strmov(index_name, org_name);
- fn_format(data_name,org_name,"",MI_NAME_DEXT,4+16);
+ (void) strmov(index_name, org_name);
+ (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16);
info_length=mi_uint2korr(share->state.header.header_length);
base_pos=mi_uint2korr(share->state.header.base_pos);
diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c
index 5c92db3f7ce..4d6250f58f4 100644
--- a/myisam/mi_rename.c
+++ b/myisam/mi_rename.c
@@ -51,7 +51,7 @@ int mi_rename(const char *old_name, const char *new_name)
fn_format(from,old_name,"",MI_NAME_IEXT,4);
fn_format(to,new_name,"",MI_NAME_IEXT,4);
- if (my_rename(from, to, MYF(MY_WME)))
+ if (my_rename_with_symlink(from, to, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,old_name,"",MI_NAME_DEXT,4);
fn_format(to,new_name,"",MI_NAME_DEXT,4);
@@ -60,5 +60,5 @@ int mi_rename(const char *old_name, const char *new_name)
DBUG_RETURN(my_raid_rename(from, to, raid_chunks, MYF(MY_WME)) ? my_errno :
0);
#endif
- DBUG_RETURN(my_rename(from, to,MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_rename_with_symlink(from, to,MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index c2f67c64e48..4a27bef57d1 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -498,7 +498,6 @@ static int myisamchk(MI_CHECK *param, my_string filename)
uint raid_chunks;
MI_INFO *info;
File datafile;
- char fixed_name[FN_REFLEN];
char llbuff[22],llbuff2[22];
my_bool state_updated=0;
MYISAM_SHARE *share;
@@ -675,9 +674,6 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
- VOID(fn_format(fixed_name,filename,"",MI_NAME_IEXT,
- 4+ (param->opt_follow_links ? 32 : 0)));
-
if (rep_quick && chk_del(&check_param, info,
param->testflag & ~T_VERBOSE))
{
@@ -702,11 +698,11 @@ static int myisamchk(MI_CHECK *param, my_string filename)
info->s->state.key_map,
check_param.force_sort))
{
- error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
+ error=mi_repair_by_sort(&check_param,info,filename,rep_quick);
state_updated=1;
}
else if (param->testflag & (T_REP | T_REP_BY_SORT))
- error=mi_repair(&check_param, info,fixed_name,rep_quick);
+ error=mi_repair(&check_param, info,filename,rep_quick);
}
if (!error && param->testflag & T_SORT_RECORDS)
{
@@ -718,7 +714,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (param->out_flag & O_NEW_DATA)
{ /* Change temp file to org file */
VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
MYF(0));
if (mi_open_datafile(info,info->s))
@@ -739,7 +735,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (share->keyinfo[key].flag & HA_BINARY_PACK_KEY)
update_index=0;
- error=mi_sort_records(param,info,fixed_name,param->opt_sort_key,
+ error=mi_sort_records(param,info,filename,param->opt_sort_key,
(my_bool) !(param->testflag & T_REP),
update_index);
datafile=info->dfile; /* This is now locked */
@@ -747,12 +743,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
{
if (check_param.verbose)
puts("Table had a compressed index; We must now recreate the index");
- error=mi_repair_by_sort(&check_param,info,fixed_name,1);
+ error=mi_repair_by_sort(&check_param,info,filename,1);
}
}
}
if (!error && param->testflag & T_SORT_INDEX)
- error=mi_sort_index(param,info,fixed_name);
+ error=mi_sort_index(param,info,filename);
if (!error)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR);
@@ -849,12 +845,12 @@ end2:
if (error == 0)
{
if (param->out_flag & O_NEW_DATA)
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
((param->testflag & T_BACKUP_DATA) ?
MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
if (param->out_flag & O_NEW_INDEX)
- error|=change_to_newfile(fixed_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
+ error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0));
}
VOID(fflush(stdout)); VOID(fflush(stderr));
@@ -1212,7 +1208,9 @@ static int mi_sort_records(MI_CHECK *param,
mi_check_print_error(param,"Not enough memory for record");
goto err;
}
- new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
DATA_TMP_EXT,2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
diff --git a/pstack/bucomm.c b/pstack/bucomm.c
index 6c491d80bb5..d3231e71747 100644
--- a/pstack/bucomm.c
+++ b/pstack/bucomm.c
@@ -212,7 +212,7 @@ make_tempname (filename)
{
tmpname = xmalloc (sizeof (template));
strcpy (tmpname, template);
- mktemp (tmpname);
+ mkstemp (tmpname);
}
return tmpname;
}
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 6409ec5d019..a8e5faa6eda 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -813,6 +813,8 @@ void ha_myisam::position(const byte* record)
void ha_myisam::info(uint flag)
{
MI_ISAMINFO info;
+ char name_buff[FN_REFLEN];
+
(void) mi_status(file,&info,flag);
if (flag & HA_STATUS_VARIABLE)
{
@@ -842,6 +844,18 @@ void ha_myisam::info(uint flag)
raid_type=info.raid_type;
raid_chunks=info.raid_chunks;
raid_chunksize=info.raid_chunksize;
+
+ /*
+ Set data_file_name and index_file_name to point at the symlink value
+ if table is symlinked
+ */
+ data_file_name=index_file_name=0;
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT, 4);
+ if (!strcmp(name_buff, info.data_file_name))
+ data_file_name=info.data_file_name;
+ strmov(fn_ext(name_buff),MI_NAME_DEXT);
+ if (!strcmp(name_buff, info.index_file_name))
+ index_file_name=info.index_file_name;
}
if (flag & HA_STATUS_ERRKEY)
{
@@ -897,6 +911,7 @@ THR_LOCK_DATA **ha_myisam::store_lock(THD *thd,
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
{
+ MI_ISAMINFO info;
table->file->info(HA_STATUS_AUTO | HA_STATUS_CONST);
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
{
@@ -908,6 +923,8 @@ void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
create_info->raid_chunks= raid_chunks;
create_info->raid_chunksize= raid_chunksize;
}
+ create_info->data_file_name=data_file_name;
+ create_info->index_file_name=index_file_name;
}
@@ -1079,6 +1096,8 @@ int ha_myisam::create(const char *name, register TABLE *form,
create_info.raid_type=info->raid_type;
create_info.raid_chunks=info->raid_chunks ? info->raid_chunks : RAID_DEFAULT_CHUNKS;
create_info.raid_chunksize=info->raid_chunksize ? info->raid_chunksize : RAID_DEFAULT_CHUNKSIZE;
+ create_info.data_file_name= info->data_file_name;
+ create_info.index_file_name=info->index_file_name;
error=mi_create(fn_format(buff,name,"","",2+4+16),
form->keys,keydef,
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index 6451e2b80ee..0a4a465a44b 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -38,6 +38,7 @@ class ha_myisam: public handler
{
MI_INFO *file;
uint int_option_flag;
+ char *data_file_name, *index_file_name;
int repair(THD *thd, MI_CHECK &param, bool optimize);
public:
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index b842c15cce0..e3e1d959438 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -232,7 +232,7 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
for (table=file->open_tables ; table != file->end_table ; table++)
{
- char *name=table->table->s->filename;
+ char *name=table->table->filename;
char buff[FN_REFLEN];
TABLE_LIST *ptr;
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
@@ -278,7 +278,7 @@ void ha_myisammrg::append_create_info(String *packet)
for (first=table=file->open_tables ; table != file->end_table ; table++)
{
- char *name=table->table->s->filename;
+ char *name=table->table->filename;
fn_format(buff,name,"","",3);
if (table != first)
packet->append(',');
diff --git a/sql/handler.cc b/sql/handler.cc
index bac24a6dba7..5b5d6d4764c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -853,5 +853,5 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
{
char buff[FN_REFLEN];
VOID(fn_format(buff,name,"",ext,extflag | 4));
- return(my_delete(buff,MYF(MY_WME)));
+ return(my_delete_with_symlink(buff,MYF(MY_WME)));
}
diff --git a/sql/handler.h b/sql/handler.h
index 7a28dc07a81..fc20e563f9f 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -142,6 +142,7 @@ typedef struct st_ha_create_information
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
char *comment,*password;
+ char *data_file_name, *index_file_name;
uint options; /* OR of HA_CREATE_ options */
uint raid_type,raid_chunks;
ulong raid_chunksize;
diff --git a/sql/lex.h b/sql/lex.h
index c29c4081787..2f3ae260417 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -113,6 +113,7 @@ static SYMBOL symbols[] = {
{ "DELETE", SYM(DELETE_SYM),0,0},
{ "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0},
+ { "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
{ "DISABLE", SYM(DISABLE_SYM),0,0},
{ "DISTINCT", SYM(DISTINCT),0,0},
{ "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 35a428273c7..68d717bc1fa 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -218,3 +218,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index b2fe6c4e800..2b054724222 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -212,3 +212,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 616f832bee8..48f5e9e3dc4 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index 032806f73f8..858618285b2 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -213,3 +213,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index aadfecbc8a1..26c114022c6 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 7a86a4368e7..9cf8b3c2e2e 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -212,3 +212,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index 5022bb65792..778c4483bd1 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index cfdd4b7fe75..b1bb76cd6c7 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -211,3 +211,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index d1b17bc8f2e..3b9a6b1604b 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 9dfe9bb3efb..6368ee5bae3 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -211,3 +211,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 4f0f90f88ce..a0e73ff9772 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 99238d61e3e..10c28232a5d 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -211,3 +211,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 473d297b649..e32d66f5eab 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -211,3 +211,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 253d4afd2b7..9d9c88e2ed6 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -213,3 +213,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index ba010a20710..65a1de7b4ff 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -209,3 +209,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 384df0c864e..421b43a781f 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -213,3 +213,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 7dd24c743bb..55d5a6ad360 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -212,3 +212,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index 2a6063b6aee..814bcccfc8e 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -217,3 +217,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index dbf7caf585d..4b075a4d3f6 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -210,3 +210,5 @@
"Lock wait timeout exceeded",
"The total number of locks exceeds the lock table size",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
diff --git a/sql/share/swedish/errmsg.OLD b/sql/share/swedish/errmsg.OLD
index 672ce97c575..227a02ac873 100644
--- a/sql/share/swedish/errmsg.OLD
+++ b/sql/share/swedish/errmsg.OLD
@@ -206,3 +206,8 @@
"Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
"Du kan endast använda konstant-uttryck med SET",
+"Tiden att få ett lås var för lång",
+"Antal lås är större än vad som ryms i lock tabellen",
+"Du kan inte låsa tabeller/poster under READ UNCOMMITTED",
+"Fick fel vid inloggning till master: %-.128s",
+"Fick fel vid exekvering av fråga på master: %-.128s",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index fc26a08e9ee..227a02ac873 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -206,6 +206,8 @@
"Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
"Du kan endast använda konstant-uttryck med SET",
-"Lock wait timeout exceeded",
-"The total number of locks exceeds the lock table size",
-"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+"Tiden att få ett lås var för lång",
+"Antal lås är större än vad som ryms i lock tabellen",
+"Du kan inte låsa tabeller/poster under READ UNCOMMITTED",
+"Fick fel vid inloggning till master: %-.128s",
+"Fick fel vid exekvering av fråga på master: %-.128s",
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 20eb4688de7..f3fda058113 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -212,7 +212,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
}
strxmov(filePath,org_path,"/",file->name,NullS);
unpack_filename(filePath,filePath);
- if (my_delete(filePath,MYF(MY_WME)))
+ if (my_delete_with_symlink(filePath,MYF(MY_WME)))
{
if(thd)
net_printf(&thd->net,ER_DB_DROP_DELETE,filePath,my_error);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index dc4e7358138..cccb58b1ea0 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -46,6 +46,7 @@ static bool check_dup(THD *thd,const char *db,const char *name,
static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
+static bool append_file_to_dir(char **filename_ptr, char *table_name);
const char *any_db="*any*"; // Special symbol for check_access
@@ -1286,6 +1287,14 @@ mysql_execute_command(void)
res=0;
break;
}
+ /* Fix names if symlinked tables */
+ if (append_file_to_dir(&lex->create_info.data_file_name, tables->name) ||
+ append_file_to_dir(&lex->create_info.index_file_name, tables->name))
+ {
+ res=-1;
+ break;
+ }
+
if (lex->item_list.elements) // With select
{
select_result *result;
@@ -1404,6 +1413,8 @@ mysql_execute_command(void)
goto error;
}
}
+ /* Don't yet allow changing of symlinks with ALTER TABLE */
+ lex->create_info.data_file_name=lex->create_info.index_file_name=0;
/* ALTER TABLE ends previous transaction */
if (end_active_trans(thd))
res= -1;
@@ -2884,3 +2895,31 @@ static void refresh_status(void)
pthread_mutex_unlock(&LOCK_status);
pthread_mutex_unlock(&THR_LOCK_keycache);
}
+
+
+ /* If pointer is not a null pointer, append filename to it */
+
+static bool append_file_to_dir(char **filename_ptr, char *table_name)
+{
+ char buff[FN_REFLEN],*ptr;
+ if (!*filename_ptr)
+ return 0; // nothing to do
+
+ /* Check that the filename is not too long and it's a hard path */
+ if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
+ !test_if_hard_path(*filename_ptr))
+ {
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
+ return 1;
+ }
+ /* Fix is using unix filename format on dos */
+ strmov(buff,*filename_ptr);
+ convert_dirname(buff);
+ if (!(ptr=sql_alloc(strlen(buff)+strlen(table_name+1))))
+ return 1; // End of memory
+ *filename_ptr=ptr;
+ ptr=strmov(ptr,buff);
+ *ptr=FN_LIBCHAR;
+ strmov(ptr+1,table_name);
+ return 0;
+}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c23c784ec14..69aa2a2c403 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1098,7 +1098,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
TABLE *table,*new_table;
int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN],
- *table_name,*db;
+ *table_name,*db;
+ char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0;
ha_rows copied,deleted;
ulonglong next_insert_id;
@@ -1120,10 +1121,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
strmov(new_name_buff,new_name);
fn_same(new_name_buff,table_name,3);
+ // Check if name changed
#ifdef FN_LOWER_CASE
- if (!my_strcasecmp(new_name_buff,table_name))// Check if name changed
+ if (!strcmp(db,new_db) && !my_strcasecmp(new_name_buff,table_name))
#else
- if (!strcmp(new_name_buff,table_name)) // Check if name changed
+ if (!strcmp(db,new_db) && !strcmp(new_name_buff,table_name))
#endif
new_name=table_name; // No. Make later check easier
else
@@ -1445,6 +1447,51 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table->tmp_table)
create_info->options|=HA_LEX_CREATE_TMP_TABLE;
+ /*
+ Handling of symlinked tables:
+ If no rename:
+ Create new data file and index file on the same disk as the
+ old data and index files.
+ Copy data.
+ Rename new data file over old data file and new index file over
+ old index file.
+ Symlinks are not changed.
+
+ If rename:
+ Create new data file and index file on the same disk as the
+ old data and index files. Create also symlinks to point at
+ the new tables.
+ Copy data.
+ At end, rename temporary tables and symlinks to temporary table
+ to final table name.
+ Remove old table and old symlinks
+
+ If rename is made to another database:
+ Create new tables in new database.
+ Copy data.
+ Remove old table and symlinks.
+ */
+
+ if (!strcmp(db, new_db)) // Ignore symlink if db changed
+ {
+ if (create_info->index_file_name)
+ {
+ /* Fix index_file_name to have 'tmp_name' as basename */
+ strmov(index_file, tmp_name);
+ create_info->index_file_name=fn_same(index_file,
+ create_info->index_file_name,
+ 1);
+ }
+ if (create_info->data_file_name)
+ {
+ /* Fix data_file_name to have 'tmp_name' as basename */
+ strmov(data_file, tmp_name);
+ create_info->data_file_name=fn_same(data_file,
+ create_info->data_file_name,
+ 1);
+ }
+ }
+
if ((error=mysql_create_table(thd, new_db, tmp_name,
create_info,
create_list,key_list,1,1))) // no logging
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a3bfd8c04a1..e3e5b2c567c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -161,6 +161,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DELAY_KEY_WRITE_SYM
%token DESC
%token DESCRIBE
+%token DIRECTORY_SYM
%token DISTINCT
%token DISABLE_SYM
%token DYNAMIC_SYM
@@ -771,6 +772,8 @@ create_table_option:
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
+ | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
+ | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; }
table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; }
@@ -2383,7 +2386,7 @@ use: USE_SYM ident
/* import, export of files */
-load: LOAD DATA_SYM opt_low_priority opt_local INFILE TEXT_STRING
+load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
{
Lex->sql_command= SQLCOM_LOAD;
Lex->local_file= $4;
@@ -2584,6 +2587,7 @@ keyword:
| DATETIME {}
| DATE_SYM {}
| DAY_SYM {}
+ | DIRECTORY_SYM {}
| DELAY_KEY_WRITE_SYM {}
| DISABLE_SYM {}
| DUMPFILE {}