From aa09cb3b11dbd3c8e36055343beeddecf5248168 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 27 Jan 2024 00:15:40 +0100 Subject: [PATCH] open frm for DROP TABLE needed to get partitioning and information about secondary objects --- mysql-test/main/features.result | 2 +- mysql-test/main/invisible_field.result | 2 +- mysql-test/suite/archive/discover.result | 2 +- sql/sql_class.h | 7 +++ sql/sql_table.cc | 56 +++++++++++++++++++----- sql/table.cc | 6 +-- 6 files changed, 57 insertions(+), 18 deletions(-) diff --git a/mysql-test/main/features.result b/mysql-test/main/features.result index 58a2c0fa55e..cae4a37ca64 100644 --- a/mysql-test/main/features.result +++ b/mysql-test/main/features.result @@ -176,7 +176,7 @@ create table t2 (b int, constraint foo check (b < 10)); drop table t1, t2; show status like "feature_check_constraint"; Variable_name Value -Feature_check_constraint 2 +Feature_check_constraint 4 # # Feature insert...returning # diff --git a/mysql-test/main/invisible_field.result b/mysql-test/main/invisible_field.result index e23b88e954d..9d7e9b1a47f 100644 --- a/mysql-test/main/invisible_field.result +++ b/mysql-test/main/invisible_field.result @@ -444,7 +444,7 @@ d int(11) YES UNI NULL drop table t1; SHOW STATUS LIKE 'Feature_invisible_columns'; Variable_name Value -Feature_invisible_columns 52 +Feature_invisible_columns 54 #invisible is non reserved create table t1(a int unique , invisible int invisible, c int ); desc t1; diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index 572d30c18dc..c216a37e71e 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -93,7 +93,7 @@ drop table t0; db.opt show status like 'Handler_discover'; Variable_name Value -Handler_discover 6 +Handler_discover 7 # # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE # diff --git a/sql/sql_class.h b/sql/sql_class.h index 3a700b84547..d49f6ceb3c9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1329,6 +1329,13 @@ public: { return strmake_lex_cstring(from.str, from.length); } + LEX_CUSTRING strmake_lex_custring(const LEX_CUSTRING &from) const + { + const void *tmp= memdup(from.str, from.length); + if (!tmp) + return {0,0}; + return {(const uchar*)tmp, from.length}; + } LEX_CSTRING strmake_lex_cstring_trim_whitespace(const LEX_CSTRING &from, CHARSET_INFO *cs) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3b9ec489faa..877bd24c912 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1265,6 +1265,7 @@ static uint32 get_comment(THD *thd, uint32 comment_pos, return 0; } + /** Execute the drop of a sequence, view or table (normal or temporary). @@ -1535,20 +1536,51 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, cpath = { path, (size_t)(path_end - path) }; + Dummy_error_handler err_handler; + thd->push_internal_handler(&err_handler); + if (TABLE_SHARE *share= tdc_acquire_share(thd, table, GTS_TABLE)) { - char engine_buf[NAME_CHAR_LEN + 1]; - LEX_CSTRING engine= { engine_buf, 0 }; - - table_type= dd_frm_type(thd, path, &engine, &partition_engine_name, - &version); - if (table_type == TABLE_TYPE_NORMAL || table_type == TABLE_TYPE_SEQUENCE) - { - plugin_ref p= plugin_lock_by_name(thd, &engine, - MYSQL_STORAGE_ENGINE_PLUGIN); - hton= p ? plugin_hton(p) : NULL; - } - // note that for TABLE_TYPE_VIEW and TABLE_TYPE_UNKNOWN hton == NULL + table_type= share->table_type; + hton= plugin_hton(plugin_lock(thd, share->db_plugin)); + version= thd->strmake_lex_custring(share->tabledef_version); + if (plugin_ref pp= IF_PARTITIONING(share->default_part_plugin, NULL)) + partition_engine_name= thd->strmake_lex_cstring(*plugin_name(pp)); + tdc_release_share(share); } + else + { + switch (err_handler.got_error()) { + case ER_WRONG_OBJECT: + table_type= TABLE_TYPE_VIEW; + break; + case ER_NO_SUCH_TABLE: /* no .frm */ + table_type= TABLE_TYPE_UNKNOWN; + break; + case ER_NOT_FORM_FILE: + { + /* + cannot open the frm, let's at least get the engine + see main.partition_not_blackhole and connect.drop-open-error + */ + char engine_buf[NAME_CHAR_LEN + 1]; + LEX_CSTRING engine= { engine_buf, 0 }; + table_type= dd_frm_type(thd, path, &engine, NULL, &version); + if (table_type == TABLE_TYPE_NORMAL || table_type == TABLE_TYPE_SEQUENCE) + { + plugin_ref p= plugin_lock_by_name(thd, &engine, + MYSQL_STORAGE_ENGINE_PLUGIN); + hton= p ? plugin_hton(p) : NULL; + } + break; + } + case ER_FAILED_READ_FROM_PAR_FILE: /* no .par file */ + hton= partition_hton; + /* fall through */ + default: /* unreadable (corrupted?) .frm, still need to DROP it */ + table_type= TABLE_TYPE_NORMAL; + } + } + thd->pop_internal_handler(); thd->replication_flags= 0; const bool was_view= table_type == TABLE_TYPE_VIEW; diff --git a/sql/table.cc b/sql/table.cc index ede653ce1dd..7ee6e031afd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -663,7 +663,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) File file; uchar *buf; uchar head[FRM_HEADER_SIZE]; - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; size_t frmlen, read_length; uint length; DBUG_ENTER("open_table_def"); @@ -672,8 +672,8 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) share->error= OPEN_FRM_OPEN_ERROR; - length=(uint) (strxmov(path, share->normalized_path.str, reg_ext, NullS) - - path); + length=(uint) (strxnmov(path, sizeof(path) - 1, + share->normalized_path.str, reg_ext, NullS) - path); if (flags & GTS_FORCE_DISCOVERY) { const char *path2= share->normalized_path.str;