diff options
author | Michael Widenius <monty@askmonty.org> | 2010-09-03 19:20:30 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-09-03 19:20:30 +0300 |
commit | a4fff491eb7f8be7c635287377c57eeff1dd6e89 (patch) | |
tree | 683f4f0603bcac2b3eeefef2f9861714d4578bef /sql/sql_table.cc | |
parent | ee5551e644cfae6bc1c95df0ff98d70a666dfdd2 (diff) | |
download | mariadb-git-a4fff491eb7f8be7c635287377c57eeff1dd6e89.tar.gz |
Fix that one can run mysql_upgrade with long table names
Fall back to use ALTER TABLE for engines that doesn't support REPAIR when doing repair for upgrade.
Nicer output from mysql_upgrade and mysql_check
Updated all arrays that used NAME_LEN to use SAFE_NAME_LEN to ensure that we don't break things accidently as names can now have a #mysql50# prefix.
client/mysql_upgrade.c:
If we are using verbose, also run mysqlcheck in verbose mode.
client/mysqlcheck.c:
Add more information if running in verbose mode
Print 'Needs upgrade' instead of complex error if table needs to be upgraded
Don't write connect information if verbose is not 2 or above
mysql-test/r/drop.result:
Updated test and results as we now support full table names
mysql-test/r/grant.result:
Now you get a correct error message if using #mysql with paths
mysql-test/r/show_check.result:
Update results as table names can temporarly be bigger than NAME_LEN (during upgrade)
mysql-test/r/upgrade.result:
Test upgrade for long table names.
mysql-test/suite/funcs_1/r/is_tables_is.result:
Updated old test result (had note been updated in a while)
mysql-test/t/drop.test:
Updated test and results as we now support full table names
mysql-test/t/grant.test:
Now you get a correct error message if using #mysql with paths
mysql-test/t/upgrade.test:
Test upgrade for long table names.
sql/ha_partition.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/item.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/log_event.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/mysql_priv.h:
Added SAFE_NAME_LEN
sql/rpl_filter.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sp.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sp_head.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_acl.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_base.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_connect.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_parse.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_prepare.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_select.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_show.cc:
NAME_LEN -> SAFE_NAME_LEN
Enlarge table names for SHOW TABLES to also include optional #mysql50#
sql/sql_table.cc:
Fall back to use ALTER TABLE for engines that doesn't support REPAIR when doing repair for upgrade.
sql/sql_trigger.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_udf.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/sql_view.cc:
NAME_LEN -> SAFE_NAME_LEN
sql/table.cc:
Fixed check_table_name() to not count #mysql50# as part of name
If #mysql50# is part of the name, don't allow path characters in name.
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1d3bb23cc3d..a0621dbbdcf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,6 +54,7 @@ static bool mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); +static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list); #ifndef DBUG_OFF @@ -4172,7 +4173,7 @@ mysql_rename_table(handlerton *base, const char *old_db, char from[FN_REFLEN + 1], to[FN_REFLEN + 1], lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1]; char *from_base= from, *to_base= to; - char tmp_name[NAME_LEN+1]; + char tmp_name[SAFE_NAME_LEN+1]; handler *file; int error=0; DBUG_ENTER("mysql_rename_table"); @@ -4567,6 +4568,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, Protocol *protocol= thd->protocol; LEX *lex= thd->lex; int result_code; + bool need_repair_or_alter= 0; DBUG_ENTER("mysql_admin_table"); if (end_active_trans(thd)) @@ -4587,7 +4589,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, for (table= tables; table; table= table->next_local) { - char table_name[NAME_LEN*2+2]; + char table_name[SAFE_NAME_LEN*2+2]; char* db = table->db; bool fatal_error=0; @@ -4795,32 +4797,35 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (operator_func == &handler::ha_repair && !(check_opt->sql_flags & TT_USEFRM)) { - if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) || - (table->table->file->ha_check_for_upgrade(check_opt) == - HA_ADMIN_NEEDS_ALTER)) + handler *file= table->table->file; + int check_old_types= file->check_old_types(); + int check_for_upgrade= file->ha_check_for_upgrade(check_opt); + + if (check_old_types == HA_ADMIN_NEEDS_ALTER || + check_for_upgrade == HA_ADMIN_NEEDS_ALTER) { - DBUG_PRINT("admin", ("recreating table")); - ha_autocommit_or_rollback(thd, 1); - close_thread_tables(thd); - tmp_disable_binlog(thd); // binlogging is done by caller if wanted - result_code= mysql_recreate_table(thd, table); - reenable_binlog(thd); - /* - mysql_recreate_table() can push OK or ERROR. - Clear 'OK' status. If there is an error, keep it: - we will store the error message in a result set row - and then clear. - */ - if (thd->main_da.is_ok()) - thd->main_da.reset_diagnostics_area(); + result_code= admin_recreate_table(thd, table); goto send_result; } + if (check_old_types || check_for_upgrade) + { + /* If repair is not implemented for the engine, run ALTER TABLE */ + need_repair_or_alter= 1; + } } DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name)); result_code = (table->table->file->*operator_func)(thd, check_opt); DBUG_PRINT("admin", ("operator_func returned: %d", result_code)); + if (result_code == HA_ADMIN_NOT_IMPLEMENTED && need_repair_or_alter) + { + /* + repair was not implemented and we need to upgrade the table + to a new version so we recreate the table with ALTER TABLE + */ + result_code= admin_recreate_table(thd, table); + } send_result: lex->cleanup_after_one_table_open(); @@ -4920,23 +4925,13 @@ send_result_message: system_charset_info); if (protocol->write()) goto err; - ha_autocommit_or_rollback(thd, 0); - close_thread_tables(thd); DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze...")); TABLE_LIST *save_next_local= table->next_local, *save_next_global= table->next_global; table->next_local= table->next_global= 0; - tmp_disable_binlog(thd); // binlogging is done by caller if wanted - result_code= mysql_recreate_table(thd, table); - reenable_binlog(thd); - /* - mysql_recreate_table() can push OK or ERROR. - Clear 'OK' status. If there is an error, keep it: - we will store the error message in a result set row - and then clear. - */ - if (thd->main_da.is_ok()) - thd->main_da.reset_diagnostics_area(); + + result_code= admin_recreate_table(thd, table); + ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); if (!result_code) // recreation went ok @@ -7954,6 +7949,30 @@ err: } +/* Prepare, run and cleanup for mysql_recreate_table() */ + +static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list) +{ + bool result_code; + DBUG_ENTER("admin_recreate_table"); + + ha_autocommit_or_rollback(thd, 1); + close_thread_tables(thd); + tmp_disable_binlog(thd); // binlogging is done by caller if wanted + result_code= mysql_recreate_table(thd, table_list); + reenable_binlog(thd); + /* + mysql_recreate_table() can push OK or ERROR. + Clear 'OK' status. If there is an error, keep it: + we will store the error message in a result set row + and then clear. + */ + if (thd->main_da.is_ok()) + thd->main_da.reset_diagnostics_area(); + DBUG_RETURN(result_code); +} + + /* Recreates tables by calling mysql_alter_table(). @@ -8010,7 +8029,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, /* Open one table after the other to keep lock time as short as possible. */ for (table= tables; table; table= table->next_local) { - char table_name[NAME_LEN*2+2]; + char table_name[SAFE_NAME_LEN*2+2]; TABLE *t; strxmov(table_name, table->db ,".", table->table_name, NullS); |