From e62048fa8632d9266907b6d992047cba6d8e2248 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 00:53:25 +0200 Subject: Avoiding a theoretically possible crash (pthread_mutex_lock(0)) which could (at least in POSIX Threads books) happen on SMP machines, when a thread is going to wait on a condition and it is KILLed at the same time. Cleaning code a bit by adding a test in enter_cond() that we have the mutex (was already the case in all places where it's called except one which is fixed here). sql/log.cc: safe_mutex_assert_owner() is now in THD::enter_cond() sql/slave.cc: lock mutex before waiting on condition. sql/sql_class.cc: THD::awake(): before locking the mutex, let's test it's not zero; in theory indeed, the killer thread may see current_cond non-zero and current_mutex zero (order of assignments is not guaranteed by POSIX). A comment noting that there is still a small chance a KILL does not work and needs being re-issued. sql/sql_class.h: Assert in enter_cond() that we have the mutex. It is already the case in all places where we call enter_cond(), so better ensure it there. --- sql/sql_class.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 44faa3d6963..eb6e74a58c4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -299,8 +299,18 @@ void THD::awake(bool prepare_to_die) exits the cond in the time between read and broadcast, but that is ok since all we want to do is to make the victim thread get out of waiting on current_cond. + If we see a non-zero current_cond: it cannot be an old value (because + then exit_cond() should have run and it can't because we have mutex); so + it is the true value but maybe current_mutex is not yet non-zero (we're + in the middle of enter_cond() and there is a "memory order + inversion"). So we test the mutex too to not lock 0. + Note that there is a small chance we fail to kill. If victim has locked + current_mutex, and hasn't entered enter_cond(), then we don't know it's + going to wait on cond. Then victim goes into its cond "forever" (until + we issue a second KILL). True we have set its thd->killed but it may not + see it immediately and so may have time to reach the cond_wait(). */ - if (mysys_var->current_cond) + if (mysys_var->current_cond && mysys_var->current_mutex) { pthread_mutex_lock(mysys_var->current_mutex); pthread_cond_broadcast(mysys_var->current_cond); -- cgit v1.2.1 From 48bb56302e9e85d4a1939968be41ffa222b036e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Aug 2004 02:02:46 +0400 Subject: Fix for bug#4912 "mysqld crashs in case a statement is executed a second time". The bug was caused by incompatibility of negations elimination algorithm and PS: during first statement execute a subtree with negation was replaced with equivalent subtree without NOTs. The problem was that although this transformation was permanent, items of the new subtree were created in execute-local memory. The patch adds means to check if it is the first execute of a prepared statement, and if this is the case, to allocate items in memory of the prepared statement. The implementation: - backports Item_arena from 5.0 - adds Item_arena::is_stmt_prepare(), Item_arena::is_first_stmt_execute(). - deletes THD::allocate_temporary_pool_for_ps_preparing(), THD::free_temporary_pool_for_ps_preparing(); they were redundant. and adds a few invariants: - thd->free_list never contains junk (= freed items) - thd->current_arena is never null. If there is no prepared statement, it points at the thd. The rest of the patch contains mainly mechanical changes and cleanups. mysql-test/r/ps.result: Test results updated (test case for Bug#4912) mysql-test/t/ps.test: A test case for Bug#4912 "mysqld crashs in case a statement is executed a second time" sql/item_cmpfunc.cc: current_statement -> current_arena sql/item_subselect.cc: Statement -> Item_arena, current_statement -> current_arena sql/item_subselect.h: Item_subselect does not need to save thd->current_statement. sql/item_sum.cc: Statement -> Item_arena sql/item_sum.h: Statement -> Item_arena sql/mysql_priv.h: Statement -> Item_arena sql/sql_base.cc: current_statement -> current_arena sql/sql_class.cc: - Item_arena - convenient set_n_backup_statement, restore_backup_statement (nice idea, Sanja) sql/sql_class.h: - Item_arena: backport from 5.0 - allocate_temporary_pool_for_ps_preparing, free_temporary_pool_for_ps_preparing removed. sql/sql_derived.cc: current_statement -> current_arena sql/sql_lex.cc: current_statement -> current_arena sql/sql_parse.cc: Deploy invariant that thd->free_list never contains junk items (backport from 5.0). sql/sql_prepare.cc: - backporting Item_arena - no need to allocate_temporary_pool_for_ps_preparing(). sql/sql_select.cc: Fix for bug#4912 "mysqld crashs in case a statement is executed a second time": if this is the first execute of a prepared statement, negation elimination is done in memory of the prepared statement. sql/sql_union.cc: Backporting Item_arena from 5.0. --- sql/sql_class.cc | 78 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 14 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 73a180078cf..23fef44c964 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,7 +155,7 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_statement(0), is_fatal_error(0), +THD::THD():user_time(0), current_arena(this), is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), time_zone_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0) @@ -1301,23 +1301,59 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } +Item_arena::Item_arena(THD* thd) + :free_list(0), + state(INITIALIZED) +{ + init_sql_alloc(&mem_root, + thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); +} + + +/* This constructor is called when Item_arena is a subobject of THD */ + +Item_arena::Item_arena() + :free_list(0), + state(CONVENTIONAL_EXECUTION) +{ + clear_alloc_root(&mem_root); +} + + +Item_arena::Item_arena(bool init_mem_root) + :free_list(0), + state(INITIALIZED) +{ + if (init_mem_root) + clear_alloc_root(&mem_root); +} + +Item_arena::Type Item_arena::type() const +{ + DBUG_ASSERT("Item_arena::type()" == "abstract"); + return STATEMENT; +} + + +Item_arena::~Item_arena() +{} + + /* Statement functions */ Statement::Statement(THD *thd) - :id(++thd->statement_id_counter), + :Item_arena(thd), + id(++thd->statement_id_counter), set_query_id(1), allow_sum_func(0), lex(&main_lex), query(0), - query_length(0), - free_list(0) + query_length(0) { name.str= NULL; - init_sql_alloc(&mem_root, - thd->variables.query_alloc_block_size, - thd->variables.query_prealloc_size); } /* @@ -1332,14 +1368,12 @@ Statement::Statement() allow_sum_func(0), /* initialized later */ lex(&main_lex), query(0), /* these two are set */ - query_length(0), /* in alloc_query() */ - free_list(0) + query_length(0) /* in alloc_query() */ { - bzero((char *) &mem_root, sizeof(mem_root)); } -Statement::Type Statement::type() const +Item_arena::Type Statement::type() const { return STATEMENT; } @@ -1356,14 +1390,29 @@ void Statement::set_statement(Statement *stmt) } -void Statement::set_n_backup_item_arena(Statement *set, Statement *backup) +void +Statement::set_n_backup_statement(Statement *stmt, Statement *backup) +{ + backup->set_statement(this); + set_statement(stmt); +} + + +void Statement::restore_backup_statement(Statement *stmt, Statement *backup) +{ + stmt->set_statement(this); + set_statement(backup); +} + + +void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); set_item_arena(set); } -void Statement::restore_backup_item_arena(Statement *set, Statement *backup) +void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) { set->set_item_arena(this); set_item_arena(backup); @@ -1371,10 +1420,11 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup) init_alloc_root(&backup->mem_root, 0, 0); } -void Statement::set_item_arena(Statement *set) +void Item_arena::set_item_arena(Item_arena *set) { mem_root= set->mem_root; free_list= set->free_list; + state= set->state; } Statement::~Statement() -- cgit v1.2.1 From 11010a0887fd3cc2dac9dc1f7a8bdc667da2729a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 14:44:15 +0400 Subject: Fix to compile with msvc: converted static const int Item_arena::* to enum members, undefine ERROR include/config-win.h: Undefine ERROR #defined by WINGDI sql/sql_class.cc: Fix to compile with msvc: converted static const int Item_arena::* to enum members sql/sql_class.h: Fix to compile with msvc: converted static const int Item_arena::* to enum members sql/sql_prepare.cc: Fix to compile with msvc: converted static const int Item_arena::* to enum members --- sql/sql_class.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..ff7dc805119 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1303,7 +1303,7 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) Item_arena::Item_arena(THD* thd) :free_list(0), - state(INITIALIZED) + state((int)INITIALIZED) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, @@ -1315,7 +1315,7 @@ Item_arena::Item_arena(THD* thd) Item_arena::Item_arena() :free_list(0), - state(CONVENTIONAL_EXECUTION) + state((int)CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } @@ -1323,7 +1323,7 @@ Item_arena::Item_arena() Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state(INITIALIZED) + state((int)INITIALIZED) { if (init_mem_root) clear_alloc_root(&mem_root); -- cgit v1.2.1 From 0469136073575b53634168dd03edceaa25f66b77 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 18:00:45 +0300 Subject: Portablity fixes & simple optimizations sql/ha_ndbcluster.cc: Added missing cast sql/item.cc: Portability fix (for windows) sql/lock.cc: Cleanup + more comments sql/sql_class.cc: Portability fix + more comments sql/sql_select.cc: Portability fix sql/sql_table.cc: Simpler handling of auto_increment in ALTER TABLE --- sql/sql_class.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..e49cfecba9d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,11 +155,13 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_arena(this), is_fatal_error(0), - last_insert_id_used(0), - insert_id_used(0), rand_used(0), time_zone_used(0), - in_lock_tables(0), global_read_lock(0), bootstrap(0) +THD::THD() + :user_time(0), global_read_lock(0), is_fatal_error(0), + last_insert_id_used(0), + insert_id_used(0), rand_used(0), time_zone_used(0), + in_lock_tables(0), bootstrap(0) { + current_arena= this; host= user= priv_user= db= ip=0; host_or_ip= "connecting host"; locked=some_tables_deleted=no_errors=password= 0; @@ -439,10 +441,13 @@ void THD::awake(bool prepare_to_die) it is the true value but maybe current_mutex is not yet non-zero (we're in the middle of enter_cond() and there is a "memory order inversion"). So we test the mutex too to not lock 0. + Note that there is a small chance we fail to kill. If victim has locked - current_mutex, and hasn't entered enter_cond(), then we don't know it's - going to wait on cond. Then victim goes into its cond "forever" (until - we issue a second KILL). True we have set its thd->killed but it may not + current_mutex, but hasn't yet entered enter_cond() (which means that + current_cond and current_mutex are 0), then the victim will not get + a signal and it may wait "forever" on the cond (until + we issue a second KILL or the status it's waiting for happens). + It's true that we have set its thd->killed but it may not see it immediately and so may have time to reach the cond_wait(). */ if (mysys_var->current_cond && mysys_var->current_mutex) -- cgit v1.2.1 From dd5022c0f2ea3fde8b365a4c923faa3d57c12321 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 20:17:11 +0400 Subject: Fix for Bug#5034 "prepared "select 1 into @arg15", second execute crashes server": we were deleting lex->result after each execute, but prepared statements assumed that it's left intact. The fix adds cleanup() method to select_result hierarchy, so that result objects can be reused. Plus we now need to delete result objects more wisely. mysql-test/r/ps.result: Test results fixed: test case for bug#5034 mysql-test/t/ps.test: A test case for bug#5034, few followups sql/sql_class.cc: - fix warning in THD::THD - implementation of cleanup() for select_result hierarchy - select_export::send_eof was identical to select_dump::send_eof: moved to the base class select_to_file. - Statement::end_statement() to end lex, free items, and delete possible select_result sql/sql_class.h: - select_result::cleanup() declaration - sql/sql_insert.cc: - implementation of select_insert::cleanup(): currently we always create a new instance of select_insert/ select_create on each execute. sql/sql_lex.cc: - with more complicated logic of freeing lex->result it's easier to have it non-zero only if it points to a valid result. sql/sql_lex.h: Now st_lex::st_lex is not empty. sql/sql_parse.cc: mysql_execute_command(): - delete select_result *result only if it was created in this function. - use end_statement() to cleanup lex and thd in the end of each statement. - no need to save THD::lock if this is explain. This save apparently left from times when derived tables were materialized here, not in open_and_lock_tables. sql/sql_prepare.cc: - call result->cleanup() in reset_stmt_for_execute - now Statement is responsible for freeing its lex->result. sql/sql_select.cc: handle_select(): - don't delete result, it might be needed for next executions - result is never null --- sql/sql_class.cc | 84 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 27 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..07df83b78e7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,10 +155,10 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_arena(this), is_fatal_error(0), - last_insert_id_used(0), +THD::THD():user_time(0), current_arena(this), global_read_lock(0), + is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), time_zone_used(0), - in_lock_tables(0), global_read_lock(0), bootstrap(0) + in_lock_tables(0), bootstrap(0) { host= user= priv_user= db= ip=0; host_or_ip= "connecting host"; @@ -703,6 +703,12 @@ void select_result::send_error(uint errcode,const char *err) ::send_error(thd, errcode, err); } + +void select_result::cleanup() +{ + /* do nothing */ +} + static String default_line_term("\n",default_charset_info); static String default_escaped("\\",default_charset_info); static String default_field_term("\t",default_charset_info); @@ -808,6 +814,32 @@ void select_to_file::send_error(uint errcode,const char *err) } +bool select_to_file::send_eof() +{ + int error= test(end_io_cache(&cache)); + if (my_close(file,MYF(MY_WME))) + error= 1; + if (!error) + ::send_ok(thd,row_count); + file= -1; + return error; +} + + +void select_to_file::cleanup() +{ + /* In case of error send_eof() may be not called: close the file here. */ + if (file >= 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + file= -1; + } + path[0]= '\0'; + row_count= 0; +} + + select_to_file::~select_to_file() { if (file >= 0) @@ -1058,18 +1090,6 @@ err: } -bool select_export::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - /*************************************************************************** ** Dump of select to a binary file ***************************************************************************/ @@ -1123,18 +1143,6 @@ err: } -bool select_dump::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; @@ -1301,6 +1309,13 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } +void select_dumpvar::cleanup() +{ + vars.empty(); + row_count=0; +} + + Item_arena::Item_arena(THD* thd) :free_list(0), state(INITIALIZED) @@ -1405,6 +1420,21 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) } +void Statement::end_statement() +{ + /* Cleanup SQL processing state to resuse this statement in next query. */ + lex_end(lex); + delete lex->result; + lex->result= 0; + free_items(free_list); + free_list= 0; + /* + Don't free mem_root, as mem_root is freed in the end of dispatch_command + (once for any command). + */ +} + + void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); -- cgit v1.2.1 From 44d1bf72a4734621dab5216c857fb9d1a0f0cc0e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 22:45:32 +0500 Subject: Fix for bug #4815 (embedded server calculates wrong places for outfiles) In some places in mysqld behaviour depends on system working directory It works badly in libmysqld because user can set it in the way he needs. I think we should explicitly insert mysql_real_data_home value in paths in these places sql/sql_class.cc: here we concat mysql_real_data_home and thd->db to be the prefix sql/sql_load.cc: it's better to build the prefix from mysql_real_data_home also i think it's better always to call my_load_path to not to depend of current system working directory --- sql/sql_class.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index aecb2ef6522..80b9d6e20bf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -854,12 +854,21 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, { File file; uint option= MY_UNPACK_FILENAME; + char buff[FN_REFLEN]; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|= MY_REPLACE_DIR; // Force use of db directory #endif - (void) fn_format(path, exchange->file_name, thd->db ? thd->db : "", "", - option); + + char *cnt= strmake(buff, mysql_real_data_home, FN_REFLEN); + *cnt= FN_LIBCHAR; + cnt++; + cnt= strmake(cnt, thd->db ? thd->db : "", FN_REFLEN - (cnt-buff)); + *cnt= FN_LIBCHAR; + cnt++; + *cnt= 0; + + (void) fn_format(path, exchange->file_name, buff, "", option); if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); -- cgit v1.2.1 From 44b9a3b27f26e572abeae7ba25d2517685b63ccd Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Aug 2004 19:44:28 +0400 Subject: Fix for BUG#5242: Made SQL Syntax Prepared Statement names case-insensitive. mysql-test/r/ps.result: Testcase for BUG#5242 mysql-test/t/ps.test: Testcase for BUG#5242 --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 26e2cebb909..c7d8e81d11b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1503,7 +1503,7 @@ Statement_map::Statement_map() : hash_init(&st_hash, default_charset_info, START_STMT_HASH_SIZE, 0, 0, get_statement_id_as_hash_key, delete_statement_as_hash_key, MYF(0)); - hash_init(&names_hash, &my_charset_bin, START_NAME_HASH_SIZE, 0, 0, + hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0, (hash_get_key) get_stmt_name_hash_key, NULL,MYF(0)); } -- cgit v1.2.1 From e7622b1071247b7fa48e6623a0858589b375d72f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 14:07:02 +0400 Subject: Change Item_arena::state to enum --- sql/sql_class.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 26e2cebb909..79c28d94127 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1323,7 +1323,7 @@ void select_dumpvar::cleanup() Item_arena::Item_arena(THD* thd) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, @@ -1335,7 +1335,7 @@ Item_arena::Item_arena(THD* thd) Item_arena::Item_arena() :free_list(0), - state((int)CONVENTIONAL_EXECUTION) + state(CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } @@ -1343,7 +1343,7 @@ Item_arena::Item_arena() Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { if (init_mem_root) clear_alloc_root(&mem_root); -- cgit v1.2.1 From d08d32bc6415a2ccb2234d9b87aa63b655c7e152 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 11:10:26 +0500 Subject: Addition to the fix for #4815 sql/sql_class.cc: Code simplified with strxnmov --- sql/sql_class.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 80b9d6e20bf..b6b9a316cc6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -854,21 +854,13 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, { File file; uint option= MY_UNPACK_FILENAME; - char buff[FN_REFLEN]; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|= MY_REPLACE_DIR; // Force use of db directory #endif - char *cnt= strmake(buff, mysql_real_data_home, FN_REFLEN); - *cnt= FN_LIBCHAR; - cnt++; - cnt= strmake(cnt, thd->db ? thd->db : "", FN_REFLEN - (cnt-buff)); - *cnt= FN_LIBCHAR; - cnt++; - *cnt= 0; - - (void) fn_format(path, exchange->file_name, buff, "", option); + strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : ""); + (void) fn_format(path, exchange->file_name, path, "", option); if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); -- cgit v1.2.1 From f2f12233d83c33be92ce2644d5c6200238b88dc8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 02:25:27 +0300 Subject: Remove extra '/' after mysql_real_data_home Add missing parameter to strxnmov() that caused some INTO OUTFILE commands to core dump mysql-test/mysql-test-run.sh: Ensure that clients used the supplied --socket argument mysql-test/r/lowercase_table.result: Remove tables used in other tests that may affect this one mysql-test/r/rename.result: Remove tables used in other tests that may affect this one mysql-test/t/lowercase_table.test: Remove tables used in other tests that may affect this one mysql-test/t/rename.test: Remove tables used in other tests that may affect this one sql/item_cmpfunc.cc: Remove not relevant comment sql/sql_class.cc: Add missing parameter to strxnmov() that caused some INTO OUTFILE commands to core dump sql/sql_load.cc: Remove extra '/' after mysql_real_data_home sql/sql_table.cc: Remove extra '/' after mysql_real_data_home --- sql/sql_class.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 36b1b89f6bf..b103ee29095 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -891,7 +891,8 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, option|= MY_REPLACE_DIR; // Force use of db directory #endif - strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : ""); + strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : "", + NullS); (void) fn_format(path, exchange->file_name, path, "", option); if (!access(path, F_OK)) { -- cgit v1.2.1