Commit 866a8278 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

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.
parent 762f423d
......@@ -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 */
......
......@@ -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 \
......
......@@ -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 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
} /* 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,
......
......@@ -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);
}
......@@ -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);
......
......@@ -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);
}
......@@ -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 @@ static int myisamchk(MI_CHECK *param, my_string filename)
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,
......
......@@ -212,7 +212,7 @@ make_tempname (filename)
{
tmpname = xmalloc (sizeof (template));
strcpy (tmpname, template);
mktemp (tmpname);
mkstemp (tmpname);
}
return tmpname;
}
......
......@@ -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,
......
......@@ -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:
......
......@@ -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(',');
......
......@@ -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)));
}
......@@ -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;
......
......@@ -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 */
......
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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",
......@@ -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);
......
......@@ -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;
}
......@@ -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
......
......@@ -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 {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment