mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Generate warning in ha_delete_table() if files is missing in handler
mysql-test/r/myisam.result: Test of DROP TABLE when .MYI or .MYD is missing mysql-test/r/ndb_autodiscover.result: Update test results mysql-test/r/rpl_EE_error.result: Change test to conform with new handling of drop table when handler file is missing mysql-test/t/myisam.test: Test of DROP TABLE when .MYI or .MYD is missing mysql-test/t/rpl_EE_error.test: Change test to conform with new handling of drop table when handler file is missing sql/handler.cc: Generate a warning in ha_delete_table() if we get an error from 'delete_table()' sql/handler.h: More parameters to ha_delete_table() so that we can generate better error messages sql/sql_table.cc: Generate warning in ha_delete_table()
This commit is contained in:
@ -1150,3 +1150,15 @@ drop table t1;
|
|||||||
set storage_engine=MyISAM;
|
set storage_engine=MyISAM;
|
||||||
create table t1 (v varchar(65535));
|
create table t1 (v varchar(65535));
|
||||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
|
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
drop table if exists t1;
|
||||||
|
Warnings:
|
||||||
|
Error 2 Can't find file: 't1' (errno: 2)
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
drop table t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
drop table t1;
|
||||||
|
ERROR HY000: File './test/t1.MYD' not found (Errcode: 2)
|
||||||
|
drop table t1;
|
||||||
|
ERROR 42S02: Unknown table 't1'
|
||||||
|
@ -180,7 +180,7 @@ select * from t4;
|
|||||||
ERROR 42S02: Table 'test.t4' doesn't exist
|
ERROR 42S02: Table 'test.t4' doesn't exist
|
||||||
drop table if exists t4;
|
drop table if exists t4;
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1051 Unknown table 't4'
|
Error 155 Table 'test.t4' doesn't exist
|
||||||
drop table t5;
|
drop table t5;
|
||||||
ERROR 42S02: Unknown table 't5'
|
ERROR 42S02: Unknown table 't5'
|
||||||
drop table if exists t5;
|
drop table if exists t5;
|
||||||
|
@ -6,7 +6,9 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
|||||||
start slave;
|
start slave;
|
||||||
create table t1 (a int) engine=myisam;
|
create table t1 (a int) engine=myisam;
|
||||||
flush tables;
|
flush tables;
|
||||||
drop table t1;
|
drop table if exists t1;
|
||||||
|
Warnings:
|
||||||
|
Error 2 Can't find file: 't1' (errno: 2)
|
||||||
create table t1 (a int, unique(a)) engine=myisam;
|
create table t1 (a int, unique(a)) engine=myisam;
|
||||||
set sql_log_bin=0;
|
set sql_log_bin=0;
|
||||||
insert into t1 values(2);
|
insert into t1 values(2);
|
||||||
|
@ -539,3 +539,20 @@ eval set storage_engine=$default;
|
|||||||
# MyISAM specific varchar tests
|
# MyISAM specific varchar tests
|
||||||
--error 1118
|
--error 1118
|
||||||
create table t1 (v varchar(65535));
|
create table t1 (v varchar(65535));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test how DROP TABLE works if the index or data file doesn't exists
|
||||||
|
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
system rm ./var/master-data/test/t1.MYI ;
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
system rm ./var/master-data/test/t1.MYI ;
|
||||||
|
--error 1051
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int) engine=myisam;
|
||||||
|
system rm ./var/master-data/test/t1.MYD ;
|
||||||
|
--error 1105
|
||||||
|
drop table t1;
|
||||||
|
--error 1051
|
||||||
|
drop table t1;
|
||||||
|
@ -9,7 +9,7 @@ source include/master-slave.inc;
|
|||||||
create table t1 (a int) engine=myisam;
|
create table t1 (a int) engine=myisam;
|
||||||
flush tables;
|
flush tables;
|
||||||
system rm ./var/master-data/test/t1.MYI ;
|
system rm ./var/master-data/test/t1.MYI ;
|
||||||
drop table t1;
|
drop table if exists t1;
|
||||||
save_master_pos;
|
save_master_pos;
|
||||||
connection slave;
|
connection slave;
|
||||||
sync_with_master;
|
sync_with_master;
|
||||||
|
@ -1027,15 +1027,24 @@ bool ha_flush_logs()
|
|||||||
The .frm file will be deleted only if we return 0 or ENOENT
|
The .frm file will be deleted only if we return 0 or ENOENT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ha_delete_table(enum db_type table_type, const char *path)
|
int ha_delete_table(THD *thd, enum db_type table_type, const char *path,
|
||||||
|
const char *alias, bool generate_warning)
|
||||||
{
|
{
|
||||||
handler *file;
|
handler *file;
|
||||||
char tmp_path[FN_REFLEN];
|
char tmp_path[FN_REFLEN];
|
||||||
|
int error;
|
||||||
|
TABLE dummy_table;
|
||||||
|
TABLE_SHARE dummy_share;
|
||||||
|
DBUG_ENTER("ha_delete_table");
|
||||||
|
|
||||||
|
bzero((char*) &dummy_table, sizeof(dummy_table));
|
||||||
|
bzero((char*) &dummy_share, sizeof(dummy_share));
|
||||||
|
dummy_table.s= &dummy_share;
|
||||||
|
|
||||||
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
|
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
|
||||||
if (table_type == DB_TYPE_UNKNOWN ||
|
if (table_type == DB_TYPE_UNKNOWN ||
|
||||||
! (file=get_new_handler((TABLE*) 0, table_type)))
|
! (file=get_new_handler(&dummy_table, table_type)))
|
||||||
return ENOENT;
|
DBUG_RETURN(ENOENT);
|
||||||
|
|
||||||
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
||||||
{
|
{
|
||||||
@ -1044,9 +1053,45 @@ int ha_delete_table(enum db_type table_type, const char *path)
|
|||||||
my_casedn_str(files_charset_info, tmp_path);
|
my_casedn_str(files_charset_info, tmp_path);
|
||||||
path= tmp_path;
|
path= tmp_path;
|
||||||
}
|
}
|
||||||
int error=file->delete_table(path);
|
if ((error= file->delete_table(path)) && generate_warning)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Because file->print_error() use my_error() to generate the error message
|
||||||
|
we must store the error state in thd, reset it and restore it to
|
||||||
|
be able to get hold of the error message.
|
||||||
|
(We should in the future either rewrite handler::print_error() or make
|
||||||
|
a nice method of this.
|
||||||
|
*/
|
||||||
|
bool query_error= thd->query_error;
|
||||||
|
sp_rcontext *spcont= thd->spcont;
|
||||||
|
SELECT_LEX *current_select= thd->lex->current_select;
|
||||||
|
char buff[sizeof(thd->net.last_error)];
|
||||||
|
char new_error[sizeof(thd->net.last_error)];
|
||||||
|
int last_errno= thd->net.last_errno;
|
||||||
|
|
||||||
|
strmake(buff, thd->net.last_error, sizeof(buff)-1);
|
||||||
|
thd->query_error= 0;
|
||||||
|
thd->spcont= 0;
|
||||||
|
thd->lex->current_select= 0;
|
||||||
|
thd->net.last_error[0]= 0;
|
||||||
|
|
||||||
|
/* Fill up strucutures that print_error may need */
|
||||||
|
dummy_table.s->path= path;
|
||||||
|
dummy_table.alias= alias;
|
||||||
|
|
||||||
|
file->print_error(error, 0);
|
||||||
|
strmake(new_error, thd->net.last_error, sizeof(buff)-1);
|
||||||
|
|
||||||
|
/* restore thd */
|
||||||
|
thd->query_error= query_error;
|
||||||
|
thd->spcont= spcont;
|
||||||
|
thd->lex->current_select= current_select;
|
||||||
|
thd->net.last_errno= last_errno;
|
||||||
|
strmake(thd->net.last_error, buff, sizeof(buff)-1);
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, new_error);
|
||||||
|
}
|
||||||
delete file;
|
delete file;
|
||||||
return error;
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1320,7 +1365,16 @@ ulonglong handler::get_auto_increment()
|
|||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print error that we got from handler function */
|
|
||||||
|
/*
|
||||||
|
Print error that we got from handler function
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
In case of delete table it's only safe to use the following parts of
|
||||||
|
the 'table' structure:
|
||||||
|
table->s->path
|
||||||
|
table->alias
|
||||||
|
*/
|
||||||
|
|
||||||
void handler::print_error(int error, myf errflag)
|
void handler::print_error(int error, myf errflag)
|
||||||
{
|
{
|
||||||
@ -1529,7 +1583,7 @@ int handler::delete_table(const char *name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
enoent_or_zero= 0;
|
enoent_or_zero= 0; // No error for ENOENT
|
||||||
error= enoent_or_zero;
|
error= enoent_or_zero;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
@ -757,7 +757,8 @@ bool ha_flush_logs(void);
|
|||||||
void ha_drop_database(char* path);
|
void ha_drop_database(char* path);
|
||||||
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
||||||
bool update_create_info);
|
bool update_create_info);
|
||||||
int ha_delete_table(enum db_type db_type, const char *path);
|
int ha_delete_table(THD *thd, enum db_type db_type, const char *path,
|
||||||
|
const char *alias, bool generate_warning);
|
||||||
|
|
||||||
/* discovery */
|
/* discovery */
|
||||||
int ha_create_table_from_engine(THD* thd, const char *db, const char *name,
|
int ha_create_table_from_engine(THD* thd, const char *db, const char *name,
|
||||||
|
@ -113,7 +113,8 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
|
|||||||
thd Thread handle
|
thd Thread handle
|
||||||
tables List of tables to delete
|
tables List of tables to delete
|
||||||
if_exists If 1, don't give error if one table doesn't exists
|
if_exists If 1, don't give error if one table doesn't exists
|
||||||
dont_log_query Don't write query to log files
|
dont_log_query Don't write query to log files. This will also not
|
||||||
|
generate warnings if the handler files doesn't exists
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
Works like documented in mysql_rm_table(), but don't check
|
Works like documented in mysql_rm_table(), but don't check
|
||||||
@ -157,7 +158,8 @@ int mysql_rm_table_part2_with_lock(THD *thd,
|
|||||||
In this case we give an warning of level 'NOTE'
|
In this case we give an warning of level 'NOTE'
|
||||||
drop_temporary Only drop temporary tables
|
drop_temporary Only drop temporary tables
|
||||||
drop_view Allow to delete VIEW .frm
|
drop_view Allow to delete VIEW .frm
|
||||||
dont_log_query Don't log the query
|
dont_log_query Don't write query to log files. This will also not
|
||||||
|
generate warnings if the handler files doesn't exists
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
When logging to the binary log, we should log
|
When logging to the binary log, we should log
|
||||||
@ -234,16 +236,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
char *end;
|
char *end;
|
||||||
db_type table_type= get_table_type(path);
|
db_type table_type= get_table_type(path);
|
||||||
*(end=fn_ext(path))=0; // Remove extension for delete
|
*(end=fn_ext(path))=0; // Remove extension for delete
|
||||||
error=ha_delete_table(table_type, path);
|
error= ha_delete_table(thd, table_type, path, table->table_name,
|
||||||
|
!dont_log_query);
|
||||||
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
|
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
|
||||||
{
|
|
||||||
/* Warn that the table did not exist in engine */
|
|
||||||
if (error == HA_ERR_NO_SUCH_TABLE)
|
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
||||||
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
|
|
||||||
table->table_name);
|
|
||||||
error= 0;
|
error= 0;
|
||||||
}
|
|
||||||
if (error == HA_ERR_ROW_IS_REFERENCED)
|
if (error == HA_ERR_ROW_IS_REFERENCED)
|
||||||
{
|
{
|
||||||
/* the table is referenced by a foreign key constraint */
|
/* the table is referenced by a foreign key constraint */
|
||||||
@ -306,7 +302,7 @@ int quick_rm_table(enum db_type base,const char *db,
|
|||||||
error=1; /* purecov: inspected */
|
error=1; /* purecov: inspected */
|
||||||
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
|
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
|
||||||
unpack_filename(path,path);
|
unpack_filename(path,path);
|
||||||
return ha_delete_table(base,path) || error;
|
return ha_delete_table(current_thd, base, path, table_name, 0) || error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user