diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 85 |
1 files changed, 53 insertions, 32 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 8d69a93c2c1..d4d796b779d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2331,9 +2331,11 @@ handle_condition(THD *, } -/** @brief - This should return ENOENT if the file doesn't exists. - The .frm file will be deleted only if we return 0 or ENOENT +/** delete a table in the engine + + @note + ENOENT and HA_ERR_NO_SUCH_TABLE are not considered errors. + The .frm file will be deleted only if we return 0. */ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, const char *db, const char *alias, bool generate_warning) @@ -2348,47 +2350,66 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* table_type is NULL in ALTER TABLE when renaming only .frm files */ if (table_type == NULL || table_type == view_pseudo_hton || ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) - DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); + DBUG_RETURN(0); bzero((char*) &dummy_table, sizeof(dummy_table)); bzero((char*) &dummy_share, sizeof(dummy_share)); dummy_table.s= &dummy_share; path= get_canonical_filename(file, path, tmp_path); - if ((error= file->ha_delete_table(path)) && generate_warning) + if ((error= file->ha_delete_table(path))) { /* - Because file->print_error() use my_error() to generate the error message - we use an internal error handler to intercept it and store the text - in a temporary buffer. Later the message will be presented to user - as a warning. + it's not an error if the table doesn't exist in the engine. + warn the user, but still report DROP being a success */ - Ha_delete_table_error_handler ha_delete_table_error_handler; - - /* Fill up strucutures that print_error may need */ - dummy_share.path.str= (char*) path; - dummy_share.path.length= strlen(path); - dummy_share.normalized_path= dummy_share.path; - dummy_share.db.str= (char*) db; - dummy_share.db.length= strlen(db); - dummy_share.table_name.str= (char*) alias; - dummy_share.table_name.length= strlen(alias); - dummy_table.alias.set(alias, dummy_share.table_name.length, - table_alias_charset); + bool intercept= error == ENOENT || error == HA_ERR_NO_SUCH_TABLE; - file->change_table_ptr(&dummy_table, &dummy_share); - - thd->push_internal_handler(&ha_delete_table_error_handler); - file->print_error(error, 0); + if (!intercept || generate_warning) + { + /* + Because file->print_error() use my_error() to generate the error message + we use an internal error handler to intercept it and store the text + in a temporary buffer. Later the message will be presented to user + as a warning. + */ + Ha_delete_table_error_handler ha_delete_table_error_handler; + + /* Fill up strucutures that print_error may need */ + dummy_share.path.str= (char*) path; + dummy_share.path.length= strlen(path); + dummy_share.normalized_path= dummy_share.path; + dummy_share.db.str= (char*) db; + dummy_share.db.length= strlen(db); + dummy_share.table_name.str= (char*) alias; + dummy_share.table_name.length= strlen(alias); + dummy_table.alias.set(alias, dummy_share.table_name.length, + table_alias_charset); + + file->change_table_ptr(&dummy_table, &dummy_share); + +#if MYSQL_VERSION_ID > 100105 + // XXX as an ugly 10.0-only hack we intercept HA_ERR_ROW_IS_REFERENCED, + // to report it under the old historical error number. +#error remove HA_ERR_ROW_IS_REFERENCED, use ME_JUST_WARNING instead of a handler +#endif + if (intercept || error == HA_ERR_ROW_IS_REFERENCED) + thd->push_internal_handler(&ha_delete_table_error_handler); - thd->pop_internal_handler(); + file->print_error(error, 0); - /* - XXX: should we convert *all* errors to warnings here? - What if the error is fatal? - */ - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, error, - ha_delete_table_error_handler.buff); + if (intercept || error == HA_ERR_ROW_IS_REFERENCED) + { + thd->pop_internal_handler(); + if (error == HA_ERR_ROW_IS_REFERENCED) + my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); + else + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, error, + ha_delete_table_error_handler.buff); + } + } + if (intercept) + error= 0; } delete file; |