summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/partition_myisam.result2
-rw-r--r--mysql-test/r/partition_not_blackhole.result2
-rw-r--r--mysql-test/suite/percona/percona_innodb_fake_changes.result2
-rw-r--r--mysql-test/suite/percona/percona_innodb_fake_changes.test2
-rw-r--r--mysql-test/t/partition_myisam.test2
-rw-r--r--mysql-test/t/partition_not_blackhole.test2
-rw-r--r--sql/handler.cc85
-rw-r--r--sql/sql_table.cc28
8 files changed, 68 insertions, 57 deletions
diff --git a/mysql-test/r/partition_myisam.result b/mysql-test/r/partition_myisam.result
index 80b3a9511ea..bb1a7b19a9d 100644
--- a/mysql-test/r/partition_myisam.result
+++ b/mysql-test/r/partition_myisam.result
@@ -90,7 +90,7 @@ ERROR HY000: Failed to read from the .par file
# Note that it is currently impossible to drop a partitioned table
# without the .par file
DROP TABLE t1;
-ERROR 42S02: Unknown table 'test.t1'
+ERROR HY000: Got error 1 "Operation not permitted" from storage engine partition
#
# Bug#50392: insert_id is not reset for partitioned tables
# auto_increment on duplicate entry
diff --git a/mysql-test/r/partition_not_blackhole.result b/mysql-test/r/partition_not_blackhole.result
index 923d70c0ad6..7759f947c32 100644
--- a/mysql-test/r/partition_not_blackhole.result
+++ b/mysql-test/r/partition_not_blackhole.result
@@ -11,6 +11,6 @@ t1
SHOW CREATE TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
DROP TABLE t1;
-ERROR 42S02: Unknown table 'test.t1'
+ERROR HY000: Got error 1 "Operation not permitted" from storage engine partition
t1.frm
t1.par
diff --git a/mysql-test/suite/percona/percona_innodb_fake_changes.result b/mysql-test/suite/percona/percona_innodb_fake_changes.result
index 95f0c07cd11..1b870fdbb92 100644
--- a/mysql-test/suite/percona/percona_innodb_fake_changes.result
+++ b/mysql-test/suite/percona/percona_innodb_fake_changes.result
@@ -45,7 +45,7 @@ BEGIN;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`t2` (errno: 131 "Command not supported by database")
DROP TABLE t1;
-ERROR 42S02: Unknown table 'test.t1'
+ERROR HY000: Storage engine InnoDB of the table `test`.`t1` doesn't have this option
TRUNCATE TABLE t1;
ERROR HY000: Got error 131 "Command not supported by database" during COMMIT
ALTER TABLE t1 ENGINE=MyISAM;
diff --git a/mysql-test/suite/percona/percona_innodb_fake_changes.test b/mysql-test/suite/percona/percona_innodb_fake_changes.test
index 5fa3ecc7b63..67f5450ba45 100644
--- a/mysql-test/suite/percona/percona_innodb_fake_changes.test
+++ b/mysql-test/suite/percona/percona_innodb_fake_changes.test
@@ -38,7 +38,7 @@ SET innodb_fake_changes=1;
BEGIN;
--error 1005
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
---error 1051
+--error 1031
DROP TABLE t1;
--error 1180
TRUNCATE TABLE t1;
diff --git a/mysql-test/t/partition_myisam.test b/mysql-test/t/partition_myisam.test
index a33b9e19fbf..bce0c6f009c 100644
--- a/mysql-test/t/partition_myisam.test
+++ b/mysql-test/t/partition_myisam.test
@@ -123,7 +123,7 @@ CHECK TABLE t1;
SELECT * FROM t1;
--echo # Note that it is currently impossible to drop a partitioned table
--echo # without the .par file
---error ER_BAD_TABLE_ERROR
+--error ER_GET_ERRNO
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
diff --git a/mysql-test/t/partition_not_blackhole.test b/mysql-test/t/partition_not_blackhole.test
index 7352aeaa230..3731d659ad0 100644
--- a/mysql-test/t/partition_not_blackhole.test
+++ b/mysql-test/t/partition_not_blackhole.test
@@ -19,7 +19,7 @@ SHOW TABLES;
--replace_result $MYSQLD_DATADIR ./
--error ER_NOT_FORM_FILE
SHOW CREATE TABLE t1;
---error ER_BAD_TABLE_ERROR
+--error ER_GET_ERRNO
DROP TABLE t1;
--list_files $MYSQLD_DATADIR/test t1*
--remove_file $MYSQLD_DATADIR/test/t1.frm
diff --git a/sql/handler.cc b/sql/handler.cc
index 70bce6f3963..1f8daf3927b 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2298,9 +2298,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)
@@ -2315,47 +2317,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;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3a7930f6963..20cfccaa3d9 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2201,15 +2201,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
char path[FN_REFLEN + 1], wrong_tables_buff[160], *alias= NULL;
String wrong_tables(wrong_tables_buff, sizeof(wrong_tables_buff)-1,
system_charset_info);
- uint path_length= 0;
+ uint path_length= 0, errors= 0;
int error= 0;
int non_temp_tables_count= 0;
- bool foreign_key_error=0;
bool non_tmp_error= 0;
bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
bool non_tmp_table_deleted= 0;
bool is_drop_tmp_if_exists_added= 0;
- bool one_table= tables->next_local == 0;
bool was_view= 0;
String built_query;
String built_trans_tmp_query, built_non_trans_tmp_query;
@@ -2495,12 +2493,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
error= ha_delete_table(thd, table_type, path, db, table->table_name,
!dont_log_query);
- if (error == HA_ERR_ROW_IS_REFERENCED)
- {
- /* the table is referenced by a foreign key constraint */
- foreign_key_error= 1;
- }
- if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
+ if (!error)
{
int frm_delete_error, trigger_drop_error= 0;
/* Delete the table definition file */
@@ -2518,11 +2511,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (trigger_drop_error ||
(frm_delete_error && frm_delete_error != ENOENT))
error= 1;
- else if (!frm_delete_error || !error || if_exists)
- {
- error= 0;
+ else if (frm_delete_error && if_exists)
thd->clear_error();
- }
}
non_tmp_error= error ? TRUE : non_tmp_error;
}
@@ -2533,6 +2523,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
wrong_tables.append(db);
wrong_tables.append('.');
wrong_tables.append(table->table_name);
+ errors++;
}
else
{
@@ -2556,14 +2547,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
err:
if (wrong_tables.length())
{
- if (one_table && was_view)
+ DBUG_ASSERT(errors);
+ if (errors == 1 && was_view)
my_printf_error(ER_IT_IS_A_VIEW, ER(ER_IT_IS_A_VIEW), MYF(0),
wrong_tables.c_ptr_safe());
- else if (!foreign_key_error)
+ else if (errors > 1 || !thd->is_error())
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
wrong_tables.c_ptr_safe());
- else
- my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
error= 1;
}
@@ -2614,8 +2604,8 @@ err:
/* Chop of the last comma */
built_query.chop();
built_query.append(" /* generated by server */");
- int error_code = (non_tmp_error ?
- (foreign_key_error ? ER_ROW_IS_REFERENCED : ER_BAD_TABLE_ERROR) : 0);
+ int error_code = non_tmp_error ? thd->get_stmt_da()->sql_errno()
+ : 0;
error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
built_query.ptr(),
built_query.length(),