From cbd1bd90786025b98b9e510f770c5e3a0f3b23c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Dec 2006 21:08:25 -0800 Subject: [PATCH 1/6] Fixed bug #25027. Blocked evaluation of constant objects of the classes Item_func_is_null and Item_is_not_null_test at the prepare phase in the cases when the objects used subqueries. mysql-test/r/ps.result: Extended test case for bug #25027. mysql-test/t/ps.test: Extended test case for bug #25027. sql/sql_lex.cc: Returned back the assertion in st_select_lex_unit::set_limit, removed by the previous commit for this bug. --- mysql-test/r/ps.result | 7 +++++++ mysql-test/t/ps.test | 7 ++++++- sql/item_cmpfunc.cc | 6 +++--- sql/item_cmpfunc.h | 3 ++- sql/sql_lex.cc | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index b5a9367c985..000a9317b8d 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1528,5 +1528,12 @@ a 1 2 DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2 limit ?) IS NULL'; +SET @arg=1; +EXECUTE stmt USING @arg; +a +1 +2 +DEALLOCATE PREPARE stmt; DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9386436a1fd..f6de2a40efa 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1577,8 +1577,13 @@ SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL; PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL'; EXECUTE stmt; - DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2 limit ?) IS NULL'; +SET @arg=1; +EXECUTE stmt USING @arg; +DEALLOCATE PREPARE stmt; + DROP TABLE t1,t2; --echo End of 5.0 tests. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 29fa049b6c4..0a7cbbb51cb 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2990,7 +2990,7 @@ longlong Item_func_isnull::val_int() Handle optimization if the argument can't be null This has to be here because of the test in update_used_tables(). */ - if (!used_tables_cache) + if (!used_tables_cache && !with_subselect) return cached_value; return args[0]->is_null() ? 1: 0; } @@ -2999,7 +2999,7 @@ longlong Item_is_not_null_test::val_int() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_is_not_null_test::val_int"); - if (!used_tables_cache) + if (!used_tables_cache && !with_subselect) { owner->was_null|= (!cached_value); DBUG_PRINT("info", ("cached :%ld", (long) cached_value)); @@ -3026,7 +3026,7 @@ void Item_is_not_null_test::update_used_tables() else { args[0]->update_used_tables(); - if (!(used_tables_cache=args[0]->used_tables())) + if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect) { /* Remember if the value is always NULL or never NULL */ cached_value= (longlong) !args[0]->is_null(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index acad1e51bc9..faeee0d5567 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1028,7 +1028,8 @@ public: else { args[0]->update_used_tables(); - if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()))) + if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) && + !with_subselect) { /* Remember if the value is always NULL or never NULL */ cached_value= (longlong) args[0]->is_null(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f5ec0c1161d..3de842c8551 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1903,6 +1903,7 @@ void st_select_lex_unit::set_limit(SELECT_LEX *sl) { ha_rows select_limit_val; + DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare()); select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR); offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() : From 42010cde4ad923b03788e430646c0ff395069f01 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Jan 2007 12:16:03 -0800 Subject: [PATCH 2/6] Fixed bug #24345. This bug appeared after the patch for bug 21390 that had added some code to handle outer joins with no matches after substitution of a const table in an efficient way. That code as it is cannot be applied to the case of nested outer join operations. Being applied to the queries with nested outer joins the code can cause crashes or wrong result sets. The fix blocks row substitution for const inner tables of an outer join if the inner operand is not a single table. mysql-test/r/join_nested.result: Added a test case for bug #24345. mysql-test/t/join_nested.test: Added a test case for bug #24345. --- mysql-test/r/join_nested.result | 43 +++++++++++++++++++++++++++ mysql-test/t/join_nested.test | 51 +++++++++++++++++++++++++++++++++ sql/sql_select.cc | 12 +++++++- 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 0747418111b..f5c98f383b7 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1562,3 +1562,46 @@ id ngroupbynsa 2 1 2 1 DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 ( +id int NOT NULL PRIMARY KEY, +ct int DEFAULT NULL, +pc int DEFAULT NULL, +INDEX idx_ct (ct), +INDEX idx_pc (pc) +); +INSERT INTO t1 VALUES +(1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL); +CREATE TABLE t2 ( +id int NOT NULL PRIMARY KEY, +sr int NOT NULL, +nm varchar(255) NOT NULL, +INDEX idx_sr (sr) +); +INSERT INTO t2 VALUES +(2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand'); +CREATE TABLE t3 ( +id int NOT NULL PRIMARY KEY, +ct int NOT NULL, +ln int NOT NULL, +INDEX idx_ct (ct), +INDEX idx_ln (ln) +); +CREATE TABLE t4 ( +id int NOT NULL PRIMARY KEY, +nm varchar(255) NOT NULL +); +INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique'); +SELECT t1.* +FROM t1 LEFT JOIN +(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id +WHERE t1.id='5'; +id ct pc +5 NULL NULL +SELECT t1.*, t4.nm +FROM t1 LEFT JOIN +(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id +LEFT JOIN t4 ON t2.sr=t4.id +WHERE t1.id='5'; +id ct pc nm +5 NULL NULL NULL +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 69886d035bf..e7405418be7 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -994,3 +994,54 @@ SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa DROP TABLE t1,t2,t3,t4,t5; +# +# Test for bug #24345: crash with nested left outer join when outer table is substituted +# for a row that happens to have a null value for the join attribute. +# + +CREATE TABLE t1 ( + id int NOT NULL PRIMARY KEY, + ct int DEFAULT NULL, + pc int DEFAULT NULL, + INDEX idx_ct (ct), + INDEX idx_pc (pc) +); +INSERT INTO t1 VALUES + (1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL); + +CREATE TABLE t2 ( + id int NOT NULL PRIMARY KEY, + sr int NOT NULL, + nm varchar(255) NOT NULL, + INDEX idx_sr (sr) +); +INSERT INTO t2 VALUES + (2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand'); + +CREATE TABLE t3 ( + id int NOT NULL PRIMARY KEY, + ct int NOT NULL, + ln int NOT NULL, + INDEX idx_ct (ct), + INDEX idx_ln (ln) +); + +CREATE TABLE t4 ( + id int NOT NULL PRIMARY KEY, + nm varchar(255) NOT NULL +); + +INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique'); + +SELECT t1.* + FROM t1 LEFT JOIN + (t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id + WHERE t1.id='5'; + +SELECT t1.*, t4.nm + FROM t1 LEFT JOIN + (t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id + LEFT JOIN t4 ON t2.sr=t4.id + WHERE t1.id='5'; + +DROP TABLE t1,t2,t3,t4; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d2f46a9982..f175f770b55 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2306,8 +2306,18 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, substitution of a const table the key value happens to be null then we can state that there are no matches for this equi-join. */ - if ((keyuse= s->keyuse) && *s->on_expr_ref) + if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map) { + /* + When performing an outer join operation if there are no matching rows + for the single row of the outer table all the inner tables are to be + null complemented and thus considered as constant tables. + Here we apply this consideration to the case of outer join operations + with a single inner table only because the case with nested tables + would require a more thorough analysis. + TODO. Apply single row substitution to null complemented inner tables + for nested outer join operations. + */ while (keyuse->table == table) { if (!(keyuse->val->used_tables() & ~join->const_table_map) && From 78dff026afa9ff1fbb02f6f2acc1569895f9c371 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Jan 2007 22:35:30 +0300 Subject: [PATCH 3/6] Bug#14171: Wrong internal default value for a BINARY field. A BINARY field is represented by the Field_string class. The space character is used as the filler for unused characters in such a field. But a BINARY field should use \x00 instead. Field_string:reset() now detects whether the current field is a BINARY one and if so uses the \x00 character as a default value filler. sql/field.h: Bug#14171: Wrong internal default value for a BINARY field. Field_string:reset() now detects whether the current field is a BINARY one and if so uses the \x00 character as a default value filler. mysql-test/r/type_binary.result: Added a test case for the bug#14171: Wrong internal default value for a BINARY field. mysql-test/t/type_binary.test: Added a test case for the bug#14171: Wrong internal default value for a BINARY field. --- mysql-test/r/type_binary.result | 9 +++++++++ mysql-test/t/type_binary.test | 8 ++++++++ sql/field.h | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result index 597defb7a9b..debf4ff8fb8 100644 --- a/mysql-test/r/type_binary.result +++ b/mysql-test/r/type_binary.result @@ -136,4 +136,13 @@ insert into t1 values(NULL, 0x412020); ERROR 22001: Data too long for column 'vb' at row 1 drop table t1; set @@sql_mode= @old_sql_mode; +create table t1(f1 int, f2 binary(2) not null, f3 char(2) not null); +insert into t1 set f1=1; +Warnings: +Warning 1364 Field 'f2' doesn't have a default value +Warning 1364 Field 'f3' doesn't have a default value +select hex(f2), hex(f3) from t1; +hex(f2) hex(f3) +0000 +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/type_binary.test b/mysql-test/t/type_binary.test index 1639aff4711..91eba9b328e 100644 --- a/mysql-test/t/type_binary.test +++ b/mysql-test/t/type_binary.test @@ -91,4 +91,12 @@ insert into t1 values(NULL, 0x412020); drop table t1; set @@sql_mode= @old_sql_mode; +# +# Bug#14171: Wrong default value for a BINARY field +# +create table t1(f1 int, f2 binary(2) not null, f3 char(2) not null); +insert into t1 set f1=1; +select hex(f2), hex(f3) from t1; +drop table t1; + --echo End of 5.0 tests diff --git a/sql/field.h b/sql/field.h index d4bcdf556cf..103b596ae77 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1034,7 +1034,8 @@ public: bool zero_pack() const { return 0; } int reset(void) { - charset()->cset->fill(charset(),ptr,field_length,' '); + charset()->cset->fill(charset(),ptr,field_length, + (has_charset() ? ' ' : 0)); return 0; } int store(const char *to,uint length,CHARSET_INFO *charset); From f094fe551a833f50fbac7092b069462a00856719 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Jan 2007 23:24:56 +0300 Subject: [PATCH 4/6] Fixed bug#16861: User defined variable can have a wrong value if a tmp table was used. The Item::save_in_field() function is called from fill_record() to fill the new row with data while execution of the CREATE TABLE ... SELECT statement. Item::save_in_field() calls val_xxx() methods in order to get values. val_xxx() methods do not take into account the result field. Due to this Item_func_set_user_var::val_xxx() methods returns values from the original table, not from the temporary one. The save_in_field() member function is added to the Item_func_set_user_var class. It detects whether the result field should be used and properly updates the value of the user variable. sql/item_func.cc: Bug#16861: User defined variable can have a wrong value if a tmp table was used. Added the save_in_field() member function to the Item_func_set_user_var class. sql/item_func.h: Bug#16861: User defined variable can have a wrong value if a tmp table was used. Added the save_in_field() member function to the Item_func_set_user_var class. mysql-test/r/user_var.result: Extended the test case for bug#18681: User defined variable can have a wrong value if a tmp table was used. mysql-test/t/user_var.test: Extended the test case for bug#18681: User defined variable can have a wrong value if a tmp table was used. --- mysql-test/r/user_var.result | 9 +++- mysql-test/t/user_var.test | 5 +- sql/item_func.cc | 99 ++++++++++++++++++++++++++++++++++++ sql/item_func.h | 1 + 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 90954fc1ede..753c982155c 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -301,7 +301,14 @@ select @var:=f2 from t1 group by f1 order by f2 desc limit 1; select @var; @var 3 -drop table t1; +create table t2 as select @var:=f2 from t1 group by f1 order by f2 desc limit 1; +select * from t2; +@var:=f2 +3 +select @var; +@var +3 +drop table t1,t2; insert into city 'blah'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''blah'' at line 1 SHOW COUNT(*) WARNINGS; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 65ca1b2c1b7..70f57fdf283 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -210,7 +210,10 @@ create table t1(f1 int, f2 int); insert into t1 values (1,2),(2,3),(3,1); select @var:=f2 from t1 group by f1 order by f2 desc limit 1; select @var; -drop table t1; +create table t2 as select @var:=f2 from t1 group by f1 order by f2 desc limit 1; +select * from t2; +select @var; +drop table t1,t2; # # Bug#19024 - SHOW COUNT(*) WARNINGS not return Errors diff --git a/sql/item_func.cc b/sql/item_func.cc index 0eab370237d..4138573785e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4056,6 +4056,105 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field) Item::make_field(tmp_field); } + +/* + Save the value of a user variable into a field + + SYNOPSIS + save_in_field() + field target field to save the value to + no_conversion flag indicating whether conversions are allowed + + DESCRIPTION + Save the function value into a field and update the user variable + accordingly. If a result field is defined and the target field doesn't + coincide with it then the value from the result field will be used as + the new value of the user variable. + + The reason to have this method rather than simply using the result + field in the val_xxx() methods is that the value from the result field + not always can be used when the result field is defined. + Let's consider the following cases: + 1) when filling a tmp table the result field is defined but the value of it + is undefined because it has to be produced yet. Thus we can't use it. + 2) on execution of an INSERT ... SELECT statement the save_in_field() + function will be called to fill the data in the new record. If the SELECT + part uses a tmp table then the result field is defined and should be + used in order to get the correct result. + + The difference between the SET_USER_VAR function and regular functions + like CONCAT is that the Item_func objects for the regular functions are + replaced by Item_field objects after the values of these functions have + been stored in a tmp table. Yet an object of the Item_field class cannot + be used to update a user variable. + Due to this we have to handle the result field in a special way here and + in the Item_func_set_user_var::send() function. + + RETURN VALUES + FALSE Ok + TRUE Error +*/ + +int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions) +{ + bool use_result_field= (result_field && result_field != field); + int error; + + /* Update the value of the user variable */ + check(use_result_field); + update(); + + if (result_type() == STRING_RESULT || + result_type() == REAL_RESULT && + field->result_type() == STRING_RESULT) + { + String *result; + CHARSET_INFO *cs= collation.collation; + char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns + str_value.set_quick(buff, sizeof(buff), cs); + result= entry->val_str(&null_value, &str_value, decimals); + + if (null_value) + { + str_value.set_quick(0, 0, cs); + return set_field_to_null_with_conversions(field, no_conversions); + } + + /* NOTE: If null_value == FALSE, "result" must be not NULL. */ + + field->set_notnull(); + error=field->store(result->ptr(),result->length(),cs); + str_value.set_quick(0, 0, cs); + } + else if (result_type() == REAL_RESULT) + { + double nr= entry->val_real(&null_value); + if (null_value) + return set_field_to_null(field); + field->set_notnull(); + error=field->store(nr); + } + else if (result_type() == DECIMAL_RESULT) + { + my_decimal decimal_value; + my_decimal *value= entry->val_decimal(&null_value, &decimal_value); + if (null_value) + return set_field_to_null(field); + field->set_notnull(); + error=field->store_decimal(value); + } + else + { + longlong nr= entry->val_int(&null_value); + if (null_value) + return set_field_to_null_with_conversions(field, no_conversions); + field->set_notnull(); + error=field->store(nr, unsigned_flag); + } + return error; +} + + String * Item_func_get_user_var::val_str(String *str) { diff --git a/sql/item_func.h b/sql/item_func.h index c116c18bc50..68591f9c6f5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1188,6 +1188,7 @@ public: void print(String *str); void print_as_stmt(String *str); const char *func_name() const { return "set_user_var"; } + int save_in_field(Field *field, bool no_conversions); }; From ac71a8fa5ee66e72aa55fdccecf1de97cdaefa7c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Jan 2007 12:57:03 +0400 Subject: [PATCH 5/6] Fix for bug#20867 InnoDB Bug - create temporary table+crash => mysqld needs to clean up 2nd version During tmp tables cleanup we get the handler for temporary table and delete table using handler method. sql/mysql_priv.h: added function prototype sql/mysqld.cc: added call of mysql_rm_tmp_tables() function sql/sql_base.cc: mysql_rm_tmp_tables() -removed from table_cache_init -During tmp tables cleanup we get the handler for temporary table and delete table using handler method. it allows to remove orphan records from data dictionary(InnoDB) --- sql/mysql_priv.h | 1 + sql/mysqld.cc | 2 +- sql/sql_base.cc | 42 +++++++++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8d6cdebe1f7..a12944437d7 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -861,6 +861,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, /* mysqld.cc */ extern void yyerror(const char*); +my_bool mysql_rm_tmp_tables(void); /* item_func.cc */ extern bool check_reserved_words(LEX_STRING *name); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cd0ddc00624..024e4682a22 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3241,7 +3241,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); */ error_handler_hook = my_message_sql; start_signal_handler(); // Creates pidfile - if (acl_init(opt_noacl) || + if (mysql_rm_tmp_tables() || acl_init(opt_noacl) || my_tz_init((THD *)0, default_tz_name, opt_bootstrap)) { abort_loop=1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c60bed09cf9..05ecfe9b484 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -34,7 +34,6 @@ HASH assign_cache; static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, const char *name, const char *alias); static void free_cache_entry(TABLE *entry); -static void mysql_rm_tmp_tables(void); extern "C" byte *table_cache_key(const byte *record,uint *length, @@ -47,7 +46,6 @@ extern "C" byte *table_cache_key(const byte *record,uint *length, bool table_cache_init(void) { - mysql_rm_tmp_tables(); return hash_init(&open_cache, &my_charset_bin, table_cache_size+16, 0, 0,table_cache_key, (hash_free_key) free_cache_entry, 0) != 0; @@ -2940,14 +2938,20 @@ fill_record(Field **ptr,List &values, bool ignore_errors) } -static void mysql_rm_tmp_tables(void) +my_bool mysql_rm_tmp_tables(void) { uint i, idx; - char filePath[FN_REFLEN], *tmpdir; + char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN]; MY_DIR *dirp; FILEINFO *file; + TABLE tmp_table; + THD *thd; DBUG_ENTER("mysql_rm_tmp_tables"); + if (!(thd= new THD)) + DBUG_RETURN(1); + thd->store_globals(); + for (i=0; i<=mysql_tmpdir_list.max; i++) { tmpdir=mysql_tmpdir_list.list[i]; @@ -2968,13 +2972,37 @@ static void mysql_rm_tmp_tables(void) if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) { - sprintf(filePath,"%s%s",tmpdir,file->name); - VOID(my_delete(filePath,MYF(MY_WME))); + char *ext= fn_ext(file->name); + uint ext_len= strlen(ext); + uint filePath_len= my_snprintf(filePath, sizeof(filePath), + "%s%s", tmpdir, file->name); + if (!bcmp(reg_ext, ext, ext_len)) + { + TABLE tmp_table; + if (!openfrm(filePath, "tmp_table", (uint) 0, + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, + 0, &tmp_table)) + { + /* We should cut file extention before deleting of table */ + memcpy(filePathCopy, filePath, filePath_len - ext_len); + filePathCopy[filePath_len - ext_len]= 0; + tmp_table.file->delete_table(filePathCopy); + closefrm(&tmp_table); + } + } + /* + File can be already deleted by tmp_table.file->delete_table(). + So we hide error messages which happnes during deleting of these + files(MYF(0)). + */ + VOID(my_delete(filePath, MYF(0))); } } my_dirend(dirp); } - DBUG_VOID_RETURN; + delete thd; + my_pthread_setspecific_ptr(THR_THD, 0); + DBUG_RETURN(0); } From 53c9b0d07ce85870bfd8654a12b3a1934308fdef Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Jan 2007 14:03:36 +0400 Subject: [PATCH 6/6] after merge fix --- sql/sql_base.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6e93245c95f..5dcd596f6c2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5167,6 +5167,7 @@ my_bool mysql_rm_tmp_tables(void) if (!(thd= new THD)) DBUG_RETURN(1); + thd->thread_stack= (char*) &thd; thd->store_globals(); for (i=0; i<=mysql_tmpdir_list.max; i++) @@ -5196,7 +5197,7 @@ my_bool mysql_rm_tmp_tables(void) if (!bcmp(reg_ext, ext, ext_len)) { TABLE tmp_table; - if (!openfrm(filePath, "tmp_table", (uint) 0, + if (!openfrm(thd, filePath, "tmp_table", (uint) 0, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, 0, &tmp_table)) {