summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc108
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));