Commit bfdd0591 authored by Davi Arnaut's avatar Davi Arnaut

Merge of mysql-5.0-bugteam branch.

parents de73b729 42d0266a
...@@ -574,6 +574,7 @@ extern int my_close(File Filedes,myf MyFlags); ...@@ -574,6 +574,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,
......
...@@ -267,6 +267,10 @@ extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; ...@@ -267,6 +267,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);
......
...@@ -1732,7 +1732,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1732,7 +1732,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;
} }
} }
...@@ -2519,7 +2519,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, ...@@ -2519,7 +2519,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;
} }
} }
...@@ -3050,7 +3050,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -3050,7 +3050,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;
} }
} }
......
...@@ -192,7 +192,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -192,7 +192,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,7 +94,16 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -94,7 +94,16 @@ 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((byte*) &info,sizeof(info)); bzero((byte*) &info,sizeof(info));
my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0)); realpath_err= my_realpath(name_buff,
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)))
{ {
...@@ -463,7 +472,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -463,7 +472,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;
...@@ -534,7 +543,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -534,7 +543,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;
...@@ -1191,12 +1200,30 @@ The argument file_to_dup is here for the future if there would on some OS ...@@ -1191,12 +1200,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, File file_to_dup __attribute__((unused))) int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
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,
...@@ -1205,8 +1232,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attr ...@@ -1205,8 +1232,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attr
} }
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 , == , >= , <= , > , <
......
...@@ -1039,7 +1039,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) ...@@ -1039,7 +1039,7 @@ static int myisamchk(MI_CHECK *param, my_string 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;
......
...@@ -739,7 +739,9 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); ...@@ -739,7 +739,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);
......
...@@ -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);
} }
} }
......
...@@ -1861,4 +1861,26 @@ id ref ...@@ -1861,4 +1861,26 @@ 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
...@@ -57,8 +57,6 @@ t9 CREATE TABLE `t9` ( ...@@ -57,8 +57,6 @@ t9 CREATE TABLE `t9` (
Got one of the listed errors Got one of the listed errors
Got one of the listed errors Got one of the listed errors
Got one of the listed errors Got one of the listed errors
Got one of the listed errors
Got one of the listed errors
alter table t9 rename mysqltest.t9; alter table t9 rename mysqltest.t9;
select count(*) from mysqltest.t9; select count(*) from mysqltest.t9;
count(*) count(*)
......
drop table if exists t1; drop table if exists t1;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
Warnings:
Warning 1105 plugin_dir was not specified
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Can't find function 'myfunc_nonexist' in library ERROR HY000: Can't find function 'myfunc_nonexist' in library
...@@ -197,6 +199,8 @@ DROP FUNCTION avgcost; ...@@ -197,6 +199,8 @@ DROP FUNCTION avgcost;
select * from mysql.func; select * from mysql.func;
name ret dl type name ret dl type
CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
Warnings:
Warning 1105 plugin_dir was not specified
select IS_const(3); select IS_const(3);
IS_const(3) IS_const(3)
const const
...@@ -206,6 +210,8 @@ name ret dl type ...@@ -206,6 +210,8 @@ name ret dl type
select is_const(3); select is_const(3);
ERROR 42000: FUNCTION test.is_const does not exist ERROR 42000: FUNCTION test.is_const does not exist
CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
Warnings:
Warning 1105 plugin_dir was not specified
select select
is_const(3) as const, is_const(3) as const,
is_const(3.14) as const, is_const(3.14) as const,
......
...@@ -1210,4 +1210,19 @@ SELECT * FROM t1; ...@@ -1210,4 +1210,19 @@ 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
...@@ -71,8 +71,6 @@ drop table t1; ...@@ -71,8 +71,6 @@ drop table t1;
SHOW CREATE TABLE t9; SHOW CREATE TABLE t9;
disable_query_log; disable_query_log;
--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.
...@@ -81,8 +79,9 @@ create database mysqltest; ...@@ -81,8 +79,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'
--error 1,1,1105 --error 1,1,1105
...@@ -230,6 +229,7 @@ SET SESSION keep_files_on_create = TRUE; ...@@ -230,6 +229,7 @@ SET SESSION keep_files_on_create = TRUE;
EOF EOF
--disable_abort_on_error --disable_abort_on_error
--error 1 --error 1
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
CREATE TABLE t1 (a INT) ENGINE MYISAM; CREATE TABLE t1 (a INT) ENGINE MYISAM;
--error 0,1 --error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD; --remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD;
......
...@@ -106,24 +106,34 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) ...@@ -106,24 +106,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
{ {
/* /*
...@@ -138,7 +148,6 @@ int my_realpath(char *to, const char *filename, ...@@ -138,7 +148,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;
} }
......
...@@ -1264,6 +1264,7 @@ extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], ...@@ -1264,6 +1264,7 @@ extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[], mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
mysql_unpacked_real_data_home[], mysql_unpacked_real_data_home[],
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 char *command_name[]; extern const char *command_name[];
...@@ -1342,6 +1343,9 @@ extern char *default_tz_name; ...@@ -1342,6 +1343,9 @@ extern char *default_tz_name;
extern my_bool opt_large_pages; extern my_bool opt_large_pages;
extern uint opt_large_page_size; extern uint opt_large_page_size;
extern char *opt_plugin_dir_ptr;
extern char opt_plugin_dir[FN_REFLEN];
extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log; extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file; extern FILE *bootstrap_file;
extern int bootstrap_error; extern int bootstrap_error;
...@@ -1764,6 +1768,8 @@ inline void kill_delayed_threads(void) {} ...@@ -1764,6 +1768,8 @@ inline void kill_delayed_threads(void) {}
#define check_stack_overrun(A, B, C) 0 #define check_stack_overrun(A, B, C) 0
#endif #endif
extern "C" int test_if_data_home_dir(const char *dir);
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#endif #endif
...@@ -324,6 +324,9 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] = ...@@ -324,6 +324,9 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
/* static variables */ /* static variables */
char opt_plugin_dir[FN_REFLEN];
char *opt_plugin_dir_ptr;
static bool lower_case_table_names_used= 0; static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use; static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit; static bool volatile ready_to_exit;
...@@ -477,6 +480,7 @@ char mysql_real_data_home[FN_REFLEN], ...@@ -477,6 +480,7 @@ char mysql_real_data_home[FN_REFLEN],
*opt_init_file, *opt_tc_log_file, *opt_init_file, *opt_tc_log_file,
mysql_unpacked_real_data_home[FN_REFLEN], mysql_unpacked_real_data_home[FN_REFLEN],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
int mysql_unpacked_real_data_home_len;
char *mysql_data_home= mysql_real_data_home; char *mysql_data_home= mysql_real_data_home;
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
...@@ -4984,6 +4988,7 @@ enum options_mysqld ...@@ -4984,6 +4988,7 @@ enum options_mysqld
OPT_OLD_STYLE_USER_LIMITS, OPT_OLD_STYLE_USER_LIMITS,
OPT_LOG_SLOW_ADMIN_STATEMENTS, OPT_LOG_SLOW_ADMIN_STATEMENTS,
OPT_TABLE_LOCK_WAIT_TIMEOUT, OPT_TABLE_LOCK_WAIT_TIMEOUT,
OPT_PLUGIN_DIR,
OPT_PORT_OPEN_TIMEOUT, OPT_PORT_OPEN_TIMEOUT,
OPT_MERGE, OPT_MERGE,
OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_INNODB_ROLLBACK_ON_TIMEOUT,
...@@ -6216,6 +6221,10 @@ The minimum value for this variable is 4096.", ...@@ -6216,6 +6221,10 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.optimizer_search_depth, (gptr*) &global_system_variables.optimizer_search_depth,
(gptr*) &max_system_variables.optimizer_search_depth, (gptr*) &max_system_variables.optimizer_search_depth,
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0}, 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
{"plugin_dir", OPT_PLUGIN_DIR,
"Directory for plugins.",
(gptr*) &opt_plugin_dir_ptr, (gptr*) &opt_plugin_dir_ptr, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes", "The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size, (gptr*) &global_system_variables.preload_buff_size,
...@@ -6696,6 +6705,7 @@ static void mysql_init_variables(void) ...@@ -6696,6 +6705,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;
opt_bin_log= 0; opt_bin_log= 0;
...@@ -7746,13 +7756,19 @@ static void fix_paths(void) ...@@ -7746,13 +7756,19 @@ 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);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
(void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
"", "");
opt_plugin_dir_ptr= opt_plugin_dir;
char *sharedir=get_relative_path(SHAREDIR); char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir)) if (test_if_hard_path(sharedir))
......
...@@ -1026,6 +1026,7 @@ struct show_var_st init_vars[]= { ...@@ -1026,6 +1026,7 @@ struct show_var_st init_vars[]= {
{sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth, {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
SHOW_SYS}, SHOW_SYS},
{"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"pid_file", (char*) pidfile_name, SHOW_CHAR},
{"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR},
{"port", (char*) &mysqld_port, SHOW_INT}, {"port", (char*) &mysqld_port, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
{"protocol_version", (char*) &protocol_version, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT},
......
...@@ -76,7 +76,6 @@ static void remove_escape(char *name); ...@@ -76,7 +76,6 @@ static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr, static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name); const char *table_name);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
static bool test_if_data_home_dir(const char *dir);
const char *any_db="*any*"; // Special symbol for check_access const char *any_db="*any*"; // Special symbol for check_access
...@@ -3044,13 +3043,13 @@ mysql_execute_command(THD *thd) ...@@ -3044,13 +3043,13 @@ mysql_execute_command(THD *thd)
if (test_if_data_home_dir(lex->create_info.data_file_name)) if (test_if_data_home_dir(lex->create_info.data_file_name))
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY"); my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
res= -1; res= -1;
break; break;
} }
if (test_if_data_home_dir(lex->create_info.index_file_name)) if (test_if_data_home_dir(lex->create_info.index_file_name))
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY"); my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
res= -1; res= -1;
break; break;
} }
...@@ -7946,10 +7945,12 @@ bool check_string_length(LEX_STRING *str, const char *err_msg, ...@@ -7946,10 +7945,12 @@ bool check_string_length(LEX_STRING *str, const char *err_msg,
1 error 1 error
*/ */
static bool test_if_data_home_dir(const char *dir) C_MODE_START
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)
...@@ -7957,21 +7958,27 @@ static bool test_if_data_home_dir(const char *dir) ...@@ -7957,21 +7958,27 @@ static 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(default_charset_info, (const uchar*) conv_path, if (!my_strnncoll(default_charset_info, (const uchar*) 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
...@@ -214,7 +214,17 @@ void udf_init() ...@@ -214,7 +214,17 @@ void udf_init()
void *dl = find_udf_dl(tmp->dl); void *dl = find_udf_dl(tmp->dl);
if (dl == NULL) if (dl == NULL)
{ {
if (!(dl = dlopen(tmp->dl, RTLD_NOW))) char dlpath[FN_REFLEN];
if (*opt_plugin_dir)
strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
NullS);
else
{
strxnmov(dlpath, sizeof(dlpath)-1, tmp->dl, NullS);
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"plugin_dir was not specified");
}
if (!(dl = dlopen(dlpath, RTLD_NOW)))
{ {
/* Print warning to log */ /* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror()); sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror());
...@@ -443,8 +453,18 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -443,8 +453,18 @@ int mysql_create_function(THD *thd,udf_func *udf)
} }
if (!(dl = find_udf_dl(udf->dl))) if (!(dl = find_udf_dl(udf->dl)))
{ {
DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", udf->dl)); char dlpath[FN_REFLEN];
if (!(dl = dlopen(udf->dl, RTLD_NOW))) if (*opt_plugin_dir)
strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl,
NullS);
else
{
strxnmov(dlpath, sizeof(dlpath)-1, udf->dl, NullS);
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"plugin_dir was not specified");
}
DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", dlpath));
if (!(dl = dlopen(dlpath, RTLD_NOW)))
{ {
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl,errno,dlerror())); udf->dl,errno,dlerror()));
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#ifndef SHAREDIR #ifndef SHAREDIR
#define SHAREDIR "share/" #define SHAREDIR "share/"
#endif #endif
#ifndef PLUGINDIR
#define PLUGINDIR "lib/plugin"
#endif
#define ER(X) errmesg[(X) - ER_ERROR_FIRST] #define ER(X) errmesg[(X) - ER_ERROR_FIRST]
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code") #define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
......
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