diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:34:17 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:34:17 +0200 |
commit | 163882665eed8c065953bdce05aaa152b6b5df0f (patch) | |
tree | 8f537f7e5a92454ce4dee106660b0389bf2156da | |
parent | 5ad68a0d2f66b2d36f0a509c443829d58477caa2 (diff) | |
download | mariadb-git-163882665eed8c065953bdce05aaa152b6b5df0f.tar.gz |
* don't use 1-8 numbers for open_table_error codes, use an enum.
* print "table doesn't exist in engine" when a table doesn't exist in the engine,
instead of "file not found" (if no file was involved)
* print a complete filename that cannot be found ('t1.MYI', not 't1')
* it's not an error for a DROP if a table doesn't exist in the engine (or some table
files cannot be found) - if the DROP succeeded regardless
29 files changed, 196 insertions, 216 deletions
diff --git a/include/my_base.h b/include/my_base.h index 4cbcb00425b..0c12057b2ab 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -405,7 +405,7 @@ enum ha_base_keytype { #define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */ #define HA_ERR_CRASHED 126 /* Indexfile is crashed */ #define HA_ERR_WRONG_IN_RECORD 127 /* Record-file is crashed */ -#define HA_ERR_OUT_OF_MEM 128 /* Record-file is crashed */ +#define HA_ERR_OUT_OF_MEM 128 /* Out of memory */ #define HA_ERR_NOT_A_TABLE 130 /* not a MYI file - no signature */ #define HA_ERR_WRONG_COMMAND 131 /* Command not supported */ #define HA_ERR_OLD_FILE 132 /* old databasfile */ diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 87d6698865a..e7ea8b3d25a 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -627,16 +627,17 @@ DROP TABLE t1,t2,t3; create table t1 (a int) engine=innodb; let $MYSQLD_DATADIR= `select @@datadir`; copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm; ---error 1146 +--error ER_NO_SUCH_TABLE_IN_ENGINE select * from bug29807; drop table t1; ---error 1051 +--error ER_BAD_TABLE_ERROR drop table bug29807; create table bug29807 (a int); drop table bug29807; --disable_query_log call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"); call mtr.add_suppression("Cannot find or open table test\/bug29807 from"); +call mtr.add_suppression("Table 'test.bug29807' doesn't exist in engine"); --enable_query_log diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result index 924e7885814..9d5a59459ec 100644 --- a/mysql-test/r/myisam-system.result +++ b/mysql-test/r/myisam-system.result @@ -2,12 +2,18 @@ drop table if exists t1,t2; create table t1 (a int) engine=myisam; drop table if exists t1; Warnings: -Warning 2 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") create table t1 (a int) engine=myisam; +select * from t1; +ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") drop table t1; -Got one of the listed errors +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") create table t1 (a int) engine=myisam; +select * from t1; +ERROR HY000: File './test/t1.MYD' not found (Errcode: 2 "No such file or directory") drop table t1; -Got one of the listed errors +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") drop table t1; ERROR 42S02: Unknown table 't1' diff --git a/mysql-test/r/mysql_client_test.result b/mysql-test/r/mysql_client_test.result index 7875464ebe2..4ad07b20ab5 100644 --- a/mysql-test/r/mysql_client_test.result +++ b/mysql-test/r/mysql_client_test.result @@ -1,5 +1,6 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); ok # cat MYSQL_TMP_DIR/test_wl4435.out.log diff --git a/mysql-test/r/mysql_client_test_nonblock.result b/mysql-test/r/mysql_client_test_nonblock.result index edda7980e97..e37e2132b0c 100644 --- a/mysql-test/r/mysql_client_test_nonblock.result +++ b/mysql-test/r/mysql_client_test_nonblock.result @@ -1,5 +1,6 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); ok SET @@global.general_log= @old_general_log; SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 14ade969b25..c195bc6e3b3 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -160,6 +160,7 @@ Table Op Msg_type Msg_text test.v1 check status OK information_schema.routines check note The storage engine for the table doesn't support check drop view v1; +call mtr.add_suppression("Error reading file './test/t1.frm'"); CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam; test.t1 diff --git a/mysql-test/r/partition_myisam.result b/mysql-test/r/partition_myisam.result index f0844c0b407..10586ddc548 100644 --- a/mysql-test/r/partition_myisam.result +++ b/mysql-test/r/partition_myisam.result @@ -102,7 +102,6 @@ FLUSH TABLES; CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check Error Failed to read from the .par file -test.t1 check Error Incorrect information in file: './test/t1.frm' test.t1 check error Corrupt SELECT * FROM t1; ERROR HY000: Failed to read from the .par file diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 618433fe5e0..df0db73244a 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12754,9 +12754,10 @@ DROP TABLE t1; CREATE TABLE t1(a INT) ENGINE=ARCHIVE; FLUSH TABLE t1; SELECT * FROM t1; -ERROR HY000: Can't find file: 't1' (errno: 2 "No such file or directory") +ERROR HY000: Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") DROP TABLE t1; -ERROR 42S02: Unknown table 't1' +Warnings: +Warning 2 Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") # # Ensure that TRUNCATE fails for non-empty archive tables. # diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 92868158ed4..0dfdc969162 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1676,7 +1676,6 @@ FLUSH TABLE t1; --remove_file $MYSQLD_DATADIR/test/t1.ARZ --error ER_FILE_NOT_FOUND SELECT * FROM t1; ---error ER_BAD_TABLE_ERROR DROP TABLE t1; --echo # diff --git a/mysql-test/suite/federated/federated_bug_35333.result b/mysql-test/suite/federated/federated_bug_35333.result index 74f6f6e8f02..05e4bab8ec5 100644 --- a/mysql-test/suite/federated/federated_bug_35333.result +++ b/mysql-test/suite/federated/federated_bug_35333.result @@ -24,14 +24,12 @@ CREATE TABLE t1 (c1 int) ENGINE=MYISAM; SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT -test t1 BASE TABLE NULL NULL NULL NULL Can't find file: 't1' (errno: 2 "No such file or directory") +test t1 BASE TABLE NULL NULL NULL NULL Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") Warnings: -Warning 1017 Can't find file: 't1' (errno: 2 "No such file or directory") -SHOW WARNINGS; -Level Code Message -Warning 1017 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 1017 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") DROP TABLE t1; -ERROR 42S02: Unknown table 't1' +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") # # Cleanup # diff --git a/mysql-test/suite/federated/federated_bug_35333.test b/mysql-test/suite/federated/federated_bug_35333.test index 6487e10e018..47feefd75a1 100644 --- a/mysql-test/suite/federated/federated_bug_35333.test +++ b/mysql-test/suite/federated/federated_bug_35333.test @@ -64,11 +64,7 @@ let $MYSQLD_DATADIR= `SELECT @@datadir`; SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; -SHOW WARNINGS; ---disable_warnings ---error 1051 DROP TABLE t1; ---enable_warnings --echo # --echo # Cleanup diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index b2df98bbfa6..d963c4cc89b 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -630,7 +630,7 @@ a DROP TABLE t1,t2,t3; create table t1 (a int) engine=innodb; select * from bug29807; -ERROR 42S02: Table 'test.bug29807' doesn't exist +ERROR 42S02: Table 'test.bug29807' doesn't exist in engine drop table t1; drop table bug29807; ERROR 42S02: Unknown table 'bug29807' diff --git a/mysql-test/suite/rpl/r/rpl_EE_err.result b/mysql-test/suite/rpl/r/rpl_EE_err.result index 5b3f1872c4e..f61ca063b77 100644 --- a/mysql-test/suite/rpl/r/rpl_EE_err.result +++ b/mysql-test/suite/rpl/r/rpl_EE_err.result @@ -4,5 +4,5 @@ create table t1 (a int) engine=myisam; flush tables; drop table if exists t1; Warnings: -Warning 2 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") include/rpl_end.inc diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test index d908e639a4e..ef1bc03434d 100644 --- a/mysql-test/t/myisam-system.test +++ b/mysql-test/t/myisam-system.test @@ -12,11 +12,13 @@ let $MYSQLD_DATADIR= `select @@datadir`; drop table if exists t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYI ---error ER_BAD_TABLE_ERROR,6 +--error ER_FILE_NOT_FOUND +select * from t1; drop table t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYD ---error ER_BAD_TABLE_ERROR,6,29 +--error 29 +select * from t1; drop table t1; --error ER_BAD_TABLE_ERROR drop table t1; diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 90da022fb38..bf5331ca4f9 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -6,6 +6,8 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); + # We run with different binaries for normal and --embedded-server # # If this test fails with "command "$MYSQL_CLIENT_TEST" failed", diff --git a/mysql-test/t/mysql_client_test_nonblock.test b/mysql-test/t/mysql_client_test_nonblock.test index fc2e0b1d01b..51263854e58 100644 --- a/mysql-test/t/mysql_client_test_nonblock.test +++ b/mysql-test/t/mysql_client_test_nonblock.test @@ -5,6 +5,7 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); # We run with different binaries for normal and --embedded-server # diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index c0025f9e742..06d702495c2 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -93,6 +93,7 @@ drop view v1; # Bug#37527: mysqlcheck fails to report entire database # when frm file corruption # +call mtr.add_suppression("Error reading file './test/t1.frm'"); CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam; # backup then null t1.frm diff --git a/sql/datadict.cc b/sql/datadict.cc index e3f679cc7ec..4aa024b3b44 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -60,6 +60,11 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) DBUG_RETURN(FRMTYPE_TABLE); + /* + XXX this is a bug. + if header[3] is > DB_TYPE_FIRST_DYNAMIC, then the complete + storage engine name must be read from the frm + */ *dbt= (enum legacy_db_type) (uint) *(header + 3); /* Probably a table. */ diff --git a/sql/handler.cc b/sql/handler.cc index 0091c765042..58e8524dd8d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2189,7 +2189,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ if (table_type == NULL || ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) - DBUG_RETURN(ENOENT); + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); path= get_canonical_filename(file, path, tmp_path); if ((error= file->ha_delete_table(path)) && generate_warning) @@ -2205,6 +2205,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* Fill up strucutures that print_error may need */ dummy_share.path.str= (char*) path; dummy_share.path.length= strlen(path); + dummy_share.normalized_path= dummy_share.path; dummy_share.db.str= (char*) db; dummy_share.db.length= strlen(db); dummy_share.table_name.str= (char*) alias; @@ -3208,7 +3209,17 @@ void handler::print_error(int error, myf errflag) errflag|= ME_NOREFRESH; } } - my_error(textno, errflag, table_share->table_name.str, error); + + /* if we got an OS error from a file-based engine, specify a path of error */ + if (error < HA_ERR_FIRST && bas_ext()[0]) + { + char buff[FN_REFLEN]; + strxnmov(buff, sizeof(buff), + table_share->normalized_path.str, bas_ext()[0], NULL); + my_error(textno, errflag, buff, error); + } + else + my_error(textno, errflag, table_share->table_name.str, error); DBUG_VOID_RETURN; } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 8c7a8000695..e7f60987cc1 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6599,4 +6599,4 @@ ER_CANT_START_STOP_SLAVE ER_SLAVE_STARTED eng "SLAVE '%.*s' started" ER_SLAVE_STOPPED - eng "SLAVE '%.*s' stopped"
\ No newline at end of file + eng "SLAVE '%.*s' stopped" diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 43500211e1b..849a00a7df7 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -81,6 +81,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) { int error= 0; + enum open_frm_error not_used; TABLE tmp_table, *table; TABLE_LIST *pos_in_locked_tables= 0; TABLE_SHARE *share; @@ -129,7 +130,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, table_list, key, key_length, - FRM_READ_TABLE_ONLY, &error, hash_value); + FRM_READ_TABLE_ONLY, ¬_used, hash_value); mysql_mutex_unlock(&LOCK_open); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9b9411c63a1..03728fcd372 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -575,13 +575,14 @@ static void table_def_unuse_table(TABLE *table) */ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, int *error, + uint key_length, enum read_frm_op op, + enum open_frm_error *error, my_hash_value_type hash_value) { TABLE_SHARE *share; DBUG_ENTER("get_table_share"); - *error= 0; + *error= OPEN_FRM_OK; /* To be able perform any operation on table we should own @@ -641,12 +642,12 @@ found: if (share->error) { /* Table definition contained an error */ - open_table_error(share, share->error, share->open_errno, share->errarg); + open_table_error(share, share->error, share->open_errno); DBUG_RETURN(0); } if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) { - open_table_error(share, 1, ENOENT, 0); + open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT); DBUG_RETURN(0); } @@ -685,7 +686,7 @@ found: static TABLE_SHARE * get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, char *key, uint key_length, - enum read_frm_op op, int *error, + enum read_frm_op op, enum open_frm_error *error, my_hash_value_type hash_value) { @@ -724,7 +725,7 @@ get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE)) DBUG_RETURN(share); - *error= 0; + *error= OPEN_FRM_OK; /* Table didn't exist. Check if some engine can provide it */ if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name, @@ -762,7 +763,7 @@ get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, else { thd->clear_error(); - *error= 7; /* Run auto-discover. */ + *error= OPEN_FRM_DISCOVER; /* Run auto-discover. */ } DBUG_RETURN(NULL); } @@ -2735,7 +2736,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char *alias= table_list->alias; uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; - int error; + enum open_frm_error error; TABLE_SHARE *share; my_hash_value_type hash_value; DBUG_ENTER("open_table"); @@ -3020,12 +3021,11 @@ retry_share: { mysql_mutex_unlock(&LOCK_open); /* - If thd->is_error() is not set, we either need discover - (error == 7), or the error was silenced by the prelocking - handler (error == 0), in which case we should skip this + If thd->is_error() is not set, we either need discover or the error was + silenced by the prelocking handler, in which case we should skip this table. */ - if (error == 7 && !thd->is_error()) + if (error == OPEN_FRM_DISCOVER && !thd->is_error()) { (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); @@ -3172,7 +3172,7 @@ retry_share: { my_free(table); - if (error == 7) + if (error == OPEN_FRM_DISCOVER) (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); else if (share->crashed) @@ -3847,7 +3847,7 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, MEM_ROOT *mem_root, uint flags) { TABLE not_used; - int error; + enum open_frm_error error; my_hash_value_type hash_value; TABLE_SHARE *share; @@ -3934,7 +3934,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) uint cache_key_length; TABLE_SHARE *share; TABLE *entry; - int not_used; + enum open_frm_error not_used; bool result= TRUE; my_hash_value_type hash_value; diff --git a/sql/sql_base.h b/sql/sql_base.h index 1cd36160309..e0612397361 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -108,7 +108,8 @@ create_table_def_key(char *key, const char *db, const char *table_name) } TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, int *error, + uint key_length, enum read_frm_op op, + enum open_frm_error *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d63e8221654..7afbd3a7f9c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4305,7 +4305,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, TABLE tbl; TABLE_LIST table_list; uint res= 0; - int not_used; + enum open_frm_error not_used; my_hash_value_type hash_value; char key[MAX_DBKEY_LENGTH]; uint key_length; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7072cb38138..ad30b26908a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2323,8 +2323,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, !dont_log_query); /* No error if non existent table and 'IF EXIST' clause or view */ - if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && - (if_exists || table_type == NULL)) + if (error == ENOENT || (error == HA_ERR_NO_SUCH_TABLE && + (if_exists || table_type == NULL))) { error= 0; thd->clear_error(); diff --git a/sql/table.cc b/sql/table.cc index a0012e2e0d0..661d448b743 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -64,7 +64,7 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; /* Functions defined in this file */ -static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *buf); +static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image); static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, char **names); static uint find_field(Field **fields, uchar *record, uint start, uint length); @@ -608,20 +608,13 @@ static bool has_disabled_path_chars(const char *str) table_def_cache The data is returned in 'share', which is alloced by alloc_table_share().. The code assumes that share is initialized. - - RETURN VALUES - 0 ok - 1 Error (see open_table_error) - 2 Error (see open_table_error) - 3 Wrong data in .frm file - 4 Error (see open_table_error) - 5 Error (see open_table_error: charset unavailable) - 6 Unknown .frm version */ -int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) +enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, + enum read_frm_op op) { - int error, table_type; + enum open_frm_error error; + bool is_binary_frm= false; bool error_given; File file; uchar head[64]; @@ -631,7 +624,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); - error= 1; + error= OPEN_FRM_OPEN_ERROR; error_given= 0; strxmov(path, share->normalized_path.str, reg_ext, NullS); @@ -684,31 +677,38 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) share->normalized_path.length= length; } - error= 4; if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) + { + error = my_errno == HA_ERR_FILE_TOO_SHORT + ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; goto err; + } if (head[0] == (uchar) 254 && head[1] == 1) { if (head[2] == FRM_VER || head[2] == FRM_VER+1 || (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) { - table_type= 1; + is_binary_frm= true; } else { - error= 6; // Unknown .frm version + my_printf_error(ER_NOT_FORM_FILE, + "Table '%-.64s' was created with a different version " + "of MySQL and cannot be read", + MYF(0), path); + error= OPEN_FRM_ERROR_ALREADY_ISSUED; goto err; } } else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0) { - error= 5; + error= OPEN_FRM_NO_VIEWS; if (memcmp(head+5,"VIEW",4) == 0) { share->is_view= 1; if (op == FRM_READ_NO_ERROR_FOR_VIEW) - error= 0; + error= OPEN_FRM_OK; } goto err; } @@ -716,7 +716,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) goto err; /* No handling of text based files yet */ - if (table_type == 1) + if (is_binary_frm) { MY_STAT stats; uchar *buf; @@ -740,7 +740,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); old_root= *root_ptr; *root_ptr= &share->mem_root; - error= open_binary_frm(thd, share, buf); + error= open_binary_frm(thd, share, buf) ? OPEN_FRM_CORRUPTED : OPEN_FRM_OK; *root_ptr= old_root; error_given= 1; my_free(buf); @@ -760,7 +760,8 @@ err_not_open: if (error && !error_given) { share->error= error; - open_table_error(share, error, (share->open_errno= my_errno), 0); + share->open_errno= my_errno; + open_table_error(share, error, share->open_errno); } DBUG_RETURN(error); @@ -779,9 +780,8 @@ err_not_open: They're still set, for compatibility reasons, but never read. */ -static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) +static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) { - int error, errarg= 0; uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; @@ -820,8 +820,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; - error= 3; - /* Position of the form in the form file. */ len = uint2korr(frm_image+4); if (!(pos= uint4korr(frm_image + 64 + len))) @@ -885,7 +883,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->db_record_offset= 1; if (db_create_options & HA_OPTION_LONG_BLOB_PTR) share->blob_ptr_size= portable_sizeof_char_ptr; - error=4; share->max_rows= uint4korr(frm_image+18); share->min_rows= uint4korr(frm_image+22); @@ -1125,7 +1122,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) /* Check if the partitioning engine is ready */ if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN)) { - error= 8; my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition"); goto err; @@ -1140,7 +1136,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) else if (!tmp_plugin) { /* purecov: begin inspected */ - error= 8; name.str[name.length]=0; my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); goto err; @@ -1238,7 +1233,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) } share->key_block_size= uint2korr(frm_image+62); - error=4; extra_rec_buf_length= uint2korr(frm_image+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; @@ -1396,7 +1390,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) geom_type= (Field::geometry_type) strpos[14]; charset= &my_charset_bin; #else - error= 4; // unsupported field type goto err; #endif } @@ -1407,8 +1400,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) charset= &my_charset_bin; else if (!(charset= get_charset(csid, MYF(0)))) { - error= 5; // Unknown or unavailable charset - errarg= (int) csid; + const char *csname= get_charset_name((uint) csid); + char tmp[10]; + if (!csname || csname[0] =='?') + { + my_snprintf(tmp, sizeof(tmp), "#%d", csid); + csname= tmp; + } + my_printf_error(ER_UNKNOWN_COLLATION, + "Unknown collation '%s' in table '%-.64s' definition", + MYF(0), csname, share->table_name.str); goto err; } } @@ -1452,10 +1453,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (opt_interval_id) interval_nr= (uint)vcol_screen_pos[3]; else if ((uint)vcol_screen_pos[0] != 1) - { - error= 4; goto err; - } + fld_stored_in_db= (bool) (uint) vcol_screen_pos[2]; vcol_expr_length= vcol_info_length - (uint)(FRM_VCOL_HEADER_SIZE(opt_interval_id)); @@ -1554,10 +1553,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) (TYPELIB*) 0), share->fieldnames.type_names[i]); if (!reg_field) // Not supported field type - { - error= 4; - goto err; /* purecov: inspected */ - } + goto err; + reg_field->field_index= i; reg_field->comment=comment; @@ -1583,20 +1580,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (reg_field->unireg_check == Field::NEXT_NUMBER) share->found_next_number_field= field_ptr; - if (use_hash) - { - if (my_hash_insert(&share->name_hash, - (uchar*) field_ptr)) - { - /* - Set return code 8 here to indicate that an error has - occurred but that the error message already has been - sent (OOM). - */ - error= 8; - goto err; - } - } + if (use_hash && my_hash_insert(&share->name_hash, (uchar*) field_ptr)) + goto err; if (!reg_field->stored_in_db) { share->stored_fields--; @@ -1748,10 +1733,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) (uint) key_part->offset, (uint) key_part->length); if (!key_part->fieldnr) - { - error= 4; // Wrong file goto err; - } + field= key_part->field= share->field[key_part->fieldnr-1]; key_part->type= field->key_type(); if (field->null_ptr) @@ -1924,11 +1907,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->default_values, reg_field, &share->next_number_key_offset, &share->next_number_keypart)) < 0) - { - /* Wrong field definition */ - error= 4; - goto err; - } + goto err; // Wrong field definition else reg_field->flags |= AUTO_INCREMENT_FLAG; } @@ -1974,12 +1953,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (use_hash) (void) my_hash_check(&share->name_hash); #endif - DBUG_RETURN (0); + DBUG_RETURN(0); err: - share->error= error; + share->error= OPEN_FRM_CORRUPTED; share->open_errno= my_errno; - share->errarg= errarg; delete handler_file; my_hash_free(&share->name_hash); if (share->ha_data_destroy) @@ -1995,8 +1973,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) } #endif /* WITH_PARTITION_STORAGE_ENGINE */ - open_table_error(share, error, share->open_errno, errarg); - DBUG_RETURN(error); + if (!thd->is_error()) + open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); + + DBUG_RETURN(1); } /* open_binary_frm */ /* @@ -2306,11 +2286,12 @@ end: 7 Table definition has changed in engine */ -int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, - uint db_stat, uint prgflag, uint ha_open_flags, - TABLE *outparam, bool is_create_table) +enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, + const char *alias, uint db_stat, uint prgflag, + uint ha_open_flags, TABLE *outparam, + bool is_create_table) { - int error; + enum open_frm_error error; uint records, i, bitmap_size; bool error_reported= FALSE; uchar *record, *bitmaps; @@ -2322,7 +2303,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view - error= 1; + error= OPEN_FRM_ERROR_ALREADY_ISSUED; // for OOM errors below bzero((char*) outparam, sizeof(*outparam)); outparam->in_use= thd; outparam->s= share; @@ -2351,7 +2332,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, DBUG_ASSERT(!db_stat); } - error= 4; outparam->reginfo.lock_type= TL_UNLOCK; outparam->current_lock= F_UNLCK; records=0; @@ -2504,7 +2484,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, &(*field_ptr)->vcol_info->expr_str, &error_reported)) { - error= 4; // in case no error is reported + error= OPEN_FRM_CORRUPTED; goto err; } *(vfield_ptr++)= *field_ptr; @@ -2615,53 +2595,32 @@ partititon_err: outparam->default_column_bitmaps(); /* The table struct is now initialized; Open the table */ - error= 2; if (db_stat) { - int ha_err; - if ((ha_err= (outparam->file-> - ha_open(outparam, share->normalized_path.str, - (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), - (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : - ((db_stat & HA_WAIT_IF_LOCKED) || - (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? - HA_OPEN_WAIT_IF_LOCKED : - (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? - HA_OPEN_ABORT_IF_LOCKED : - HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) + if (db_stat & HA_OPEN_TEMPORARY) + ha_open_flags|= HA_OPEN_TMP_TABLE; + else if ((db_stat & HA_WAIT_IF_LOCKED) || + (specialflag & SPECIAL_WAIT_IF_LOCKED)) + ha_open_flags|= HA_OPEN_WAIT_IF_LOCKED; + else if (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) + ha_open_flags|= HA_OPEN_ABORT_IF_LOCKED; + else + ha_open_flags|= HA_OPEN_IGNORE_IF_LOCKED; + + int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str, + (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), + ha_open_flags); + if (ha_err) { + share->open_errno= ha_err; /* Set a flag if the table is crashed and it can be auto. repaired */ share->crashed= (outparam->file->auto_repair(ha_err) && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - - switch (ha_err) - { - case HA_ERR_NO_SUCH_TABLE: - /* - The table did not exists in storage engine, use same error message - as if the .frm file didn't exist - */ - error= 1; - my_errno= ENOENT; - break; - case EMFILE: - /* - Too many files opened, use same error message as if the .frm - file can't open - */ - DBUG_PRINT("error", ("open file: %s failed, too many files opened (errno: %d)", - share->normalized_path.str, ha_err)); - error= 1; - my_errno= EMFILE; - break; - default: - outparam->file->print_error(ha_err, MYF(0)); - error_reported= TRUE; - if (ha_err == HA_ERR_TABLE_DEF_CHANGED) - error= 7; - break; - } - goto err; /* purecov: inspected */ + outparam->file->print_error(ha_err, MYF(0)); + error_reported= TRUE; + if (ha_err == HA_ERR_TABLE_DEF_CHANGED) + error= OPEN_FRM_DISCOVER; + goto err; } } @@ -2675,11 +2634,11 @@ partititon_err: thd->status_var.opened_tables++; thd->lex->context_analysis_only= save_context_analysis_only; - DBUG_RETURN (0); + DBUG_RETURN (OPEN_FRM_OK); err: if (! error_reported) - open_table_error(share, error, my_errno, 0); + open_table_error(share, error, my_errno); delete outparam->file; #ifdef WITH_PARTITION_STORAGE_ENGINE if (outparam->part_info) @@ -2864,16 +2823,15 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, /* error message when opening a form file */ -void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) +void open_table_error(TABLE_SHARE *share, enum open_frm_error error, + int db_errno) { - int err_no; char buff[FN_REFLEN]; myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log DBUG_ENTER("open_table_error"); switch (error) { - case 7: - case 1: + case OPEN_FRM_OPEN_ERROR: /* Test if file didn't exists. We have to also test for EINVAL as this may happen on windows when opening a file with a not legal file name @@ -2887,47 +2845,23 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) errortype, buff, db_errno); } break; - case 2: - { - const char *datext= ""; - - if (share->db_type() && share->db_type()->tablefile_extensions[0]) - datext= share->db_type()->tablefile_extensions[0]; - - err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ? - ER_FILE_USED : ER_CANT_OPEN_FILE; - strxmov(buff, share->normalized_path.str, datext, NullS); - my_error(err_no,errortype, buff, db_errno); + case OPEN_FRM_OK: + DBUG_ASSERT(0); // open_table_error() is never called for this one break; - } - case 5: - { - const char *csname= get_charset_name((uint) errarg); - char tmp[10]; - if (!csname || csname[0] =='?') - { - my_snprintf(tmp, sizeof(tmp), "#%d", errarg); - csname= tmp; - } - my_printf_error(ER_UNKNOWN_COLLATION, - "Unknown collation '%s' in table '%-.64s' definition", - MYF(0), csname, share->table_name.str); + case OPEN_FRM_ERROR_ALREADY_ISSUED: break; - } - case 6: - strxmov(buff, share->normalized_path.str, reg_ext, NullS); - my_printf_error(ER_NOT_FORM_FILE, - "Table '%-.64s' was created with a different version " - "of MySQL and cannot be read", - MYF(0), buff); + case OPEN_FRM_DISCOVER: + case OPEN_FRM_NO_VIEWS: + DBUG_ASSERT(0); // open_table_error() is never called for this one break; - case 8: - break; - default: /* Better wrong error than none */ - case 4: + case OPEN_FRM_CORRUPTED: strxmov(buff, share->normalized_path.str, reg_ext, NullS); my_error(ER_NOT_FORM_FILE, errortype, buff); break; + case OPEN_FRM_READ_ERROR: + strxmov(buff, share->normalized_path.str, reg_ext, NullS); + my_error(ER_ERROR_ON_READ, errortype, buff, db_errno); + break; } DBUG_VOID_RETURN; } /* open_table_error */ diff --git a/sql/table.h b/sql/table.h index 18ed635aae8..737afc38300 100644 --- a/sql/table.h +++ b/sql/table.h @@ -562,6 +562,16 @@ typedef I_P_List <Wait_for_flush, Wait_for_flush_list; +enum open_frm_error { + OPEN_FRM_OK = 0, + OPEN_FRM_OPEN_ERROR, + OPEN_FRM_READ_ERROR, + OPEN_FRM_CORRUPTED, + OPEN_FRM_DISCOVER, + OPEN_FRM_ERROR_ALREADY_ISSUED, + OPEN_FRM_NO_VIEWS, +}; + /** Control block to access table statistics loaded from persistent statistical tables @@ -694,7 +704,8 @@ struct TABLE_SHARE uint next_number_index; /* autoincrement key number */ uint next_number_key_offset; /* autoinc keypart offset in a key */ uint next_number_keypart; /* autoinc keypart number in a key */ - uint error, open_errno, errarg; /* error from open_table_def() */ + enum open_frm_error error; /* error from open_table_def() */ + uint open_errno; /* error from open_table_def() */ uint column_bitmap_size; uchar frm_version; uint vfields; /* Number of computed (virtual) fields */ @@ -2442,9 +2453,10 @@ size_t max_row_length(TABLE *table, const uchar *data); void init_mdl_requests(TABLE_LIST *table_list); -int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, - uint db_stat, uint prgflag, uint ha_open_flags, - TABLE *outparam, bool is_create_table); +enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, + const char *alias, uint db_stat, uint prgflag, + uint ha_open_flags, TABLE *outparam, + bool is_create_table); bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table, Field *field, LEX_STRING *vcol_expr, bool *error_reported); @@ -2454,9 +2466,11 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, uint key_length, const char *table_name, const char *path); void free_table_share(TABLE_SHARE *share); -int open_table_def(THD *thd, TABLE_SHARE *share, +enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op = FRM_READ_TABLE_ONLY); -void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg); + +void open_table_error(TABLE_SHARE *share, enum open_frm_error error, + int db_errno); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase); bool check_db_name(LEX_STRING *db); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c5b59f6b404..d8f3b739d4d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2166,6 +2166,13 @@ ha_innobase::init_table_handle_for_HANDLER(void) reset_template(prebuilt); } +/****************************************************************//** +Gives the file extension of an InnoDB single-table tablespace. */ +static const char* ha_innobase_exts[] = { + ".ibd", + NullS +}; + /*********************************************************************//** Opens an InnoDB database. @return 0 on success, error code on failure */ @@ -2215,6 +2222,9 @@ innobase_init( innobase_hton->alter_table_flags = innobase_alter_table_flags; innobase_hton->kill_query = innobase_kill_query; + if (srv_file_per_table) + innobase_hton->tablefile_extensions = ha_innobase_exts; + ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); #ifndef DBUG_OFF @@ -3350,13 +3360,6 @@ ha_innobase::table_flags() const } /****************************************************************//** -Gives the file extension of an InnoDB single-table tablespace. */ -static const char* ha_innobase_exts[] = { - ".ibd", - NullS -}; - -/****************************************************************//** Returns the table type (storage engine name). @return table type */ UNIV_INTERN diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 5ba58fe439b..e90b62aa3db 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2615,7 +2615,9 @@ innobase_init( innobase_hton->release_temporary_latches=innobase_release_temporary_latches; innobase_hton->alter_table_flags = innobase_alter_table_flags; innobase_hton->kill_query = innobase_kill_query; - innobase_hton->tablefile_extensions = ha_innobase_exts; + + if (srv_file_per_table) + innobase_hton->tablefile_extensions = ha_innobase_exts; ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); |