mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Generate warning in ha_delete_table() if files is missing in handler
This commit is contained in:
@ -1150,3 +1150,15 @@ drop table t1;
|
||||
set storage_engine=MyISAM;
|
||||
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
|
||||
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
|
||||
drop table if exists t4;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't4'
|
||||
Error 155 Table 'test.t4' doesn't exist
|
||||
drop table t5;
|
||||
ERROR 42S02: Unknown table '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;
|
||||
create table t1 (a int) engine=myisam;
|
||||
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;
|
||||
set sql_log_bin=0;
|
||||
insert into t1 values(2);
|
||||
|
@ -539,3 +539,20 @@ eval set storage_engine=$default;
|
||||
# MyISAM specific varchar tests
|
||||
--error 1118
|
||||
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;
|
||||
flush tables;
|
||||
system rm ./var/master-data/test/t1.MYI ;
|
||||
drop table t1;
|
||||
drop table if exists t1;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
@ -1027,15 +1027,24 @@ bool ha_flush_logs()
|
||||
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;
|
||||
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 */
|
||||
if (table_type == DB_TYPE_UNKNOWN ||
|
||||
! (file=get_new_handler((TABLE*) 0, table_type)))
|
||||
return ENOENT;
|
||||
! (file=get_new_handler(&dummy_table, table_type)))
|
||||
DBUG_RETURN(ENOENT);
|
||||
|
||||
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);
|
||||
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;
|
||||
return error;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1320,7 +1365,16 @@ ulonglong handler::get_auto_increment()
|
||||
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)
|
||||
{
|
||||
@ -1529,7 +1583,7 @@ int handler::delete_table(const char *name)
|
||||
break;
|
||||
}
|
||||
else
|
||||
enoent_or_zero= 0;
|
||||
enoent_or_zero= 0; // No error for ENOENT
|
||||
error= enoent_or_zero;
|
||||
}
|
||||
return error;
|
||||
|
@ -757,7 +757,8 @@ bool ha_flush_logs(void);
|
||||
void ha_drop_database(char* path);
|
||||
int ha_create_table(const char *name, HA_CREATE_INFO *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 */
|
||||
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
|
||||
tables List of tables to delete
|
||||
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
|
||||
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'
|
||||
drop_temporary Only drop temporary tables
|
||||
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:
|
||||
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;
|
||||
db_type table_type= get_table_type(path);
|
||||
*(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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
if (error == HA_ERR_ROW_IS_REFERENCED)
|
||||
{
|
||||
/* 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 */
|
||||
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
|
||||
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