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") ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
drop table t1; drop table t1;
Warnings: 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, if (!create_partition_name(name_buff, sizeof(name_buff), path,
name_buffer_ptr, NORMAL_PART_NAME, FALSE)) 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; name_buffer_ptr= strend(name_buffer_ptr) + 1;
} }
handler::delete_table(name); handler::delete_table(name);
@ -880,7 +880,7 @@ int ha_partition::drop_partitions(const char *path)
error= ret_error; error= ret_error;
file= m_file[part]; file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); 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; error= ret_error;
if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos))) entry_pos)))
@ -897,7 +897,7 @@ int ha_partition::drop_partitions(const char *path)
{ {
file= m_file[i]; file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); 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; error= ret_error;
if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos))) entry_pos)))
@ -989,7 +989,7 @@ int ha_partition::rename_partitions(const char *path)
NORMAL_PART_NAME)))) NORMAL_PART_NAME))))
error= ret_error; error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); 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; error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos))) entry_pos)))
@ -1010,7 +1010,7 @@ int ha_partition::rename_partitions(const char *path)
else else
{ {
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); 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; error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos))) entry_pos)))
@ -1071,7 +1071,7 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); 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; error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry->
entry_pos))) entry_pos)))
@ -1118,7 +1118,7 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); 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; error= ret_error;
else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry->
entry_pos))) entry_pos)))
@ -1670,7 +1670,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
error_external_lock: error_external_lock:
(void) file->ha_close(); (void) file->ha_close();
error_open: error_open:
(void) file->ha_delete_table(part_name); (void) file->delete_table(part_name);
error_create: error_create:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -1716,7 +1716,7 @@ void ha_partition::cleanup_new_partition(uint part_count)
(*file)->ha_external_unlock(thd); (*file)->ha_external_unlock(thd);
(*file)->ha_close(); (*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++; file++;
part_count--; part_count--;
@ -2309,7 +2309,7 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
@param table_arg TABLE object @param table_arg TABLE object
@param share New share to use @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) 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 else // delete branch
{ {
error= (*file)->ha_delete_table(from_buff); error= (*file)->delete_table(from_buff);
} }
name_buffer_ptr= strend(name_buffer_ptr) + 1; name_buffer_ptr= strend(name_buffer_ptr) + 1;
if (unlikely(error)) if (unlikely(error))

View File

@ -546,6 +546,26 @@ static void update_discovery_counters(handlerton *hton, int val)
engines_with_discover+= 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) int ha_finalize_handlerton(st_plugin_int *plugin)
{ {
handlerton *hton= (handlerton *)plugin->data; handlerton *hton= (handlerton *)plugin->data;
@ -616,6 +636,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
hton->tablefile_extensions= no_exts; hton->tablefile_extensions= no_exts;
hton->discover_table_names= hton_ext_based_table_discovery; hton->discover_table_names= hton_ext_based_table_discovery;
hton->drop_table= hton_drop_table;
hton->slot= HA_SLOT_UNDEF; hton->slot= HA_SLOT_UNDEF;
/* Historical Requirement */ /* 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. 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, const LEX_CSTRING *db, const LEX_CSTRING *alias,
bool generate_warning) bool generate_warning)
{ {
handler *file;
char tmp_path[FN_REFLEN];
int error; int error;
TABLE dummy_table;
TABLE_SHARE dummy_share;
bool is_error= thd->is_error(); bool is_error= thd->is_error();
DBUG_ENTER("ha_delete_table"); DBUG_ENTER("ha_delete_table");
/* table_type is NULL in ALTER TABLE when renaming only .frm files */ /* hton is NULL in ALTER TABLE when renaming only .frm files */
if (table_type == NULL || table_type == view_pseudo_hton || if (hton == NULL || hton == view_pseudo_hton)
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) DBUG_RETURN(0);
DBUG_RETURN(-1);
bzero((char*) &dummy_table, sizeof(dummy_table)); if (unlikely((error= hton->drop_table(hton, path))))
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))))
{ {
/* /*
It's not an error if the table doesn't exist in the engine. 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()) 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.str= (char*) path;
dummy_share.path.length= strlen(path); dummy_share.path.length= strlen(path);
dummy_share.normalized_path= dummy_share.path; dummy_share.normalized_path= dummy_share.path;
dummy_share.db= *db; dummy_share.db= *db;
dummy_share.table_name= *alias; dummy_share.table_name= *alias;
dummy_table.s= &dummy_share;
dummy_table.alias.set(alias->str, alias->length, table_alias_charset); dummy_table.alias.set(alias->str, alias->length, table_alias_charset);
file->change_table_ptr(&dummy_table, &dummy_share); file->change_table_ptr(&dummy_table, &dummy_share);
file->print_error(error, MYF(intercept ? ME_WARNING : 0)); file->print_error(error, MYF(intercept ? ME_WARNING : 0));
delete file;
} }
if (intercept) if (intercept)
{ {
@ -2775,7 +2792,6 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
error= -1; error= -1;
} }
} }
delete file;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -4586,8 +4602,8 @@ void handler::mark_trx_read_write_internal()
if (ha_info->is_started()) if (ha_info->is_started())
{ {
/* /*
table_share can be NULL in ha_delete_table(). See implementation table_share can be NULL, for example, in ha_delete_table() or
of standalone function ha_delete_table() in sql_base.cc. ha_rename_table().
*/ */
if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE) if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
ha_info->set_trx_read_write(); 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. 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); void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
void (*drop_database)(handlerton *hton, char* path); 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 (*panic)(handlerton *hton, enum ha_panic_function flag);
int (*start_consistent_snapshot)(handlerton *hton, THD *thd); int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
bool (*flush_logs)(handlerton *hton); bool (*flush_logs)(handlerton *hton);
@ -3453,7 +3454,6 @@ public:
int ha_enable_indexes(uint mode); int ha_enable_indexes(uint mode);
int ha_discard_or_import_tablespace(my_bool discard); int ha_discard_or_import_tablespace(my_bool discard);
int ha_rename_table(const char *from, const char *to); int ha_rename_table(const char *from, const char *to);
int ha_delete_table(const char *name);
void ha_drop_table(const char *name); void ha_drop_table(const char *name);
int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
@ -4673,13 +4673,14 @@ protected:
provide useful functionality. provide useful functionality.
*/ */
virtual int rename_table(const char *from, const char *to); virtual int rename_table(const char *from, const char *to);
public:
/** /**
Delete a table in the engine. Called for base as well as temporary Delete a table in the engine. Called for base as well as temporary
tables. tables.
*/ */
virtual int delete_table(const char *name); virtual int delete_table(const char *name);
public:
bool check_table_binlog_row_based(); bool check_table_binlog_row_based();
bool prepare_for_row_logging(); bool prepare_for_row_logging();
int prepare_for_insert(bool do_create); 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) my_bool mysql_rm_tmp_tables(void)
{ {
uint i, idx; uint i, idx;
char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN]; char path[FN_REFLEN], *tmpdir, path_copy[FN_REFLEN];
MY_DIR *dirp; MY_DIR *dirp;
FILEINFO *file; FILEINFO *file;
TABLE_SHARE share; TABLE_SHARE share;
@ -8823,23 +8823,17 @@ my_bool mysql_rm_tmp_tables(void)
{ {
char *ext= fn_ext(file->name); char *ext= fn_ext(file->name);
size_t ext_len= strlen(ext); 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, "%s%c%s", tmpdir, FN_LIBCHAR,
file->name); file->name);
if (!strcmp(reg_ext, ext)) if (!strcmp(reg_ext, ext))
{ {
handler *handler_file= 0;
/* We should cut file extention before deleting of table */ /* We should cut file extention before deleting of table */
memcpy(filePathCopy, filePath, filePath_len - ext_len); memcpy(path_copy, path, path_len - ext_len);
filePathCopy[filePath_len - ext_len]= 0; path_copy[path_len - ext_len]= 0;
init_tmp_table_share(thd, &share, "", 0, "", filePathCopy); init_tmp_table_share(thd, &share, "", 0, "", path_copy);
if (!open_table_def(thd, &share) && if (!open_table_def(thd, &share))
((handler_file= get_new_handler(&share, thd->mem_root, share.db_type()->drop_table(share.db_type(), path_copy);
share.db_type()))))
{
handler_file->ha_delete_table(filePathCopy);
delete handler_file;
}
free_table_share(&share); 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 So we hide error messages which happnes during deleting of these
files(MYF(0)). 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); my_dirend(dirp);

View File

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

View File

@ -1168,7 +1168,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
} }
else 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)) if (!non_existing_table_error(error))
break; break;

View File

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

View File

@ -5031,19 +5031,8 @@ int ha_mroonga::wrapper_delete_table(const char *name,
handlerton *wrap_handlerton, handlerton *wrap_handlerton,
const char *table_name) const char *table_name)
{ {
int error = 0;
MRN_DBUG_ENTER_METHOD(); MRN_DBUG_ENTER_METHOD();
DBUG_RETURN(wrap_handlerton->drop_table(wrap_handlerton, name));
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);
} }
int ha_mroonga::generic_delete_table(const char *name, const char *table_name) int ha_mroonga::generic_delete_table(const char *name, const char *table_name)