* 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_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 */

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.
#

View File

@ -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 #

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
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
#

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
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
SHOW WARNINGS;
--disable_warnings
--error 1051
DROP TABLE t1;
--enable_warnings
--echo #
--echo # Cleanup

View File

@ -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'

View File

@ -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

View File

@ -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;

View File

@ -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",

View File

@ -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
#

View File

@ -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

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)))
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. */

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 */
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;
}

View File

@ -6599,4 +6599,4 @@ ER_CANT_START_STOP_SLAVE
ER_SLAVE_STARTED
eng "SLAVE '%.*s' started"
ER_SLAVE_STOPPED
eng "SLAVE '%.*s' stopped"
eng "SLAVE '%.*s' stopped"

View File

@ -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, &not_used, hash_value);
mysql_mutex_unlock(&LOCK_open);
if (share == NULL)
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,
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;

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,
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);

View File

@ -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;

View File

@ -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();

View File

@ -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 */

View File

@ -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);

View File

@ -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
@ -3349,13 +3359,6 @@ ha_innobase::table_flags() const
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).
@return table type */

View File

@ -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);