introduce hton->drop_table() method

first step in moving drop table out of the handler.
todo: other methods that don't need an open table

for now hton->drop_table is optional, for backward compatibility
reasons
This commit is contained in:
Sergei Golubchik 2020-06-13 21:23:19 +02:00
parent f17f7a43ba
commit c55c292832
9 changed files with 70 additions and 95 deletions

View File

@ -5,4 +5,4 @@ select * from t1 partition (p0);
ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
drop table t1;
Warnings:
Warning 1017 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
Warning 1017 Can't find file: './test/t1.par' (errno: 2 "No such file or directory")

View File

@ -811,7 +811,7 @@ create_error:
{
if (!create_partition_name(name_buff, sizeof(name_buff), path,
name_buffer_ptr, NORMAL_PART_NAME, FALSE))
(void) (*file)->ha_delete_table((const char*) name_buff);
(void) (*file)->delete_table((const char*) name_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
handler::delete_table(name);
@ -880,7 +880,7 @@ int ha_partition::drop_partitions(const char *path)
error= ret_error;
file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if (unlikely((ret_error= file->ha_delete_table(part_name_buff))))
if (unlikely((ret_error= file->delete_table(part_name_buff))))
error= ret_error;
if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos)))
@ -897,7 +897,7 @@ int ha_partition::drop_partitions(const char *path)
{
file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
if (unlikely((ret_error= file->ha_delete_table(part_name_buff))))
if (unlikely((ret_error= file->delete_table(part_name_buff))))
error= ret_error;
if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos)))
@ -989,7 +989,7 @@ int ha_partition::rename_partitions(const char *path)
NORMAL_PART_NAME))))
error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if (unlikely((ret_error= file->ha_delete_table(norm_name_buff))))
if (unlikely((ret_error= file->delete_table(norm_name_buff))))
error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos)))
@ -1010,7 +1010,7 @@ int ha_partition::rename_partitions(const char *path)
else
{
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if (unlikely((ret_error= file->ha_delete_table(norm_name_buff))))
if (unlikely((ret_error= file->delete_table(norm_name_buff))))
error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos)))
@ -1071,7 +1071,7 @@ int ha_partition::rename_partitions(const char *path)
{
file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if (unlikely((ret_error= file->ha_delete_table(norm_name_buff))))
if (unlikely((ret_error= file->delete_table(norm_name_buff))))
error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos)))
@ -1118,7 +1118,7 @@ int ha_partition::rename_partitions(const char *path)
{
file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if (unlikely((ret_error= file->ha_delete_table(norm_name_buff))))
if (unlikely((ret_error= file->delete_table(norm_name_buff))))
error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos)))
@ -1670,7 +1670,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
error_external_lock:
(void) file->ha_close();
error_open:
(void) file->ha_delete_table(part_name);
(void) file->delete_table(part_name);
error_create:
DBUG_RETURN(error);
}
@ -1716,7 +1716,7 @@ void ha_partition::cleanup_new_partition(uint part_count)
(*file)->ha_external_unlock(thd);
(*file)->ha_close();
/* Leave the (*file)->ha_delete_table(part_name) to the ddl-log */
/* Leave the (*file)->delete_table(part_name) to the ddl-log */
file++;
part_count--;
@ -2309,7 +2309,7 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
@param table_arg TABLE object
@param share New share to use
@note Is used in error handling in ha_delete_table.
@note Is used in error handling in delete_table.
All handlers should exist (lock_partitions should not be used)
*/
@ -2450,7 +2450,7 @@ uint ha_partition::del_ren_table(const char *from, const char *to)
}
else // delete branch
{
error= (*file)->ha_delete_table(from_buff);
error= (*file)->delete_table(from_buff);
}
name_buffer_ptr= strend(name_buffer_ptr) + 1;
if (unlikely(error))

View File

@ -546,6 +546,26 @@ static void update_discovery_counters(handlerton *hton, int val)
engines_with_discover+= val;
}
int ha_drop_table(THD *thd, handlerton *hton, const char *path)
{
if (ha_check_if_updates_are_ignored(thd, hton, "DROP"))
return 0; // Simulate dropped
return hton->drop_table(hton, path);
}
static int hton_drop_table(handlerton *hton, const char *path)
{
char tmp_path[FN_REFLEN];
handler *file= get_new_handler(nullptr, current_thd->mem_root, hton);
if (!file)
return ENOMEM;
path= get_canonical_filename(file, path, tmp_path);
int error= file->delete_table(path);
delete file;
return error;
}
int ha_finalize_handlerton(st_plugin_int *plugin)
{
handlerton *hton= (handlerton *)plugin->data;
@ -616,6 +636,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
hton->tablefile_extensions= no_exts;
hton->discover_table_names= hton_ext_based_table_discovery;
hton->drop_table= hton_drop_table;
hton->slot= HA_SLOT_UNDEF;
/* Historical Requirement */
@ -2724,29 +2745,19 @@ const char *get_canonical_filename(handler *file, const char *path,
The .frm file should be deleted by the caller only if we return <= 0.
*/
int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
int ha_delete_table(THD *thd, handlerton *hton, const char *path,
const LEX_CSTRING *db, const LEX_CSTRING *alias,
bool generate_warning)
{
handler *file;
char tmp_path[FN_REFLEN];
int error;
TABLE dummy_table;
TABLE_SHARE dummy_share;
bool is_error= thd->is_error();
DBUG_ENTER("ha_delete_table");
/* 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(-1);
/* hton is NULL in ALTER TABLE when renaming only .frm files */
if (hton == NULL || hton == view_pseudo_hton)
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 (unlikely((error= file->ha_delete_table(path))))
if (unlikely((error= hton->drop_table(hton, path))))
{
/*
It's not an error if the table doesn't exist in the engine.
@ -2757,15 +2768,21 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
if ((!intercept || generate_warning) && ! thd->is_error())
{
/* Fill up strucutures that print_error may need */
TABLE dummy_table;
TABLE_SHARE dummy_share;
handler *file= get_new_handler(nullptr, thd->mem_root, hton);
bzero((char*) &dummy_table, sizeof(dummy_table));
bzero((char*) &dummy_share, sizeof(dummy_share));
dummy_share.path.str= (char*) path;
dummy_share.path.length= strlen(path);
dummy_share.normalized_path= dummy_share.path;
dummy_share.db= *db;
dummy_share.table_name= *alias;
dummy_table.s= &dummy_share;
dummy_table.alias.set(alias->str, alias->length, table_alias_charset);
file->change_table_ptr(&dummy_table, &dummy_share);
file->print_error(error, MYF(intercept ? ME_WARNING : 0));
delete file;
}
if (intercept)
{
@ -2775,7 +2792,6 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
error= -1;
}
}
delete file;
DBUG_RETURN(error);
}
@ -4586,8 +4602,8 @@ void handler::mark_trx_read_write_internal()
if (ha_info->is_started())
{
/*
table_share can be NULL in ha_delete_table(). See implementation
of standalone function ha_delete_table() in sql_base.cc.
table_share can be NULL, for example, in ha_delete_table() or
ha_rename_table().
*/
if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
ha_info->set_trx_read_write();
@ -4947,22 +4963,6 @@ handler::ha_rename_table(const char *from, const char *to)
}
/**
Delete table: public interface.
@sa handler::delete_table()
*/
int
handler::ha_delete_table(const char *name)
{
if (ha_check_if_updates_are_ignored(ha_thd(), ht, "DROP"))
return 0; // Simulate dropped
mark_trx_read_write();
return delete_table(name);
}
/**
Drop table in the engine: public interface.

View File

@ -1484,6 +1484,7 @@ struct handlerton
void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
void (*drop_database)(handlerton *hton, char* path);
int (*drop_table)(handlerton *hton, const char* path);
int (*panic)(handlerton *hton, enum ha_panic_function flag);
int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
bool (*flush_logs)(handlerton *hton);
@ -3453,7 +3454,6 @@ public:
int ha_enable_indexes(uint mode);
int ha_discard_or_import_tablespace(my_bool discard);
int ha_rename_table(const char *from, const char *to);
int ha_delete_table(const char *name);
void ha_drop_table(const char *name);
int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
@ -4673,13 +4673,14 @@ protected:
provide useful functionality.
*/
virtual int rename_table(const char *from, const char *to);
public:
/**
Delete a table in the engine. Called for base as well as temporary
tables.
*/
virtual int delete_table(const char *name);
public:
bool check_table_binlog_row_based();
bool prepare_for_row_logging();
int prepare_for_insert(bool do_create);

View File

@ -8794,7 +8794,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr,
my_bool mysql_rm_tmp_tables(void)
{
uint i, idx;
char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
char path[FN_REFLEN], *tmpdir, path_copy[FN_REFLEN];
MY_DIR *dirp;
FILEINFO *file;
TABLE_SHARE share;
@ -8823,23 +8823,17 @@ my_bool mysql_rm_tmp_tables(void)
{
char *ext= fn_ext(file->name);
size_t ext_len= strlen(ext);
size_t filePath_len= my_snprintf(filePath, sizeof(filePath),
size_t path_len= my_snprintf(path, sizeof(path),
"%s%c%s", tmpdir, FN_LIBCHAR,
file->name);
if (!strcmp(reg_ext, ext))
{
handler *handler_file= 0;
/* We should cut file extention before deleting of table */
memcpy(filePathCopy, filePath, filePath_len - ext_len);
filePathCopy[filePath_len - ext_len]= 0;
init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
if (!open_table_def(thd, &share) &&
((handler_file= get_new_handler(&share, thd->mem_root,
share.db_type()))))
{
handler_file->ha_delete_table(filePathCopy);
delete handler_file;
}
memcpy(path_copy, path, path_len - ext_len);
path_copy[path_len - ext_len]= 0;
init_tmp_table_share(thd, &share, "", 0, "", path_copy);
if (!open_table_def(thd, &share))
share.db_type()->drop_table(share.db_type(), path_copy);
free_table_share(&share);
}
/*
@ -8847,7 +8841,7 @@ my_bool mysql_rm_tmp_tables(void)
So we hide error messages which happnes during deleting of these
files(MYF(0)).
*/
(void) mysql_file_delete(key_file_misc, filePath, MYF(0));
(void) mysql_file_delete(key_file_misc, path, MYF(0));
}
}
my_dirend(dirp);

View File

@ -19802,8 +19802,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
if (is_duplicate)
*is_duplicate= FALSE;
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
if (table->s->db_type() != heap_hton || error != HA_ERR_RECORD_FILE_FULL)
{
/*
We don't want this error to be converted to a warning, e.g. in case of
@ -19817,7 +19816,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
new_table.s= &share;
new_table.s->db_plugin= ha_lock_engine(thd, TMP_ENGINE_HTON);
if (unlikely(!(new_table.file= get_new_handler(&share, &new_table.mem_root,
new_table.s->db_type()))))
TMP_ENGINE_HTON))))
DBUG_RETURN(1); // End of memory
if (unlikely(new_table.file->set_ha_share_ref(&share.ha_share)))
@ -19908,7 +19907,7 @@ err_killed:
(void) table->file->ha_rnd_end();
(void) new_table.file->ha_close();
err1:
new_table.file->ha_delete_table(new_table.s->path.str);
TMP_ENGINE_HTON->drop_table(TMP_ENGINE_HTON, new_table.s->path.str);
err2:
delete new_table.file;
thd_proc_info(thd, save_proc_info);
@ -19931,16 +19930,12 @@ free_tmp_table(THD *thd, TABLE *entry)
if (entry->file && entry->is_created())
{
DBUG_ASSERT(entry->db_stat);
entry->file->ha_index_or_rnd_end();
if (entry->db_stat)
{
entry->file->info(HA_STATUS_VARIABLE);
thd->tmp_tables_size+= (entry->file->stats.data_file_length +
entry->file->stats.index_file_length);
entry->file->ha_drop_table(entry->s->path.str);
}
else
entry->file->ha_delete_table(entry->s->path.str);
entry->file->info(HA_STATUS_VARIABLE);
thd->tmp_tables_size+= (entry->file->stats.data_file_length +
entry->file->stats.index_file_length);
entry->file->ha_drop_table(entry->s->path.str);
delete entry->file;
}

View File

@ -1168,7 +1168,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
}
else
{
if (unlikely((error= file->ha_delete_table(ddl_log_entry->name))))
if (unlikely((error= hton->drop_table(hton, ddl_log_entry->name))))
{
if (!non_existing_table_error(error))
break;

View File

@ -694,23 +694,19 @@ bool THD::rm_temporary_table(handlerton *base, const char *path)
DBUG_ENTER("THD::rm_temporary_table");
bool error= false;
handler *file;
char frm_path[FN_REFLEN + 1];
strxnmov(frm_path, sizeof(frm_path) - 1, path, reg_ext, NullS);
if (mysql_file_delete(key_file_frm, frm_path,
MYF(MY_WME | MY_IGNORE_ENOENT)))
error= true;
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
if (file && file->ha_delete_table(path))
if (base->drop_table(base, path))
{
error= true;
sql_print_warning("Could not remove temporary table: '%s', error: %d",
path, my_errno);
}
delete file;
DBUG_RETURN(error);
}

View File

@ -5031,19 +5031,8 @@ int ha_mroonga::wrapper_delete_table(const char *name,
handlerton *wrap_handlerton,
const char *table_name)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
handler *hnd = get_new_handler(NULL, current_thd->mem_root, wrap_handlerton);
if (!hnd)
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
error = hnd->ha_delete_table(name);
delete hnd;
DBUG_RETURN(error);
DBUG_RETURN(wrap_handlerton->drop_table(wrap_handlerton, name));
}
int ha_mroonga::generic_delete_table(const char *name, const char *table_name)