diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 108 |
1 files changed, 98 insertions, 10 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ef05a472ab7..04cf6a479ec 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -238,10 +238,17 @@ uint explain_filename(THD* thd, { part_name_len= tmp_p - part_name - 1; subpart_name= tmp_p + 3; + tmp_p+= 3; + } + else if ((tmp_p[1] == 'Q' || tmp_p[1] == 'q') && + (tmp_p[2] == 'L' || tmp_p[2] == 'l') && + tmp_p[3] == '-') + { + name_type= TEMP; + tmp_p+= 4; /* sql- prefix found */ } else res= 2; - tmp_p+= 3; break; case 'T': case 't': @@ -1937,6 +1944,49 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, /** + Find the comment in the query. + That's auxiliary function to be used handling DROP TABLE [comment]. + + @param thd Thread handler + @param comment_pos How many characters to skip before the comment. + Can be either 9 for DROP TABLE or + 17 for DROP TABLE IF EXISTS + @param comment_start returns the beginning of the comment if found. + + @retval 0 no comment found + @retval >0 the lenght of the comment found + +*/ +static uint32 comment_length(THD *thd, uint32 comment_pos, + const char **comment_start) +{ + const char *query= thd->query(); + const char *query_end= query + thd->query_length(); + const uchar *const state_map= thd->charset()->state_map; + + for (; query < query_end; query++) + { + if (state_map[*query] == MY_LEX_SKIP) + continue; + if (comment_pos-- == 0) + break; + } + if (query > query_end - 3 /* comment can't be shorter than 4 */ || + state_map[*query] != MY_LEX_LONG_COMMENT || query[1] != '*') + return 0; + + *comment_start= query; + + for (query+= 3; query < query_end; query++) + { + if (query[-1] == '*' && query[0] == '/') + return query - *comment_start + 1; + } + return 0; +} + + +/** Execute the drop of a normal or temporary table. @param thd Thread handler @@ -2011,11 +2061,20 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { if (!drop_temporary) { + const char *comment_start; + uint32 comment_len; + built_query.set_charset(system_charset_info); if (if_exists) built_query.append("DROP TABLE IF EXISTS "); else built_query.append("DROP TABLE "); + + if ((comment_len= comment_length(thd, if_exists ? 17:9, &comment_start))) + { + built_query.append(comment_start, comment_len); + built_query.append(" "); + } } if (thd->is_current_stmt_binlog_format_row() || if_exists) @@ -6935,21 +6994,47 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP); } else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, - new_alias, FN_FROM_IS_TMP) || - ((new_name != table_name || new_db != db) && // we also do rename - (need_copy_table != ALTER_TABLE_METADATA_ONLY || - mysql_rename_table(save_old_db_type, db, table_name, new_db, - new_alias, NO_FRM_RENAME)) && - Table_triggers_list::change_table_name(thd, db, alias, table_name, - new_db, new_alias))) + new_alias, FN_FROM_IS_TMP)) { /* Try to get everything back. */ - error=1; - (void) quick_rm_table(new_db_type,new_db,new_alias, 0); + error= 1; (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP); (void) mysql_rename_table(old_db_type, db, old_name, db, alias, FN_FROM_IS_TMP); } + else if (new_name != table_name || new_db != db) + { + if (need_copy_table == ALTER_TABLE_METADATA_ONLY && + mysql_rename_table(save_old_db_type, db, table_name, new_db, + new_alias, NO_FRM_RENAME)) + { + /* Try to get everything back. */ + error= 1; + (void) quick_rm_table(new_db_type, new_db, new_alias, 0); + (void) mysql_rename_table(old_db_type, db, old_name, db, alias, + FN_FROM_IS_TMP); + } + else if (Table_triggers_list::change_table_name(thd, db, alias, + table_name, new_db, + new_alias)) + { + /* Try to get everything back. */ + error= 1; + (void) quick_rm_table(new_db_type, new_db, new_alias, 0); + (void) mysql_rename_table(old_db_type, db, old_name, db, + alias, FN_FROM_IS_TMP); + /* + If we were performing "fast"/in-place ALTER TABLE we also need + to restore old name of table in storage engine as a separate + step, as the above rename affects .FRM only. + */ + if (need_copy_table == ALTER_TABLE_METADATA_ONLY) + { + (void) mysql_rename_table(save_old_db_type, new_db, new_alias, + db, table_name, NO_FRM_RENAME); + } + } + } if (! error) (void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP); @@ -7369,7 +7454,10 @@ err: thd_progress_next_stage(thd); if (error > 0) + { + /* We are going to drop the temporary table */ to->file->extra(HA_EXTRA_PREPARE_FOR_DROP); + } if (errpos >= 3 && to->file->ha_end_bulk_insert() && error <= 0) { to->file->print_error(my_errno,MYF(0)); |