diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index ede5d9a32fd..34dc1cb5b2e 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5203,6 +5203,27 @@ select * from bug15205; val drop table bug15205; drop table bug15205_2; +set names latin1; +create table t1 ( +c varchar(1), +name varchar(64) +) character set latin1 engine=csv; +insert into t1 values (0xC0,'LATIN CAPITAL LETTER A WITH GRAVE'); +insert into t1 values (0xE0,'LATIN SMALL LETTER A WITH GRAVE'); +insert into t1 values (0xEE,'LATIN SMALL LETTER I WITH CIRCUMFLEX'); +insert into t1 values (0xFE,'LATIN SMALL LETTER THORN'); +insert into t1 values (0xF7,'DIVISION SIGN'); +insert into t1 values (0xFF,'LATIN SMALL LETTER Y WITH DIAERESIS'); +select hex(c), c, name from t1 order by 1; +hex(c) c name +C0 À LATIN CAPITAL LETTER A WITH GRAVE +E0 à LATIN SMALL LETTER A WITH GRAVE +EE î LATIN SMALL LETTER I WITH CIRCUMFLEX +F7 ÷ DIVISION SIGN +FE þ LATIN SMALL LETTER THORN +FF ÿ LATIN SMALL LETTER Y WITH DIAERESIS +drop table t1; +End of 5.0 tests create table bug22080_1 (id int,string varchar(64)) Engine=CSV; create table bug22080_2 (id int,string varchar(64)) Engine=CSV; create table bug22080_3 (id int,string varchar(64)) Engine=CSV; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 76667829864..bb4fc654b38 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -852,8 +852,8 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t1' is differently defined or of non-MyISAM type or doesn't exist -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t1(a INT); @@ -861,7 +861,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t2(a BLOB); @@ -869,7 +869,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table './test/t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt ALTER TABLE t2 MODIFY a INT; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index acab2f17910..66cd929ee05 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -752,4 +752,6 @@ Tables_in_test Table_type été BASE TABLE drop table `été`; set names latin1; +show columns from `#mysql50#????????`; +Got one of the listed errors End of 5.1 tests diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 62482d576b2..c7c7f3e13ab 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1596,6 +1596,27 @@ select * from bug15205; drop table bug15205; drop table bug15205_2; + +# +# Bug#28862 "Extended Latin1 characters get lost in CVS engine" +# +set names latin1; +create table t1 ( + c varchar(1), + name varchar(64) +) character set latin1 engine=csv; +insert into t1 values (0xC0,'LATIN CAPITAL LETTER A WITH GRAVE'); +insert into t1 values (0xE0,'LATIN SMALL LETTER A WITH GRAVE'); +insert into t1 values (0xEE,'LATIN SMALL LETTER I WITH CIRCUMFLEX'); +insert into t1 values (0xFE,'LATIN SMALL LETTER THORN'); +insert into t1 values (0xF7,'DIVISION SIGN'); +insert into t1 values (0xFF,'LATIN SMALL LETTER Y WITH DIAERESIS'); +select hex(c), c, name from t1 order by 1; +drop table t1; + +--echo End of 5.0 tests + + # # Bug#22080 "CHECK fails to identify some corruption" # diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 60e680c63f3..8d41399df70 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -593,4 +593,10 @@ show full tables; drop table `été`; set names latin1; +# +# Bug#26402 Server crashes with old-style named table +# +--error ER_NO_SUCH_TABLE,ER_FILE_NOT_FOUND +show columns from `#mysql50#????????`; + --echo End of 5.1 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7fb4d95f1f6..921a940834f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1920,6 +1920,10 @@ uint filename_to_tablename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length); uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *table, const char *ext, uint flags); + +#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" +#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 + /* Flags for conversion functions. */ #define FN_FROM_IS_TMP (1 << 0) #define FN_TO_IS_TMP (1 << 1) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index c0161463550..a44e20b8daf 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -210,6 +210,11 @@ static void reap_plugins(void); /* declared in set_var.cc */ extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error); +#ifdef EMBEDDED_LIBRARY +/* declared in sql_base.cc */ +extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); +#endif /* EMBEDDED_LIBRARY */ + /**************************************************************************** Value type thunks, allows the C world to play in the C++ world @@ -1307,6 +1312,9 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) READ_RECORD read_record_info; int error; THD *new_thd; +#ifdef EMBEDDED_LIBRARY + bool table_exists; +#endif /* EMBEDDED_LIBRARY */ DBUG_ENTER("plugin_load"); if (!(new_thd= new THD)) @@ -1323,6 +1331,20 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) tables.alias= tables.table_name= (char*)"plugin"; tables.lock_type= TL_READ; tables.db= new_thd->db; + +#ifdef EMBEDDED_LIBRARY + /* + When building an embedded library, if the mysql.plugin table + does not exist, we silently ignore the missing table + */ + pthread_mutex_lock(&LOCK_open); + if (check_if_table_exists(new_thd, &tables, &table_exists)) + table_exists= FALSE; + pthread_mutex_unlock(&LOCK_open); + if (!table_exists) + goto end; +#endif /* EMBEDDED_LIBRARY */ + if (simple_open_n_lock_tables(new_thd, &tables)) { DBUG_PRINT("error",("Can't open plugin table")); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7c13f9f2c54..4378d69dd9f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,10 +54,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); -#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" -#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 - - /* Translate a file name to a table name (WL #1324). diff --git a/sql/table.cc b/sql/table.cc index 745f3a2a34e..7076dc2d8f8 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -343,10 +343,25 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) strxmov(path, share->normalized_path.str, reg_ext, NullS); if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) { - if (strchr(share->table_name.str, '@')) + /* + We don't try to open 5.0 unencoded name, if + - non-encoded name contains '@' signs, + because '@' can be misinterpreted. + It is not clear if '@' is escape character in 5.1, + or a normal character in 5.0. + + - non-encoded db or table name contain "#mysql50#" prefix. + This kind of tables must have been opened only by the + my_open() above. + */ + if (strchr(share->table_name.str, '@') || + !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX, + MYSQL50_TABLE_NAME_PREFIX_LENGTH) || + !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX, + MYSQL50_TABLE_NAME_PREFIX_LENGTH)) goto err_not_open; - /* Try unecoded 5.0 name */ + /* Try unencoded 5.0 name */ uint length; strxnmov(path, sizeof(path)-1, mysql_data_home, "/", share->db.str, "/", diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 9eead7a059c..6de153c82d7 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -444,7 +444,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) records_is_known(0) { /* Set our original buffers from pre-allocated memory */ - buffer.set((char*)byte_buffer, IO_SIZE, system_charset_info); + buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); chain= chain_buffer; file_buff= new Transparent_file(); } @@ -679,7 +679,7 @@ int ha_tina::find_current_row(uchar *buf) } if (bitmap_is_set(table->read_set, (*field)->field_index)) - (*field)->store(buffer.ptr(), buffer.length(), system_charset_info); + (*field)->store(buffer.ptr(), buffer.length(), buffer.charset()); } next_position= end_offset + eoln_len; error= 0; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 04a9938f315..c03c1e28014 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -52,11 +52,22 @@ extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, uint t1_keys, uint t1_recs, MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, uint t2_keys, uint t2_recs, bool strict); +static void split_file_name(const char *file_name, + LEX_STRING *db, LEX_STRING *name); + + extern "C" void myrg_print_wrong_table(const char *table_name) { + LEX_STRING db, name; + char buf[FN_REFLEN]; + split_file_name(table_name, &db, &name); + memcpy(buf, db.str, db.length); + buf[db.length]= '.'; + memcpy(buf + db.length + 1, name.str, name.length); + buf[db.length + name.length + 1]= 0; push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE), - table_name); + buf); }