* 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
This commit is contained in:
Sergei Golubchik 2013-04-09 15:34:17 +02:00
parent 5ad68a0d2f
commit 163882665e
29 changed files with 196 additions and 216 deletions

View File

@ -405,7 +405,7 @@ enum ha_base_keytype {
#define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */ #define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */
#define HA_ERR_CRASHED 126 /* Indexfile is crashed */ #define HA_ERR_CRASHED 126 /* Indexfile is crashed */
#define HA_ERR_WRONG_IN_RECORD 127 /* Record-file 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_NOT_A_TABLE 130 /* not a MYI file - no signature */
#define HA_ERR_WRONG_COMMAND 131 /* Command not supported */ #define HA_ERR_WRONG_COMMAND 131 /* Command not supported */
#define HA_ERR_OLD_FILE 132 /* old databasfile */ #define HA_ERR_OLD_FILE 132 /* old databasfile */

View File

@ -627,16 +627,17 @@ DROP TABLE t1,t2,t3;
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm; copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm;
--error 1146 --error ER_NO_SUCH_TABLE_IN_ENGINE
select * from bug29807; select * from bug29807;
drop table t1; drop table t1;
--error 1051 --error ER_BAD_TABLE_ERROR
drop table bug29807; drop table bug29807;
create table bug29807 (a int); create table bug29807 (a int);
drop table bug29807; drop table bug29807;
--disable_query_log --disable_query_log
call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"); 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("Cannot find or open table test\/bug29807 from");
call mtr.add_suppression("Table 'test.bug29807' doesn't exist in engine");
--enable_query_log --enable_query_log

View File

@ -2,12 +2,18 @@ drop table if exists t1,t2;
create table t1 (a int) engine=myisam; create table t1 (a int) engine=myisam;
drop table if exists t1; drop table if exists t1;
Warnings: 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; 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; 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; 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; 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; drop table t1;
ERROR 42S02: Unknown table 't1' ERROR 42S02: Unknown table 't1'

View File

@ -1,5 +1,6 @@
SET @old_general_log= @@global.general_log; SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_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 ok
# cat MYSQL_TMP_DIR/test_wl4435.out.log # cat MYSQL_TMP_DIR/test_wl4435.out.log

View File

@ -1,5 +1,6 @@
SET @old_general_log= @@global.general_log; SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_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 ok
SET @@global.general_log= @old_general_log; SET @@global.general_log= @old_general_log;
SET @@global.slow_query_log= @old_slow_query_log; SET @@global.slow_query_log= @old_slow_query_log;

View File

@ -160,6 +160,7 @@ Table Op Msg_type Msg_text
test.v1 check status OK test.v1 check status OK
information_schema.routines check note The storage engine for the table doesn't support check information_schema.routines check note The storage engine for the table doesn't support check
drop view v1; drop view v1;
call mtr.add_suppression("Error reading file './test/t1.frm'");
CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t1(a INT) engine=myisam;
CREATE TABLE t2(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam;
test.t1 test.t1

View File

@ -102,7 +102,6 @@ FLUSH TABLES;
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check Error Failed to read from the .par file 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 test.t1 check error Corrupt
SELECT * FROM t1; SELECT * FROM t1;
ERROR HY000: Failed to read from the .par file ERROR HY000: Failed to read from the .par file

View File

@ -12754,9 +12754,10 @@ DROP TABLE t1;
CREATE TABLE t1(a INT) ENGINE=ARCHIVE; CREATE TABLE t1(a INT) ENGINE=ARCHIVE;
FLUSH TABLE t1; FLUSH TABLE t1;
SELECT * FROM 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; 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. # Ensure that TRUNCATE fails for non-empty archive tables.
# #

View File

@ -1676,7 +1676,6 @@ FLUSH TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.ARZ --remove_file $MYSQLD_DATADIR/test/t1.ARZ
--error ER_FILE_NOT_FOUND --error ER_FILE_NOT_FOUND
SELECT * FROM t1; SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #

View File

@ -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 SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT 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: Warnings:
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")
SHOW WARNINGS;
Level Code Message
Warning 1017 Can't find file: 't1' (errno: 2 "No such file or directory")
DROP TABLE t1; 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 # Cleanup
# #

View File

@ -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 SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
SHOW WARNINGS;
--disable_warnings
--error 1051
DROP TABLE t1; DROP TABLE t1;
--enable_warnings
--echo # --echo #
--echo # Cleanup --echo # Cleanup

View File

@ -630,7 +630,7 @@ a
DROP TABLE t1,t2,t3; DROP TABLE t1,t2,t3;
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
select * from bug29807; 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 t1;
drop table bug29807; drop table bug29807;
ERROR 42S02: Unknown table 'bug29807' ERROR 42S02: Unknown table 'bug29807'

View File

@ -4,5 +4,5 @@ create table t1 (a int) engine=myisam;
flush tables; flush tables;
drop table if exists t1; drop table if exists t1;
Warnings: 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 include/rpl_end.inc

View File

@ -12,11 +12,13 @@ let $MYSQLD_DATADIR= `select @@datadir`;
drop table if exists t1; drop table if exists t1;
create table t1 (a int) engine=myisam; create table t1 (a int) engine=myisam;
--remove_file $MYSQLD_DATADIR/test/t1.MYI --remove_file $MYSQLD_DATADIR/test/t1.MYI
--error ER_BAD_TABLE_ERROR,6 --error ER_FILE_NOT_FOUND
select * from t1;
drop table t1; drop table t1;
create table t1 (a int) engine=myisam; create table t1 (a int) engine=myisam;
--remove_file $MYSQLD_DATADIR/test/t1.MYD --remove_file $MYSQLD_DATADIR/test/t1.MYD
--error ER_BAD_TABLE_ERROR,6,29 --error 29
select * from t1;
drop table t1; drop table t1;
--error ER_BAD_TABLE_ERROR --error ER_BAD_TABLE_ERROR
drop table t1; drop table t1;

View File

@ -6,6 +6,8 @@
SET @old_general_log= @@global.general_log; SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_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 # We run with different binaries for normal and --embedded-server
# #
# If this test fails with "command "$MYSQL_CLIENT_TEST" failed", # If this test fails with "command "$MYSQL_CLIENT_TEST" failed",

View File

@ -5,6 +5,7 @@
SET @old_general_log= @@global.general_log; SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_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 # We run with different binaries for normal and --embedded-server
# #

View File

@ -93,6 +93,7 @@ drop view v1;
# Bug#37527: mysqlcheck fails to report entire database # Bug#37527: mysqlcheck fails to report entire database
# when frm file corruption # when frm file corruption
# #
call mtr.add_suppression("Error reading file './test/t1.frm'");
CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t1(a INT) engine=myisam;
CREATE TABLE t2(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam;
# backup then null t1.frm # backup then null t1.frm

View File

@ -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))) (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
DBUG_RETURN(FRMTYPE_TABLE); 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); *dbt= (enum legacy_db_type) (uint) *(header + 3);
/* Probably a table. */ /* Probably a table. */

View File

@ -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 */ /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
if (table_type == NULL || if (table_type == NULL ||
! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) ! (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); path= get_canonical_filename(file, path, tmp_path);
if ((error= file->ha_delete_table(path)) && generate_warning) 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 */ /* Fill up strucutures that print_error may need */
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.db.str= (char*) db; dummy_share.db.str= (char*) db;
dummy_share.db.length= strlen(db); dummy_share.db.length= strlen(db);
dummy_share.table_name.str= (char*) alias; dummy_share.table_name.str= (char*) alias;
@ -3208,7 +3209,17 @@ void handler::print_error(int error, myf errflag)
errflag|= ME_NOREFRESH; 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; DBUG_VOID_RETURN;
} }

View File

@ -81,6 +81,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
HA_CHECK_OPT *check_opt) HA_CHECK_OPT *check_opt)
{ {
int error= 0; int error= 0;
enum open_frm_error not_used;
TABLE tmp_table, *table; TABLE tmp_table, *table;
TABLE_LIST *pos_in_locked_tables= 0; TABLE_LIST *pos_in_locked_tables= 0;
TABLE_SHARE *share; 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); hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length);
mysql_mutex_lock(&LOCK_open); mysql_mutex_lock(&LOCK_open);
share= get_table_share(thd, table_list, key, key_length, share= get_table_share(thd, table_list, key, key_length,
FRM_READ_TABLE_ONLY, &error, hash_value); FRM_READ_TABLE_ONLY, &not_used, hash_value);
mysql_mutex_unlock(&LOCK_open); mysql_mutex_unlock(&LOCK_open);
if (share == NULL) if (share == NULL)
DBUG_RETURN(0); // Can't open frm file DBUG_RETURN(0); // Can't open frm file

View File

@ -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, 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) my_hash_value_type hash_value)
{ {
TABLE_SHARE *share; TABLE_SHARE *share;
DBUG_ENTER("get_table_share"); DBUG_ENTER("get_table_share");
*error= 0; *error= OPEN_FRM_OK;
/* /*
To be able perform any operation on table we should own To be able perform any operation on table we should own
@ -641,12 +642,12 @@ found:
if (share->error) if (share->error)
{ {
/* Table definition contained an 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); DBUG_RETURN(0);
} }
if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) 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); DBUG_RETURN(0);
} }
@ -685,7 +686,7 @@ found:
static TABLE_SHARE * static TABLE_SHARE *
get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, get_table_share_with_discover(THD *thd, TABLE_LIST *table_list,
char *key, uint key_length, 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) 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)) thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE))
DBUG_RETURN(share); DBUG_RETURN(share);
*error= 0; *error= OPEN_FRM_OK;
/* Table didn't exist. Check if some engine can provide it */ /* 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, 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 else
{ {
thd->clear_error(); thd->clear_error();
*error= 7; /* Run auto-discover. */ *error= OPEN_FRM_DISCOVER; /* Run auto-discover. */
} }
DBUG_RETURN(NULL); 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; char *alias= table_list->alias;
uint flags= ot_ctx->get_flags(); uint flags= ot_ctx->get_flags();
MDL_ticket *mdl_ticket; MDL_ticket *mdl_ticket;
int error; enum open_frm_error error;
TABLE_SHARE *share; TABLE_SHARE *share;
my_hash_value_type hash_value; my_hash_value_type hash_value;
DBUG_ENTER("open_table"); DBUG_ENTER("open_table");
@ -3020,12 +3021,11 @@ retry_share:
{ {
mysql_mutex_unlock(&LOCK_open); mysql_mutex_unlock(&LOCK_open);
/* /*
If thd->is_error() is not set, we either need discover If thd->is_error() is not set, we either need discover or the error was
(error == 7), or the error was silenced by the prelocking silenced by the prelocking handler, in which case we should skip this
handler (error == 0), in which case we should skip this
table. 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, (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
table_list); table_list);
@ -3172,7 +3172,7 @@ retry_share:
{ {
my_free(table); my_free(table);
if (error == 7) if (error == OPEN_FRM_DISCOVER)
(void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
table_list); table_list);
else if (share->crashed) 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) MEM_ROOT *mem_root, uint flags)
{ {
TABLE not_used; TABLE not_used;
int error; enum open_frm_error error;
my_hash_value_type hash_value; my_hash_value_type hash_value;
TABLE_SHARE *share; TABLE_SHARE *share;
@ -3934,7 +3934,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
uint cache_key_length; uint cache_key_length;
TABLE_SHARE *share; TABLE_SHARE *share;
TABLE *entry; TABLE *entry;
int not_used; enum open_frm_error not_used;
bool result= TRUE; bool result= TRUE;
my_hash_value_type hash_value; my_hash_value_type hash_value;

View File

@ -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, 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); my_hash_value_type hash_value);
void release_table_share(TABLE_SHARE *share); void release_table_share(TABLE_SHARE *share);
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);

View File

@ -4305,7 +4305,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
TABLE tbl; TABLE tbl;
TABLE_LIST table_list; TABLE_LIST table_list;
uint res= 0; uint res= 0;
int not_used; enum open_frm_error not_used;
my_hash_value_type hash_value; my_hash_value_type hash_value;
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;

View File

@ -2323,8 +2323,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
!dont_log_query); !dont_log_query);
/* No error if non existent table and 'IF EXIST' clause or view */ /* No error if non existent table and 'IF EXIST' clause or view */
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if (error == ENOENT || (error == HA_ERR_NO_SUCH_TABLE &&
(if_exists || table_type == NULL)) (if_exists || table_type == NULL)))
{ {
error= 0; error= 0;
thd->clear_error(); thd->clear_error();

View File

@ -64,7 +64,7 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
/* Functions defined in this file */ /* 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, static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names); uint types, char **names);
static uint find_field(Field **fields, uchar *record, uint start, uint length); 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 table_def_cache
The data is returned in 'share', which is alloced by The data is returned in 'share', which is alloced by
alloc_table_share().. The code assumes that share is initialized. 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; bool error_given;
File file; File file;
uchar head[64]; 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, DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str,
share->table_name.str, share->normalized_path.str)); share->table_name.str, share->normalized_path.str));
error= 1; error= OPEN_FRM_OPEN_ERROR;
error_given= 0; error_given= 0;
strxmov(path, share->normalized_path.str, reg_ext, NullS); 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; share->normalized_path.length= length;
} }
error= 4;
if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) 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; goto err;
}
if (head[0] == (uchar) 254 && head[1] == 1) if (head[0] == (uchar) 254 && head[1] == 1)
{ {
if (head[2] == FRM_VER || head[2] == FRM_VER+1 || if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
{ {
table_type= 1; is_binary_frm= true;
} }
else 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; goto err;
} }
} }
else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0) else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0)
{ {
error= 5; error= OPEN_FRM_NO_VIEWS;
if (memcmp(head+5,"VIEW",4) == 0) if (memcmp(head+5,"VIEW",4) == 0)
{ {
share->is_view= 1; share->is_view= 1;
if (op == FRM_READ_NO_ERROR_FOR_VIEW) if (op == FRM_READ_NO_ERROR_FOR_VIEW)
error= 0; error= OPEN_FRM_OK;
} }
goto err; goto err;
} }
@ -716,7 +716,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op)
goto err; goto err;
/* No handling of text based files yet */ /* No handling of text based files yet */
if (table_type == 1) if (is_binary_frm)
{ {
MY_STAT stats; MY_STAT stats;
uchar *buf; 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); root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
old_root= *root_ptr; old_root= *root_ptr;
*root_ptr= &share->mem_root; *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; *root_ptr= old_root;
error_given= 1; error_given= 1;
my_free(buf); my_free(buf);
@ -760,7 +760,8 @@ err_not_open:
if (error && !error_given) if (error && !error_given)
{ {
share->error= error; 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); DBUG_RETURN(error);
@ -779,9 +780,8 @@ err_not_open:
They're still set, for compatibility reasons, but never read. 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 new_frm_ver, field_pack_length, new_field_pack_flag;
uint interval_count, interval_parts, read_length, int_length; uint interval_count, interval_parts, read_length, int_length;
uint db_create_options, keys, key_parts, n_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); new_frm_ver= (frm_image[2] - FRM_VER);
field_pack_length= new_frm_ver < 2 ? 11 : 17; field_pack_length= new_frm_ver < 2 ? 11 : 17;
error= 3;
/* Position of the form in the form file. */ /* Position of the form in the form file. */
len = uint2korr(frm_image+4); len = uint2korr(frm_image+4);
if (!(pos= uint4korr(frm_image + 64 + len))) 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; share->db_record_offset= 1;
if (db_create_options & HA_OPTION_LONG_BLOB_PTR) if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
share->blob_ptr_size= portable_sizeof_char_ptr; share->blob_ptr_size= portable_sizeof_char_ptr;
error=4;
share->max_rows= uint4korr(frm_image+18); share->max_rows= uint4korr(frm_image+18);
share->min_rows= uint4korr(frm_image+22); 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 */ /* Check if the partitioning engine is ready */
if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN)) if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
{ {
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition"); "--skip-partition");
goto err; goto err;
@ -1140,7 +1136,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image)
else if (!tmp_plugin) else if (!tmp_plugin)
{ {
/* purecov: begin inspected */ /* purecov: begin inspected */
error= 8;
name.str[name.length]=0; name.str[name.length]=0;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
goto err; 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); share->key_block_size= uint2korr(frm_image+62);
error=4;
extra_rec_buf_length= uint2korr(frm_image+59); extra_rec_buf_length= uint2korr(frm_image+59);
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
share->rec_buff_length= rec_buff_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]; geom_type= (Field::geometry_type) strpos[14];
charset= &my_charset_bin; charset= &my_charset_bin;
#else #else
error= 4; // unsupported field type
goto err; goto err;
#endif #endif
} }
@ -1407,8 +1400,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image)
charset= &my_charset_bin; charset= &my_charset_bin;
else if (!(charset= get_charset(csid, MYF(0)))) else if (!(charset= get_charset(csid, MYF(0))))
{ {
error= 5; // Unknown or unavailable charset const char *csname= get_charset_name((uint) csid);
errarg= (int) 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; goto err;
} }
} }
@ -1452,10 +1453,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image)
if (opt_interval_id) if (opt_interval_id)
interval_nr= (uint)vcol_screen_pos[3]; interval_nr= (uint)vcol_screen_pos[3];
else if ((uint)vcol_screen_pos[0] != 1) else if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
goto err; goto err;
}
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2]; fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
vcol_expr_length= vcol_info_length - vcol_expr_length= vcol_info_length -
(uint)(FRM_VCOL_HEADER_SIZE(opt_interval_id)); (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), (TYPELIB*) 0),
share->fieldnames.type_names[i]); share->fieldnames.type_names[i]);
if (!reg_field) // Not supported field type if (!reg_field) // Not supported field type
{ goto err;
error= 4;
goto err; /* purecov: inspected */
}
reg_field->field_index= i; reg_field->field_index= i;
reg_field->comment=comment; 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) if (reg_field->unireg_check == Field::NEXT_NUMBER)
share->found_next_number_field= field_ptr; share->found_next_number_field= field_ptr;
if (use_hash) if (use_hash && my_hash_insert(&share->name_hash, (uchar*) field_ptr))
{ goto err;
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 (!reg_field->stored_in_db) if (!reg_field->stored_in_db)
{ {
share->stored_fields--; 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->offset,
(uint) key_part->length); (uint) key_part->length);
if (!key_part->fieldnr) if (!key_part->fieldnr)
{
error= 4; // Wrong file
goto err; goto err;
}
field= key_part->field= share->field[key_part->fieldnr-1]; field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type(); key_part->type= field->key_type();
if (field->null_ptr) 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->default_values, reg_field,
&share->next_number_key_offset, &share->next_number_key_offset,
&share->next_number_keypart)) < 0) &share->next_number_keypart)) < 0)
{ goto err; // Wrong field definition
/* Wrong field definition */
error= 4;
goto err;
}
else else
reg_field->flags |= AUTO_INCREMENT_FLAG; 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) if (use_hash)
(void) my_hash_check(&share->name_hash); (void) my_hash_check(&share->name_hash);
#endif #endif
DBUG_RETURN (0); DBUG_RETURN(0);
err: err:
share->error= error; share->error= OPEN_FRM_CORRUPTED;
share->open_errno= my_errno; share->open_errno= my_errno;
share->errarg= errarg;
delete handler_file; delete handler_file;
my_hash_free(&share->name_hash); my_hash_free(&share->name_hash);
if (share->ha_data_destroy) 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 */ #endif /* WITH_PARTITION_STORAGE_ENGINE */
open_table_error(share, error, share->open_errno, errarg); if (!thd->is_error())
DBUG_RETURN(error); open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
DBUG_RETURN(1);
} /* open_binary_frm */ } /* open_binary_frm */
/* /*
@ -2306,11 +2286,12 @@ end:
7 Table definition has changed in engine 7 Table definition has changed in engine
*/ */
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
uint db_stat, uint prgflag, uint ha_open_flags, const char *alias, uint db_stat, uint prgflag,
TABLE *outparam, bool is_create_table) uint ha_open_flags, TABLE *outparam,
bool is_create_table)
{ {
int error; enum open_frm_error error;
uint records, i, bitmap_size; uint records, i, bitmap_size;
bool error_reported= FALSE; bool error_reported= FALSE;
uchar *record, *bitmaps; 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 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)); bzero((char*) outparam, sizeof(*outparam));
outparam->in_use= thd; outparam->in_use= thd;
outparam->s= share; outparam->s= share;
@ -2351,7 +2332,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
DBUG_ASSERT(!db_stat); DBUG_ASSERT(!db_stat);
} }
error= 4;
outparam->reginfo.lock_type= TL_UNLOCK; outparam->reginfo.lock_type= TL_UNLOCK;
outparam->current_lock= F_UNLCK; outparam->current_lock= F_UNLCK;
records=0; 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, &(*field_ptr)->vcol_info->expr_str,
&error_reported)) &error_reported))
{ {
error= 4; // in case no error is reported error= OPEN_FRM_CORRUPTED;
goto err; goto err;
} }
*(vfield_ptr++)= *field_ptr; *(vfield_ptr++)= *field_ptr;
@ -2615,53 +2595,32 @@ partititon_err:
outparam->default_column_bitmaps(); outparam->default_column_bitmaps();
/* The table struct is now initialized; Open the table */ /* The table struct is now initialized; Open the table */
error= 2;
if (db_stat) if (db_stat)
{ {
int ha_err; if (db_stat & HA_OPEN_TEMPORARY)
if ((ha_err= (outparam->file-> ha_open_flags|= HA_OPEN_TMP_TABLE;
ha_open(outparam, share->normalized_path.str, else if ((db_stat & HA_WAIT_IF_LOCKED) ||
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), (specialflag & SPECIAL_WAIT_IF_LOCKED))
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : ha_open_flags|= HA_OPEN_WAIT_IF_LOCKED;
((db_stat & HA_WAIT_IF_LOCKED) || else if (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO))
(specialflag & SPECIAL_WAIT_IF_LOCKED)) ? ha_open_flags|= HA_OPEN_ABORT_IF_LOCKED;
HA_OPEN_WAIT_IF_LOCKED : else
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? ha_open_flags|= HA_OPEN_IGNORE_IF_LOCKED;
HA_OPEN_ABORT_IF_LOCKED :
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) 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 */ /* Set a flag if the table is crashed and it can be auto. repaired */
share->crashed= (outparam->file->auto_repair(ha_err) && share->crashed= (outparam->file->auto_repair(ha_err) &&
!(ha_open_flags & HA_OPEN_FOR_REPAIR)); !(ha_open_flags & HA_OPEN_FOR_REPAIR));
outparam->file->print_error(ha_err, MYF(0));
switch (ha_err) error_reported= TRUE;
{ if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
case HA_ERR_NO_SUCH_TABLE: error= OPEN_FRM_DISCOVER;
/* goto err;
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 */
} }
} }
@ -2675,11 +2634,11 @@ partititon_err:
thd->status_var.opened_tables++; thd->status_var.opened_tables++;
thd->lex->context_analysis_only= save_context_analysis_only; thd->lex->context_analysis_only= save_context_analysis_only;
DBUG_RETURN (0); DBUG_RETURN (OPEN_FRM_OK);
err: err:
if (! error_reported) if (! error_reported)
open_table_error(share, error, my_errno, 0); open_table_error(share, error, my_errno);
delete outparam->file; delete outparam->file;
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
if (outparam->part_info) 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 */ /* 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]; char buff[FN_REFLEN];
myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log
DBUG_ENTER("open_table_error"); DBUG_ENTER("open_table_error");
switch (error) { switch (error) {
case 7: case OPEN_FRM_OPEN_ERROR:
case 1:
/* /*
Test if file didn't exists. We have to also test for EINVAL as this 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 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); errortype, buff, db_errno);
} }
break; break;
case 2: case OPEN_FRM_OK:
{ DBUG_ASSERT(0); // open_table_error() is never called for this one
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);
break; break;
} case OPEN_FRM_ERROR_ALREADY_ISSUED:
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);
break; break;
} case OPEN_FRM_DISCOVER:
case 6: case OPEN_FRM_NO_VIEWS:
strxmov(buff, share->normalized_path.str, reg_ext, NullS); DBUG_ASSERT(0); // open_table_error() is never called for this one
my_printf_error(ER_NOT_FORM_FILE,
"Table '%-.64s' was created with a different version "
"of MySQL and cannot be read",
MYF(0), buff);
break; break;
case 8: case OPEN_FRM_CORRUPTED:
break;
default: /* Better wrong error than none */
case 4:
strxmov(buff, share->normalized_path.str, reg_ext, NullS); strxmov(buff, share->normalized_path.str, reg_ext, NullS);
my_error(ER_NOT_FORM_FILE, errortype, buff); my_error(ER_NOT_FORM_FILE, errortype, buff);
break; 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; DBUG_VOID_RETURN;
} /* open_table_error */ } /* open_table_error */

View File

@ -562,6 +562,16 @@ typedef I_P_List <Wait_for_flush,
Wait_for_flush_list; 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 Control block to access table statistics loaded
from persistent statistical tables from persistent statistical tables
@ -694,7 +704,8 @@ struct TABLE_SHARE
uint next_number_index; /* autoincrement key number */ uint next_number_index; /* autoincrement key number */
uint next_number_key_offset; /* autoinc keypart offset in a key */ uint next_number_key_offset; /* autoinc keypart offset in a key */
uint next_number_keypart; /* autoinc keypart number 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; uint column_bitmap_size;
uchar frm_version; uchar frm_version;
uint vfields; /* Number of computed (virtual) fields */ 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); void init_mdl_requests(TABLE_LIST *table_list);
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
uint db_stat, uint prgflag, uint ha_open_flags, const char *alias, uint db_stat, uint prgflag,
TABLE *outparam, bool is_create_table); uint ha_open_flags, TABLE *outparam,
bool is_create_table);
bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root,
TABLE *table, Field *field, TABLE *table, Field *field,
LEX_STRING *vcol_expr, bool *error_reported); 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, uint key_length,
const char *table_name, const char *path); const char *table_name, const char *path);
void free_table_share(TABLE_SHARE *share); 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); 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); 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_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase);
bool check_db_name(LEX_STRING *db); bool check_db_name(LEX_STRING *db);

View File

@ -2166,6 +2166,13 @@ ha_innobase::init_table_handle_for_HANDLER(void)
reset_template(prebuilt); 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. Opens an InnoDB database.
@return 0 on success, error code on failure */ @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->alter_table_flags = innobase_alter_table_flags;
innobase_hton->kill_query = innobase_kill_query; 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); ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -3349,13 +3359,6 @@ ha_innobase::table_flags() const
return int_table_flags | HA_BINLOG_STMT_CAPABLE; return int_table_flags | HA_BINLOG_STMT_CAPABLE;
} }
/****************************************************************//**
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). Returns the table type (storage engine name).
@return table type */ @return table type */

View File

@ -2615,7 +2615,9 @@ innobase_init(
innobase_hton->release_temporary_latches=innobase_release_temporary_latches; innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
innobase_hton->alter_table_flags = innobase_alter_table_flags; innobase_hton->alter_table_flags = innobase_alter_table_flags;
innobase_hton->kill_query = innobase_kill_query; 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); ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);