Commit 2b5e539c authored by Davi Arnaut's avatar Davi Arnaut

Merge of mysql-5.1-bugteam branch.

parents 7e63f138 46abb094
...@@ -577,6 +577,7 @@ extern int my_close(File Filedes,myf MyFlags); ...@@ -577,6 +577,7 @@ extern int my_close(File Filedes,myf MyFlags);
extern File my_dup(File file, myf MyFlags); extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags); extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags); extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_is_symlink(const char *filename);
extern int my_realpath(char *to, const char *filename, myf MyFlags); extern int my_realpath(char *to, const char *filename, myf MyFlags);
extern File my_create_with_symlink(const char *linkname, const char *filename, extern File my_create_with_symlink(const char *linkname, const char *filename,
int createflags, int access_flags, int createflags, int access_flags,
......
...@@ -256,6 +256,10 @@ extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; ...@@ -256,6 +256,10 @@ extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_off_t myisam_max_temp_length; extern my_off_t myisam_max_temp_length;
extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
/* usually used to check if a symlink points into the mysql data home */
/* which is normally forbidden */
extern int (*myisam_test_invalid_symlink)(const char *filename);
/* Prototypes for myisam-functions */ /* Prototypes for myisam-functions */
extern int mi_close(struct st_myisam_info *file); extern int mi_close(struct st_myisam_info *file);
......
...@@ -1831,6 +1831,28 @@ id ref ...@@ -1831,6 +1831,28 @@ id ref
3 2 3 2
4 5 4 5
DROP TABLE t1, t2; DROP TABLE t1, t2;
CREATE TABLE t1 (a INT) ENGINE=MyISAM CHECKSUM=1 ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES (0);
UPDATE t1 SET a=1;
SELECT a FROM t1;
a
1
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
INSERT INTO t1 VALUES (0), (5), (4), (2);
UPDATE t1 SET a=2;
SELECT a FROM t1;
a
2
2
2
2
2
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
create table t1 (a int not null, key `a` (a) key_block_size=1024); create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1; show create table t1;
......
...@@ -113,9 +113,9 @@ set @@sql_mode=@org_mode; ...@@ -113,9 +113,9 @@ set @@sql_mode=@org_mode;
create table t1 (a int) create table t1 (a int)
partition by key (a) partition by key (a)
(partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data'); (partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
ERROR 42000: Incorrect table name 'part-data' Got one of the listed errors
create table t1 (a int) create table t1 (a int)
partition by key (a) partition by key (a)
(partition p0, (partition p0,
partition p1 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data'); partition p1 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
ERROR 42000: Incorrect table name 'part-data' Got one of the listed errors
...@@ -55,13 +55,9 @@ t9 CREATE TABLE `t9` ( ...@@ -55,13 +55,9 @@ t9 CREATE TABLE `t9` (
`d` int(11) NOT NULL, `d` int(11) NOT NULL,
PRIMARY KEY (`a`) PRIMARY KEY (`a`)
) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/' ) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/'
create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp";
Got one of the listed errors
create database mysqltest; create database mysqltest;
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist"; create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
Got one of the listed errors Got one of the listed errors
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
Got one of the listed errors
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="MYSQLTEST_VARDIR/run"; create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="MYSQLTEST_VARDIR/run";
Got one of the listed errors Got one of the listed errors
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="MYSQLTEST_VARDIR/tmp"; create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="MYSQLTEST_VARDIR/tmp";
......
...@@ -9,5 +9,3 @@ ...@@ -9,5 +9,3 @@
# Do not use any TAB characters for whitespace. # Do not use any TAB characters for whitespace.
# #
############################################################################## ##############################################################################
jp_convert_sjis : Bug#36597 Testsuite "jp": Suspicious results for some tests
jp_select_sjis : Bug#36597 Testsuite "jp": Suspicious results for some tests
...@@ -1169,6 +1169,21 @@ SELECT * FROM t1; ...@@ -1169,6 +1169,21 @@ SELECT * FROM t1;
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# Bug#37310: 'on update CURRENT_TIMESTAMP' option crashes the table
#
CREATE TABLE t1 (a INT) ENGINE=MyISAM CHECKSUM=1 ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES (0);
UPDATE t1 SET a=1;
SELECT a FROM t1;
CHECK TABLE t1;
INSERT INTO t1 VALUES (0), (5), (4), (2);
UPDATE t1 SET a=2;
SELECT a FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
......
...@@ -154,7 +154,8 @@ set @@sql_mode=@org_mode; ...@@ -154,7 +154,8 @@ set @@sql_mode=@org_mode;
# #
# Bug 21350: Data Directory problems # Bug 21350: Data Directory problems
# #
-- error ER_WRONG_TABLE_NAME # Added ER_WRONG_TABLE_NAME and reported bug#39045
-- error ER_WRONG_ARGUMENTS, ER_WRONG_TABLE_NAME
create table t1 (a int) create table t1 (a int)
partition by key (a) partition by key (a)
(partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data'); (partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
...@@ -163,7 +164,8 @@ partition by key (a) ...@@ -163,7 +164,8 @@ partition by key (a)
# Insert a test that manages to create the first partition and fails with # Insert a test that manages to create the first partition and fails with
# the second, ensure that we clean up afterwards in a proper manner. # the second, ensure that we clean up afterwards in a proper manner.
# #
--error ER_WRONG_TABLE_NAME # Added ER_WRONG_TABLE_NAME and reported bug#39045
--error ER_WRONG_ARGUMENTS, ER_WRONG_TABLE_NAME
create table t1 (a int) create table t1 (a int)
partition by key (a) partition by key (a)
(partition p0, (partition p0,
......
...@@ -65,8 +65,6 @@ drop table t1; ...@@ -65,8 +65,6 @@ drop table t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t9; SHOW CREATE TABLE t9;
--error 1103,1103
create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp";
# Check that we cannot link over a table from another database. # Check that we cannot link over a table from another database.
...@@ -75,8 +73,9 @@ create database mysqltest; ...@@ -75,8 +73,9 @@ create database mysqltest;
--error 1,1 --error 1,1
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist"; create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
--error 1103,1103 # temporarily disabled as it returns different result in the embedded server
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; # --error 1210, 1210
# create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
# Should fail becasue the file t9.MYI already exist in 'run' # Should fail becasue the file t9.MYI already exist in 'run'
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
......
...@@ -108,24 +108,34 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) ...@@ -108,24 +108,34 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags)
#define BUFF_LEN FN_LEN #define BUFF_LEN FN_LEN
#endif #endif
int my_is_symlink(const char *filename __attribute__((unused)))
{
#if defined (HAVE_LSTAT) && defined (S_ISLNK)
struct stat stat_buff;
return !lstat(filename, &stat_buff) && S_ISLNK(stat_buff.st_mode);
#elif defined (_WIN32)
DWORD dwAttr = GetFileAttributes(filename);
return (dwAttr != INVALID_FILE_ATTRIBUTES) &&
(dwAttr & FILE_ATTRIBUTE_REPARSE_POINT);
#else /* No symlinks */
return 0;
#endif
}
int my_realpath(char *to, const char *filename, int my_realpath(char *to, const char *filename,
myf MyFlags __attribute__((unused))) myf MyFlags __attribute__((unused)))
{ {
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH) #if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
int result=0; int result=0;
char buff[BUFF_LEN]; char buff[BUFF_LEN];
struct stat stat_buff; char *ptr;
DBUG_ENTER("my_realpath"); DBUG_ENTER("my_realpath");
if (!(MyFlags & MY_RESOLVE_LINK) ||
(!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
{
char *ptr;
DBUG_PRINT("info",("executing realpath")); DBUG_PRINT("info",("executing realpath"));
if ((ptr=realpath(filename,buff))) if ((ptr=realpath(filename,buff)))
{
strmake(to,ptr,FN_REFLEN-1); strmake(to,ptr,FN_REFLEN-1);
}
else else
{ {
/* /*
...@@ -140,7 +150,6 @@ int my_realpath(char *to, const char *filename, ...@@ -140,7 +150,6 @@ int my_realpath(char *to, const char *filename,
my_load_path(to, filename, NullS); my_load_path(to, filename, NullS);
result= -1; result= -1;
} }
}
DBUG_RETURN(result); DBUG_RETURN(result);
#else #else
my_load_path(to, filename, NullS); my_load_path(to, filename, NullS);
......
...@@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock) ...@@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock)
void thr_lock_delete(THR_LOCK *lock) void thr_lock_delete(THR_LOCK *lock)
{ {
DBUG_ENTER("thr_lock_delete"); DBUG_ENTER("thr_lock_delete");
VOID(pthread_mutex_destroy(&lock->mutex));
pthread_mutex_lock(&THR_LOCK_lock); pthread_mutex_lock(&THR_LOCK_lock);
thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list); thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
pthread_mutex_unlock(&THR_LOCK_lock); pthread_mutex_unlock(&THR_LOCK_lock);
pthread_mutex_destroy(&lock->mutex);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -803,7 +803,6 @@ bool check_string_byte_length(LEX_STRING *str, const char *err_msg, ...@@ -803,7 +803,6 @@ bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
bool check_string_char_length(LEX_STRING *str, const char *err_msg, bool check_string_char_length(LEX_STRING *str, const char *err_msg,
uint max_char_length, CHARSET_INFO *cs, uint max_char_length, CHARSET_INFO *cs,
bool no_error); bool no_error);
bool test_if_data_home_dir(const char *dir);
bool parse_sql(THD *thd, bool parse_sql(THD *thd,
Parser_state *parser_state, Parser_state *parser_state,
...@@ -1862,6 +1861,7 @@ extern CHARSET_INFO *character_set_filesystem; ...@@ -1862,6 +1861,7 @@ extern CHARSET_INFO *character_set_filesystem;
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
extern char *opt_mysql_tmpdir, mysql_charsets_dir[], extern char *opt_mysql_tmpdir, mysql_charsets_dir[],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
extern int mysql_unpacked_real_data_home_len;
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list; extern MY_TMPDIR mysql_tmpdir_list;
extern const LEX_STRING command_name[]; extern const LEX_STRING command_name[];
...@@ -2473,6 +2473,8 @@ bool load_collation(MEM_ROOT *mem_root, ...@@ -2473,6 +2473,8 @@ bool load_collation(MEM_ROOT *mem_root,
CHARSET_INFO **cl); CHARSET_INFO **cl);
#endif /* MYSQL_SERVER */ #endif /* MYSQL_SERVER */
extern "C" int test_if_data_home_dir(const char *dir);
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#endif /* MYSQL_PRIV_H */ #endif /* MYSQL_PRIV_H */
...@@ -520,6 +520,7 @@ char mysql_real_data_home[FN_REFLEN], ...@@ -520,6 +520,7 @@ char mysql_real_data_home[FN_REFLEN],
*opt_init_file, *opt_tc_log_file, *opt_init_file, *opt_tc_log_file,
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
char mysql_unpacked_real_data_home[FN_REFLEN]; char mysql_unpacked_real_data_home[FN_REFLEN];
int mysql_unpacked_real_data_home_len;
uint reg_ext_length; uint reg_ext_length;
const key_map key_map_empty(0); const key_map key_map_empty(0);
key_map key_map_full(0); // Will be initialized later key_map key_map_full(0); // Will be initialized later
...@@ -7408,6 +7409,7 @@ static void mysql_init_variables(void) ...@@ -7408,6 +7409,7 @@ static void mysql_init_variables(void)
/* Things reset to zero */ /* Things reset to zero */
opt_skip_slave_start= opt_reckless_slave = 0; opt_skip_slave_start= opt_reckless_slave = 0;
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
myisam_test_invalid_symlink= test_if_data_home_dir;
opt_log= opt_slow_log= 0; opt_log= opt_slow_log= 0;
opt_update_log= 0; opt_update_log= 0;
log_output_options= find_bit_type(log_output_str, &log_output_typelib); log_output_options= find_bit_type(log_output_str, &log_output_typelib);
...@@ -8360,9 +8362,12 @@ static void fix_paths(void) ...@@ -8360,9 +8362,12 @@ static void fix_paths(void)
pos[1]= 0; pos[1]= 0;
} }
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
(void) fn_format(buff, mysql_real_data_home, "", "", my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); mysql_unpacked_real_data_home_len= strlen(mysql_unpacked_real_data_home);
(void) unpack_dirname(mysql_unpacked_real_data_home, buff); if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
--mysql_unpacked_real_data_home_len;
convert_dirname(language,language,NullS); convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
......
...@@ -7413,11 +7413,12 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, ...@@ -7413,11 +7413,12 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
0 ok 0 ok
1 error 1 error
*/ */
C_MODE_START
bool test_if_data_home_dir(const char *dir) int test_if_data_home_dir(const char *dir)
{ {
char path[FN_REFLEN], conv_path[FN_REFLEN]; char path[FN_REFLEN];
uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home); int dir_len;
DBUG_ENTER("test_if_data_home_dir"); DBUG_ENTER("test_if_data_home_dir");
if (!dir) if (!dir)
...@@ -7425,24 +7426,30 @@ bool test_if_data_home_dir(const char *dir) ...@@ -7425,24 +7426,30 @@ bool test_if_data_home_dir(const char *dir)
(void) fn_format(path, dir, "", "", (void) fn_format(path, dir, "", "",
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
dir_len= unpack_dirname(conv_path, dir); dir_len= strlen(path);
if (mysql_unpacked_real_data_home_len<= dir_len)
if (home_dir_len < dir_len)
{ {
if (dir_len > mysql_unpacked_real_data_home_len &&
path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
DBUG_RETURN(0);
if (lower_case_file_system) if (lower_case_file_system)
{ {
if (!my_strnncoll(character_set_filesystem, if (!my_strnncoll(default_charset_info, (const uchar*) path,
(const uchar*) conv_path, home_dir_len, mysql_unpacked_real_data_home_len,
(const uchar*) mysql_unpacked_real_data_home, (const uchar*) mysql_unpacked_real_data_home,
home_dir_len)) mysql_unpacked_real_data_home_len))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len)) else if (!memcmp(path, mysql_unpacked_real_data_home,
mysql_unpacked_real_data_home_len))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
C_MODE_END
extern int MYSQLparse(void *thd); // from sql_yacc.cc extern int MYSQLparse(void *thd); // from sql_yacc.cc
......
...@@ -1736,7 +1736,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1736,7 +1736,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
DATA_TMP_EXT, share->base.raid_chunks, DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ? (param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,-1)) mi_open_datafile(info,share,name,-1))
got_error=1; got_error=1;
} }
} }
...@@ -2549,7 +2549,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, ...@@ -2549,7 +2549,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
DATA_TMP_EXT, share->base.raid_chunks, DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ? (param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,-1)) mi_open_datafile(info,share,name,-1))
got_error=1; got_error=1;
} }
} }
...@@ -3081,7 +3081,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -3081,7 +3081,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
DATA_TMP_EXT, share->base.raid_chunks, DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ? (param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,-1)) mi_open_datafile(info,share,name,-1))
got_error=1; got_error=1;
} }
} }
......
...@@ -196,7 +196,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -196,7 +196,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
packed=(packed+7)/8; packed=(packed+7)/8;
if (pack_reclength != INT_MAX32) if (pack_reclength != INT_MAX32)
pack_reclength+= reclength+packed + pack_reclength+= reclength+packed +
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD)); test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD));
min_pack_length+=packed; min_pack_length+=packed;
if (!ci->data_file_length && ci->max_rows) if (!ci->data_file_length && ci->max_rows)
......
...@@ -74,7 +74,7 @@ MI_INFO *test_if_reopen(char *filename) ...@@ -74,7 +74,7 @@ MI_INFO *test_if_reopen(char *filename)
MI_INFO *mi_open(const char *name, int mode, uint open_flags) MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{ {
int lock_error,kfile,open_mode,save_errno,have_rtree=0; int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys, uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,fulltext_keys,uniques; key_parts,unique_key_parts,fulltext_keys,uniques;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
...@@ -94,8 +94,15 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -94,8 +94,15 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
head_length=sizeof(share_buff.state.header); head_length=sizeof(share_buff.state.header);
bzero((uchar*) &info,sizeof(info)); bzero((uchar*) &info,sizeof(info));
my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT, realpath_err= my_realpath(name_buff,
MY_UNPACK_FILENAME),MYF(0)); fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
if (my_is_symlink(org_name) &&
(realpath_err || (*myisam_test_invalid_symlink)(name_buff)))
{
my_errno= HA_WRONG_CREATE_OPTION;
DBUG_RETURN (NULL);
}
pthread_mutex_lock(&THR_LOCK_myisam); pthread_mutex_lock(&THR_LOCK_myisam);
if (!(old_info=test_if_reopen(name_buff))) if (!(old_info=test_if_reopen(name_buff)))
{ {
...@@ -476,7 +483,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -476,7 +483,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
lock_error=1; /* Database unlocked */ lock_error=1; /* Database unlocked */
} }
if (mi_open_datafile(&info, share, -1)) if (mi_open_datafile(&info, share, name, -1))
goto err; goto err;
errpos=5; errpos=5;
...@@ -556,7 +563,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -556,7 +563,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=EACCES; /* Can't open in write mode */ my_errno=EACCES; /* Can't open in write mode */
goto err; goto err;
} }
if (mi_open_datafile(&info, share, old_info->dfile)) if (mi_open_datafile(&info, share, name, old_info->dfile))
goto err; goto err;
errpos=5; errpos=5;
have_rtree= old_info->rtree_recursion_state != NULL; have_rtree= old_info->rtree_recursion_state != NULL;
...@@ -1217,13 +1224,30 @@ The argument file_to_dup is here for the future if there would on some OS ...@@ -1217,13 +1224,30 @@ The argument file_to_dup is here for the future if there would on some OS
exist a dup()-like call that would give us two different file descriptors. exist a dup()-like call that would give us two different file descriptors.
*************************************************************************/ *************************************************************************/
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
File file_to_dup __attribute__((unused))) File file_to_dup __attribute__((unused)))
{ {
char *data_name= share->data_file_name;
char real_data_name[FN_REFLEN];
if (org_name)
{
fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4);
if (my_is_symlink(real_data_name))
{
if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
(*myisam_test_invalid_symlink)(real_data_name))
{
my_errno= HA_WRONG_CREATE_OPTION;
return 1;
}
data_name= real_data_name;
}
}
#ifdef USE_RAID #ifdef USE_RAID
if (share->base.raid_type) if (share->base.raid_type)
{ {
info->dfile=my_raid_open(share->data_file_name, info->dfile=my_raid_open(data_name,
share->mode | O_SHARE, share->mode | O_SHARE,
share->base.raid_type, share->base.raid_type,
share->base.raid_chunks, share->base.raid_chunks,
...@@ -1232,8 +1256,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, ...@@ -1232,8 +1256,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
} }
else else
#endif #endif
info->dfile=my_open(share->data_file_name, share->mode | O_SHARE, info->dfile=my_open(data_name, share->mode | O_SHARE, MYF(MY_WME));
MYF(MY_WME));
return info->dfile >= 0 ? 0 : 1; return info->dfile >= 0 ? 0 : 1;
} }
......
...@@ -41,6 +41,15 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ...@@ -41,6 +41,15 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4; ulong myisam_data_pointer_size=4;
static int always_valid(const char *filename __attribute__((unused)))
{
return 0;
}
int (*myisam_test_invalid_symlink)(const char *filename)= always_valid;
/* /*
read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
Position is , == , >= , <= , > , < Position is , == , >= , <= , > , <
......
...@@ -1033,7 +1033,7 @@ static int myisamchk(MI_CHECK *param, char * filename) ...@@ -1033,7 +1033,7 @@ static int myisamchk(MI_CHECK *param, char * filename)
error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks, raid_chunks,
MYF(0)); MYF(0));
if (mi_open_datafile(info,info->s, -1)) if (mi_open_datafile(info,info->s, NULL, -1))
error=1; error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
param->read_cache.file=info->dfile; param->read_cache.file=info->dfile;
......
...@@ -756,7 +756,9 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); ...@@ -756,7 +756,9 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
extern MI_INFO *test_if_reopen(char *filename); extern MI_INFO *test_if_reopen(char *filename);
my_bool check_table_is_closed(const char *name, const char *where); my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name,
File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share); int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share);
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
......
...@@ -389,7 +389,7 @@ int rtree_get_first(MI_INFO *info, uint keynr, uint key_length) ...@@ -389,7 +389,7 @@ int rtree_get_first(MI_INFO *info, uint keynr, uint key_length)
info->rtree_recursion_depth = -1; info->rtree_recursion_depth = -1;
info->buff_used = 1; info->buff_used = 1;
return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0); return rtree_get_req(info, keyinfo, key_length, root, 0);
} }
...@@ -436,7 +436,7 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) ...@@ -436,7 +436,7 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length)
return -1; return -1;
} }
return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0); return rtree_get_req(info, keyinfo, key_length, root, 0);
} }
} }
......
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