diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:50:30 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:50:30 +0200 |
commit | cdc01e29d3a9f6d98aaa482363af81003485e256 (patch) | |
tree | 20c8ce171e2666e720ac5977561997038fe3c2f2 /sql | |
parent | 15c936e4b3d151346c027bd4b51b44c826b095b6 (diff) | |
download | mariadb-git-cdc01e29d3a9f6d98aaa482363af81003485e256.tar.gz |
remove dd_frm_type(), dd_frm_storage_engine(), dd_check_storage_engine_flag()
from everywhere - now RENAME, SHOW FULL TABLES, and TRUNCATE work with discovery.
improve error messages in truncate
Diffstat (limited to 'sql')
-rw-r--r-- | sql/datadict.cc | 82 | ||||
-rw-r--r-- | sql/datadict.h | 19 | ||||
-rw-r--r-- | sql/handler.cc | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 5 | ||||
-rw-r--r-- | sql/sql_rename.cc | 93 | ||||
-rw-r--r-- | sql/sql_show.cc | 31 | ||||
-rw-r--r-- | sql/sql_table.cc | 8 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 22 | ||||
-rw-r--r-- | sql/sql_view.cc | 22 | ||||
-rw-r--r-- | sql/table.cc | 20 |
10 files changed, 105 insertions, 201 deletions
diff --git a/sql/datadict.cc b/sql/datadict.cc index 15419c4f577..55ffd8eaee3 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -70,88 +70,6 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) } -/** - Given a table name, check type of .frm and legacy table type. - - @param[in] thd The current session. - @param[in] db Table schema. - @param[in] table_name Table database. - @param[out] table_type handlerton of the table if FRMTYPE_TABLE, - otherwise undefined. - - @return FALSE if FRMTYPE_TABLE and storage engine found. TRUE otherwise. -*/ - -bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name, - handlerton **table_type) -{ - char path[FN_REFLEN + 1]; - enum legacy_db_type db_type; - LEX_STRING db_name = {(char *) db, strlen(db)}; - - /* There should be at least some lock on the table. */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, - table_name, MDL_SHARED)); - - if (check_db_name(&db_name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); - return TRUE; - } - - if (check_table_name(table_name, strlen(table_name), FALSE)) - { - my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name); - return TRUE; - } - - (void) build_table_filename(path, sizeof(path) - 1, db, - table_name, reg_ext, 0); - - dd_frm_type(thd, path, &db_type); - - /* Type is unknown if the object is not found or is not a table. */ - if (db_type == DB_TYPE_UNKNOWN || - !(*table_type= ha_resolve_by_legacy_type(thd, db_type))) - { - my_error(ER_NO_SUCH_TABLE, MYF(0), db, table_name); - return TRUE; - } - - return FALSE; -} - - -/** - Given a table name, check if the storage engine for the - table referred by this name supports an option 'flag'. - Return an error if the table does not exist or is not a - base table. - - @pre Any metadata lock on the table. - - @param[in] thd The current session. - @param[in] db Table schema. - @param[in] table_name Table database. - @param[in] flag The option to check. - @param[out] yes_no The result. Undefined if error. -*/ - -bool dd_check_storage_engine_flag(THD *thd, - const char *db, const char *table_name, - uint32 flag, bool *yes_no) -{ - handlerton *table_type; - - if (dd_frm_storage_engine(thd, db, table_name, &table_type)) - return TRUE; - - *yes_no= ha_check_storage_engine_flag(table_type, flag); - - return FALSE; -} - - /* Regenerate a metadata locked table. diff --git a/sql/datadict.h b/sql/datadict.h index 9c625e6434c..dd80942daca 100644 --- a/sql/datadict.h +++ b/sql/datadict.h @@ -28,14 +28,21 @@ enum frm_type_enum FRMTYPE_VIEW }; +/* + Take extra care when using dd_frm_type() - it only checks the .frm file, + and it won't work for any engine that supports discovery. + + Prefer to use ha_table_exists() instead. + To check whether it's an frm of a view, use dd_frm_is_view(). +*/ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt); -bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name, - handlerton **table_type); -bool dd_check_storage_engine_flag(THD *thd, - const char *db, const char *table_name, - uint32 flag, - bool *yes_no); +static inline bool dd_frm_is_view(THD *thd, char *path) +{ + enum legacy_db_type not_used; + return dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW; +} + bool dd_recreate_table(THD *thd, const char *db, const char *table_name, const char *path = NULL); diff --git a/sql/handler.cc b/sql/handler.cc index b8ad8678b87..57282102a1a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -386,7 +386,6 @@ static int ha_finish_errors(void) static volatile int32 need_full_discover_for_existence= 0; static volatile int32 engines_with_discover_table_names= 0; - static int full_discover_for_existence(handlerton *, const char *, const char *) { return 1; } @@ -4373,8 +4372,7 @@ public: *cond_hdl= NULL; if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE || - sql_errno == ER_WRONG_OBJECT || - sql_errno == ER_OPTION_PREVENTS_STATEMENT) // partition_disabled.test + sql_errno == ER_WRONG_OBJECT) { m_handled_errors++; return TRUE; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d93c412dd60..c4e510fd451 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -55,7 +55,7 @@ #include <hash.h> #include "rpl_filter.h" #include "sql_table.h" // build_table_filename -#include "datadict.h" // dd_frm_type() +#include "datadict.h" // dd_frm_is_view() #include "sql_hset.h" // Hash_set #ifdef __WIN__ #include <io.h> @@ -2774,7 +2774,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, MDL_SHARED)) { char path[FN_REFLEN + 1]; - enum legacy_db_type not_used; build_table_filename(path, sizeof(path) - 1, table_list->db, table_list->table_name, reg_ext, 0); /* @@ -2784,7 +2783,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, during prelocking process (in this case in theory we still should hold shared metadata lock on it). */ - if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) + if (dd_frm_is_view(thd, path)) { if (!tdc_open_view(thd, table_list, alias, key, key_length, mem_root, 0)) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index cf9810db445..2c75de6e8a6 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -29,7 +29,6 @@ #include "sql_base.h" // tdc_remove_table, lock_table_names, #include "sql_handler.h" // mysql_ha_rm_tables #include "sql_statistics.h" -#include "datadict.h" static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); @@ -241,11 +240,9 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, char *new_table_alias, bool skip_error) { int rc= 1; - char name[FN_REFLEN + 1]; + handlerton *hton; + bool new_exists, old_exists; const char *new_alias, *old_alias; - frm_type_enum frm_type; - enum legacy_db_type table_type; - DBUG_ENTER("do_rename"); if (lower_case_table_names == 2) @@ -260,53 +257,48 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } DBUG_ASSERT(new_alias); - build_table_filename(name, sizeof(name) - 1, - new_db, new_alias, reg_ext, 0); - if (!access(name,F_OK)) + new_exists= ha_table_exists(thd, new_db, new_alias); + + if (new_exists) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); - DBUG_RETURN(1); // This can't be skipped + DBUG_RETURN(1); // This can't be skipped } - build_table_filename(name, sizeof(name) - 1, - ren_table->db, old_alias, reg_ext, 0); - frm_type= dd_frm_type(thd, name, &table_type); - switch (frm_type) + old_exists= ha_table_exists(thd, ren_table->db, old_alias, &hton); + + if (old_exists) { - case FRMTYPE_TABLE: + if (hton != view_pseudo_hton) + { + if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias, + new_db, new_alias, 0))) { - if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd, - table_type), - ren_table->db, old_alias, - new_db, new_alias, 0))) + LEX_STRING db_name= { ren_table->db, ren_table->db_length }; + LEX_STRING table_name= { ren_table->table_name, + ren_table->table_name_length }; + LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) }; + (void) rename_table_in_stat_tables(thd, &db_name, &table_name, + &db_name, &new_table); + if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, + old_alias, + ren_table->table_name, + new_db, + new_alias))) { - LEX_STRING db_name= { ren_table->db, ren_table->db_length }; - LEX_STRING table_name= { ren_table->table_name, - ren_table->table_name_length }; - LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) }; - (void) rename_table_in_stat_tables(thd, &db_name, &table_name, - &db_name, &new_table); - if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, - old_alias, - ren_table->table_name, - new_db, - new_alias))) - { - /* - We've succeeded in renaming table's .frm and in updating - corresponding handler data, but have failed to update table's - triggers appropriately. So let us revert operations on .frm - and handler's data and report about failure to rename table. - */ - (void) mysql_rename_table(ha_resolve_by_legacy_type(thd, - table_type), - new_db, new_alias, - ren_table->db, old_alias, 0); - } + /* + We've succeeded in renaming table's .frm and in updating + corresponding handler data, but have failed to update table's + triggers appropriately. So let us revert operations on .frm + and handler's data and report about failure to rename table. + */ + (void) mysql_rename_table(hton, new_db, new_alias, + ren_table->db, old_alias, 0); } } - break; - case FRMTYPE_VIEW: + } + else + { /* change of schema is not allowed except of ALTER ...UPGRADE DATA DIRECTORY NAME command @@ -314,22 +306,19 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, */ if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE && strcmp(ren_table->db, new_db)) - my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, - new_db); + my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db); else rc= mysql_rename_view(thd, new_db, new_alias, ren_table); - break; - default: - DBUG_ASSERT(0); // should never happen - case FRMTYPE_ERROR: - my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); - break; + } + } + else + { + my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias); } if (rc && !skip_error) DBUG_RETURN(1); DBUG_RETURN(0); - } /* Rename all tables in list; Return pointer to wrong entry if something goes diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5c92d7db8f2..a0fa9807b29 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -57,7 +57,6 @@ #include <my_dir.h> #include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH #include "debug_sync.h" -#include "datadict.h" // dd_frm_type() #include "keycaches.h" #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -4072,26 +4071,18 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, } else if (tables->table_open_method != SKIP_OPEN_TABLE) { - enum legacy_db_type not_used; - char path[FN_REFLEN + 1]; - (void) build_table_filename(path, sizeof(path) - 1, db_name->str, - table_name->str, reg_ext, 0); - switch (dd_frm_type(thd, path, ¬_used)) { - case FRMTYPE_ERROR: - table->field[3]->store(STRING_WITH_LEN("ERROR"), - system_charset_info); - break; - case FRMTYPE_TABLE: - table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), - system_charset_info); - break; - case FRMTYPE_VIEW: - table->field[3]->store(STRING_WITH_LEN("VIEW"), - system_charset_info); - break; - default: - DBUG_ASSERT(0); + CHARSET_INFO *cs= system_charset_info; + handlerton *hton; + if (ha_table_exists(thd, db_name->str, table_name->str, &hton)) + { + if (hton == view_pseudo_hton) + table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); + else + table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); } + else + table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); + if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { thd->clear_error(); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6fc5d9c0fc1..7d5f2d870ec 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4637,9 +4637,13 @@ mysql_rename_table(handlerton *base, const char *old_db, if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext)) { error=my_errno; - /* Restore old file name */ if (file) - file->ha_rename_table(to_base, from_base); + { + if (error == ENOENT) + error= 0; // this is ok if file->ha_rename_table() succeeded + else + file->ha_rename_table(to_base, from_base); // Restore old file name + } } } delete file; diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 0e97de5a6aa..92c4d150433 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -341,9 +341,27 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref, MYSQL_OPEN_SKIP_TEMPORARY)) DBUG_RETURN(TRUE); - if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name, - HTON_CAN_RECREATE, hton_can_recreate)) + handlerton *hton; + if (!ha_table_exists(thd, table_ref->db, table_ref->table_name, &hton) || + hton == view_pseudo_hton) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db, table_ref->table_name); DBUG_RETURN(TRUE); + } + + if (!hton) + { + /* + The table exists, but its storage engine is unknown, perhaps not + loaded at the moment. We need to open and parse the frm to know the + storage engine in question, so let's proceed with the truncation and + try to open the table. This will produce the correct error message + about unknown engine. + */ + *hton_can_recreate= false; + } + else + *hton_can_recreate= hton->flags & HTON_CAN_RECREATE; } /* diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 7c033f74fb2..0a84dd996ce 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -33,7 +33,7 @@ #include "sp_head.h" #include "sp.h" #include "sp_cache.h" -#include "datadict.h" // dd_frm_type() +#include "datadict.h" // dd_frm_is_view() #define MD5_BUFF_LENGTH 33 @@ -1642,7 +1642,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) String non_existant_views; char *wrong_object_db= NULL, *wrong_object_name= NULL; bool error= FALSE; - enum legacy_db_type not_used; bool some_views_deleted= FALSE; bool something_wrong= FALSE; DBUG_ENTER("mysql_drop_view"); @@ -1665,12 +1664,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) for (view= views; view; view= view->next_local) { - frm_type_enum type= FRMTYPE_ERROR; + bool not_exist; build_table_filename(path, sizeof(path) - 1, view->db, view->table_name, reg_ext, 0); - if (access(path, F_OK) || - FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used))) + if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path)) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); @@ -1681,7 +1679,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) name); continue; } - if (type == FRMTYPE_TABLE) + if (not_exist) + { + if (non_existant_views.length()) + non_existant_views.append(','); + non_existant_views.append(String(view->table_name,system_charset_info)); + } + else { if (!wrong_object_name) { @@ -1689,12 +1693,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) wrong_object_name= view->table_name; } } - else - { - if (non_existant_views.length()) - non_existant_views.append(','); - non_existant_views.append(String(view->table_name,system_charset_info)); - } continue; } if (mysql_file_delete(key_file_frm, path, MYF(MY_WME))) diff --git a/sql/table.cc b/sql/table.cc index 647e8d3ee5a..0eaae05af77 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -573,24 +573,6 @@ inline bool is_system_table_name(const char *name, uint length) /* - We don't try to open 5.0 unencoded name, if - - non-encoded name contains '@' signs, - because '@' can be misinterpreted. - It is not clear if '@' is escape character in 5.1, - or a normal character in 5.0. - - - non-encoded db or table name contain "#mysql50#" prefix. - This kind of tables must have been opened only by the - mysql_file_open() above. -*/ -static bool has_disabled_path_chars(const char *str) -{ - return strpbrk(str, "/\\~@.") != 0 || - strncmp(str, STRING_WITH_LEN(MYSQL50_TABLE_NAME_PREFIX)) == 0; -} - - -/* Read table definition from a binary / text based .frm file SYNOPSIS @@ -3176,7 +3158,7 @@ rename_file_ext(const char * from,const char * to,const char * ext) char from_b[FN_REFLEN],to_b[FN_REFLEN]; (void) strxmov(from_b,from,ext,NullS); (void) strxmov(to_b,to,ext,NullS); - return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(MY_WME))); + return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(0))); } |