From 89bb3165501b09b2922d361905a4efb7b490d8b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2003 20:24:15 +0300 Subject: One test case, one bug fix and one new feature mysql-test/r/innodb.result: A test case for non-functional rollback after inserting a row into MyISAM table with binary log enabled. mysql-test/t/innodb.test: A test case for non-functional rollback after inserting a row into MyISAM table with binary log enabled. sql/sql_show.cc: Displaying disabled keys in SHOW KEYS sql/sql_table.cc: Fix for a serious bug with ALTER TABLE ENABLE / DISABLE KEYS --- sql/sql_table.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0cdb0a7ff48..8cec738edb0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -912,12 +912,9 @@ mysql_rename_table(enum db_type base, Win32 clients must also have a WRITE LOCK on the table ! */ -bool close_cached_table(THD *thd,TABLE *table) +static void safe_remove_from_cache(THD *thd,TABLE *table) { - bool result=0; - DBUG_ENTER("close_cached_table"); - safe_mutex_assert_owner(&LOCK_open); - + DBUG_ENTER("safe_remove_from_cache"); if (table) { DBUG_PRINT("enter",("table: %s", table->real_name)); @@ -940,7 +937,18 @@ bool close_cached_table(THD *thd,TABLE *table) #endif /* When lock on LOCK_open is freed other threads can continue */ pthread_cond_broadcast(&COND_refresh); + } + DBUG_VOID_RETURN; +} + +bool close_cached_table(THD *thd,TABLE *table) +{ + DBUG_ENTER("close_cached_table"); + safe_mutex_assert_owner(&LOCK_open); + if (table) + { + safe_remove_from_cache(thd,table); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { @@ -949,7 +957,7 @@ bool close_cached_table(THD *thd,TABLE *table) /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ thd->open_tables=unlink_open_table(thd,thd->open_tables,table); } - DBUG_RETURN(result); + DBUG_RETURN(0); } static int send_check_errmsg(THD* thd, TABLE_LIST* table, @@ -1456,9 +1464,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, case LEAVE_AS_IS: break; case ENABLE: - error=table->file->activate_all_index(thd); + safe_remove_from_cache(thd,table); + error= table->file->activate_all_index(thd); break; case DISABLE: + safe_remove_from_cache(thd,table); table->file->deactivate_non_unique_index(HA_POS_ERROR); break; } -- cgit v1.2.1 From b21a0be804fbff458ffbfff4e01f28f8730d3820 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Apr 2003 15:44:39 +0400 Subject: bug 283: FULLTEXT index on a TEXT filed converted to a CHAR field doesn't work anymore --- sql/sql_table.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0cdb0a7ff48..0fbb5807c57 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -569,6 +569,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, column->field_name); DBUG_RETURN(-1); } + /* for fulltext keys keyseg length is 1 for blobs (it's ignored in + ft code anyway, and 0 (set to column width later) for char's. + it has to be correct col width for char's, as char data are not + prefixed with length (unlike blobs, where ft code takes data length + from a data prefix, ignoring column->length). + */ + if (key->type == Key::FULLTEXT) + column->length=test(f_is_blob(sql_field->pack_flag)); if (f_is_blob(sql_field->pack_flag)) { if (!(file->table_flags() & HA_BLOB_KEY)) @@ -579,15 +587,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!column->length) { - if (key->type == Key::FULLTEXT) - column->length=1; /* ft-code ignores it anyway :-) */ - else - { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } + my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, + ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), + column->field_name); + DBUG_RETURN(-1); } } if (!(sql_field->flags & NOT_NULL_FLAG)) -- cgit v1.2.1 From f22be777341f53b4deb58851828c0733ab5380bf Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Apr 2003 22:12:08 +0300 Subject: Fixed problem when comparing a key for a multi-byte-character set. (bug 152) Use 0x.... as strings if 'new' mode. (bug 152) Don't report -max on windows when InnoDB is enabled. (bug 332) Reset current_linfo; This could cause a hang when doing PURGE LOGS. Fix for row numbers in EXPLAIN (bug 322) Fix that USE_FRM works for all table types (bug 97) VC++Files/libmysql/libmysql.dsp: Added new source files myisam/mi_key.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_range.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_rkey.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_search.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_test2.c: Fixed printf statements myisam/myisamdef.h: Fixed problem when comparing a key for a multi-byte-character set. myisam/sort.c: Fixed printf statements mysql-test/r/ctype_latin1_de.result: New test results mysql-test/r/join.result: New test results mysql-test/r/repair.result: New test results mysql-test/r/rpl_alter.result: New test results mysql-test/t/ctype_latin1_de-master.opt: --new is needed to get 0x... strings to work properly mysql-test/t/ctype_latin1_de.test: New test for latin1_de mysql-test/t/repair.test: Test of USE_FRM and HEAP tables sql/field.cc: Fixed problem when comparing a key for a multi-byte-character set. sql/item.cc: Use 0x.... as strings if 'new' mode sql/item.h: Use 0x.... as strings if 'new' mode sql/mysqld.cc: Don't report -max on windows when InnoDB is enabled. sql/sql_analyse.cc: Removed unused variable sql/sql_insert.cc: Removed debug message sql/sql_repl.cc: Reset current_linfo; This could cause a hang when doing PURGE LOGS. sql/sql_select.cc: Fix for row numbers in EXPLAIN sql/sql_table.cc: Fix that USE_FRM works for all table types (without strange errors) sql/sql_yacc.yy: Removed compiler warnings. --- sql/sql_table.cc | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0fbb5807c57..1b1b5112e0b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -23,6 +23,7 @@ #endif #include #include +#include #include #ifdef __WIN__ @@ -1046,12 +1047,31 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, } else { + /* + User gave us USE_FRM which means that the header in the index file is + trashed. + In this case we will try to fix the table the following way: + - Rename the data file to a temporary name + - Truncate the table + - Replace the new data file with the old one + - Run a normal repair using the new index file and the old data file + */ - char from[FN_REFLEN],tmp[FN_REFLEN]; - char* db = thd->db ? thd->db : table->db; + char from[FN_REFLEN],tmp[FN_REFLEN+32]; + const char **ext= table->table->file->bas_ext(); + MY_STAT stat_info; + + /* + Check if this is a table type that stores index and data separately, + like ISAM or MyISAM + */ + if (!ext[0] || !ext[1]) + DBUG_RETURN(0); // No data file + + strxmov(from, table->table->path, ext[1], NullS); // Name of data file + if (!my_stat(from, &stat_info, MYF(0))) + DBUG_RETURN(0); // Can't use USE_FRM flag - sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->real_name); - fn_format(from, from, "", MI_NAME_DEXT, 4); sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); pthread_mutex_lock(&LOCK_open); @@ -1067,7 +1087,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "repair", - "Failed renaming .MYD file")); + "Failed renaming data file")); } if (mysql_truncate(thd, table, 1)) { -- cgit v1.2.1 From 870397892be8a35afdb343c209be91cba117cee6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 May 2003 22:12:15 +0200 Subject: avoid sigsegv when open_ltable() fails in REPAIR ... USE_FRM --- sql/sql_table.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 94b37e164e7..745d9ea1084 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1049,6 +1049,11 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, { DBUG_ENTER("prepare_for_repair"); + if (!table->table) + { + DBUG_RETURN(send_check_errmsg(thd, table, "repair", "table is read-only or does not exists")); + } + if (!(check_opt->sql_flags & TT_USEFRM)) { DBUG_RETURN(0); -- cgit v1.2.1 From 563c32ccd1f5a212dfb270097c1dbd1cdc1be907 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 May 2003 19:16:30 +0200 Subject: Fix of bug 390: primary key now implies (silently) NOT NULL for key fields. --- sql/sql_table.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 745d9ea1084..90239c1c7ea 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -598,8 +598,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (key->type == Key::PRIMARY) { - my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0)); - DBUG_RETURN(-1); + /* Implicitly set primary key fields to NOT NULL for ISO conf. */ + sql_field->flags|= NOT_NULL_FLAG; + sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; } if (!(file->table_flags() & HA_NULL_KEY)) { -- cgit v1.2.1 From 13a23a879f3f2e9b3d09578e08802e6fe19f88f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 May 2003 01:27:26 +0300 Subject: Fix for MacOSX and symlinks Fix for USE_FRM and crashed index file configure.in: Fix for MacOSX and symlinks myisam/mi_open.c: Give better error message in case of of crashed index file mysql-test/r/repair.result: new test case mysql-test/r/update.result: new test case mysql-test/t/repair.test: Added test with crashed MyISAM index header mysql-test/t/update.test: Added test case from bugs system sql/handler.cc: Indentation changes sql/sql_table.cc: Fix for USE_FRM and crashed index file --- sql/sql_table.cc | 142 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 64 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 90239c1c7ea..07ec1d67538 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -946,6 +946,7 @@ static void safe_remove_from_cache(THD *thd,TABLE *table) DBUG_VOID_RETURN; } + bool close_cached_table(THD *thd,TABLE *table) { DBUG_ENTER("close_cached_table"); @@ -957,7 +958,8 @@ bool close_cached_table(THD *thd,TABLE *table) /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { - mysql_unlock_tables(thd, thd->lock); thd->lock=0; // Start locked threads + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; // Start locked threads } /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ thd->open_tables=unlink_open_table(thd,thd->open_tables,table); @@ -1045,93 +1047,105 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, } -static int prepare_for_repair(THD* thd, TABLE_LIST* table, +static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) { + int error= 0; + TABLE tmp_table, *table; DBUG_ENTER("prepare_for_repair"); - if (!table->table) - { - DBUG_RETURN(send_check_errmsg(thd, table, "repair", "table is read-only or does not exists")); - } - if (!(check_opt->sql_flags & TT_USEFRM)) - { DBUG_RETURN(0); - } - else + + if (!(table= table_list->table)) /* if open_ltable failed */ { - /* - User gave us USE_FRM which means that the header in the index file is - trashed. - In this case we will try to fix the table the following way: - - Rename the data file to a temporary name - - Truncate the table - - Replace the new data file with the old one - - Run a normal repair using the new index file and the old data file - */ + char name[FN_REFLEN]; + strxmov(name, mysql_data_home, "/", table_list->db, "/", + table_list->real_name, NullS); + if (openfrm(name, "", 0, 0, 0, &tmp_table)) + DBUG_RETURN(0); // Can't open frm file + table= &tmp_table; + } - char from[FN_REFLEN],tmp[FN_REFLEN+32]; - const char **ext= table->table->file->bas_ext(); - MY_STAT stat_info; + /* + User gave us USE_FRM which means that the header in the index file is + trashed. + In this case we will try to fix the table the following way: + - Rename the data file to a temporary name + - Truncate the table + - Replace the new data file with the old one + - Run a normal repair using the new index file and the old data file + */ - /* - Check if this is a table type that stores index and data separately, - like ISAM or MyISAM - */ - if (!ext[0] || !ext[1]) - DBUG_RETURN(0); // No data file + char from[FN_REFLEN],tmp[FN_REFLEN+32]; + const char **ext= table->file->bas_ext(); + MY_STAT stat_info; - strxmov(from, table->table->path, ext[1], NullS); // Name of data file - if (!my_stat(from, &stat_info, MYF(0))) - DBUG_RETURN(0); // Can't use USE_FRM flag + /* + Check if this is a table type that stores index and data separately, + like ISAM or MyISAM + */ + if (!ext[0] || !ext[1]) + goto end; // No data file - sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); + strxmov(from, table->path, ext[1], NullS); // Name of data file + if (!my_stat(from, &stat_info, MYF(0))) + goto end; // Can't use USE_FRM flag - pthread_mutex_lock(&LOCK_open); - close_cached_table(thd,table->table); - pthread_mutex_unlock(&LOCK_open); + sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); - if (lock_and_wait_for_table_name(thd,table)) - DBUG_RETURN(-1); + pthread_mutex_lock(&LOCK_open); + close_cached_table(thd,table_list->table); + pthread_mutex_unlock(&LOCK_open); - if (my_rename(from, tmp, MYF(MY_WME))) - { - pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, table); - pthread_mutex_unlock(&LOCK_open); - DBUG_RETURN(send_check_errmsg(thd, table, "repair", - "Failed renaming data file")); - } - if (mysql_truncate(thd, table, 1)) - { - pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, table); - pthread_mutex_unlock(&LOCK_open); - DBUG_RETURN(send_check_errmsg(thd, table, "repair", - "Failed generating table from .frm file")); - } - if (my_rename(tmp, from, MYF(MY_WME))) - { - pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, table); - pthread_mutex_unlock(&LOCK_open); - DBUG_RETURN(send_check_errmsg(thd, table, "repair", - "Failed restoring .MYD file")); - } + if (lock_and_wait_for_table_name(thd,table_list)) + { + error= -1; + goto end; + } + if (my_rename(from, tmp, MYF(MY_WME))) + { + pthread_mutex_lock(&LOCK_open); + unlock_table_name(thd, table_list); + pthread_mutex_unlock(&LOCK_open); + error= send_check_errmsg(thd, table_list, "repair", + "Failed renaming data file"); + goto end; + } + if (mysql_truncate(thd, table_list, 1)) + { + pthread_mutex_lock(&LOCK_open); + unlock_table_name(thd, table_list); + pthread_mutex_unlock(&LOCK_open); + error= send_check_errmsg(thd, table_list, "repair", + "Failed generating table from .frm file"); + goto end; + } + if (my_rename(tmp, from, MYF(MY_WME))) + { + pthread_mutex_lock(&LOCK_open); + unlock_table_name(thd, table_list); + pthread_mutex_unlock(&LOCK_open); + error= send_check_errmsg(thd, table_list, "repair", + "Failed restoring .MYD file"); + goto end; } /* Now we should be able to open the partially repaired table to finish the repair in the handler later on. */ - if (!(table->table = reopen_name_locked_table(thd, table))) + if (!(table_list->table = reopen_name_locked_table(thd, table_list))) { pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, table); + unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); } - DBUG_RETURN(0); + +end: + if (table == &tmp_table) + closefrm(table); // Free allocated memory + DBUG_RETURN(error); } -- cgit v1.2.1