From 3bb1769bc07785ffc4e586f191521f4ba9f3bafc Mon Sep 17 00:00:00 2001 From: "antony@ppcg5.local" <> Date: Tue, 12 Jun 2007 19:28:05 -0700 Subject: [PATCH 1/5] Bug#25800 "Embedded server requires mysql.plugin" Embedded builds should not print any error when the mysql.plugin table does not exist. This is achieved by checking for the existance of the mysql.plugin table before attempting to open it and proceed silently if it does not exist. --- sql/sql_plugin.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 37301751d03..ad521cb2ff7 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 @@ -1299,6 +1304,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)) @@ -1315,6 +1323,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")); From 01c9419cec2bd91fe1b7b970614949e6111b131f Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Thu, 14 Jun 2007 16:18:01 +0500 Subject: [PATCH 2/5] BUG#26976 - Missing table in merge not noted in related error msg + SHOW CREATE TABLE fails Addition to the fix: report db name + table name instead of table path. This solves embedded merge test failure. --- mysql-test/r/merge.result | 8 ++++---- sql/ha_myisammrg.cc | 13 ++++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 9f7d5f54d0e..42669eeb66f 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -849,8 +849,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); @@ -858,7 +858,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); @@ -866,7 +866,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/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index e7baa6705ee..60aa4bd6adc 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -72,11 +72,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); } From 6d2ffe7b8e1eff9ca7ade9bdb26da1a5e7947537 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com/bar.myoffice.izhnet.ru" <> Date: Thu, 14 Jun 2007 16:28:33 +0500 Subject: [PATCH 3/5] Bug#26402 Server crashes with old-style named table Problem: crash on attempt to open a table having "#mysql50#" prefix in db or table name. Fix: This prefix is reserved for "mysql_upgrade" to access 5.0 tables whose file names are not encoded according to "5.1 tablename to filename encoded". Don't try open tables whose db name or table name has this prefix. --- mysql-test/r/show_check.result | 2 ++ mysql-test/t/show_check.test | 6 ++++++ sql/mysql_priv.h | 4 ++++ sql/sql_table.cc | 4 ---- sql/table.cc | 19 +++++++++++++++++-- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index acab2f17910..dbb1f063513 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#????????`; +ERROR 42S02: Table 'test.#mysql50#????????' doesn't exist End of 5.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 60e680c63f3..3aeb92ac203 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 +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_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, "/", From caf85332ba6186dcfba3ad42d79959e0b0807740 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com/bar.myoffice.izhnet.ru" <> Date: Fri, 15 Jun 2007 11:19:35 +0500 Subject: [PATCH 4/5] Bug#28862 Extended Latin1 characters get lost in CVS engine Problem: Temporary buffer which is used for quoting and escaping was initialized to character set utf8, and thus didn't allow to store data in other character sets. Fix: changing character set of the buffer to be able to store any arbitrary sequence of bytes. --- mysql-test/r/csv.result | 21 +++++++++++++++++++++ mysql-test/t/csv.test | 18 ++++++++++++++++++ sql/examples/ha_tina.cc | 4 ++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 8ec79e9d7a9..3900597d2a6 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5009,3 +5009,24 @@ 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 diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 687f3ea3918..b724b4ce47c 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1410,3 +1410,21 @@ 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 diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 00f927aa7b7..2c5226222e2 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -301,7 +301,7 @@ ha_tina::ha_tina(TABLE *table_arg) chain_size(DEFAULT_CHAIN_LENGTH), records_is_known(0) { /* Set our original buffers from pre-allocated memory */ - buffer.set(byte_buffer, IO_SIZE, system_charset_info); + buffer.set(byte_buffer, IO_SIZE, &my_charset_bin); chain= chain_buffer; } @@ -447,7 +447,7 @@ int ha_tina::find_current_row(byte *buf) else buffer.append(*mapped_ptr); } - (*field)->store(buffer.ptr(), buffer.length(), system_charset_info); + (*field)->store(buffer.ptr(), buffer.length(), buffer.charset()); } next_position= (end_ptr - share->mapped_file)+1; /* Maybe use \N for null? */ From f28a584287f77ac87d0f07b6f9b07c081f215a24 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com/bar.myoffice.izhnet.ru" <> Date: Fri, 15 Jun 2007 11:53:46 +0500 Subject: [PATCH 5/5] Additional fix for bug N26402: An attempt to open file with name '????????.frm' can produce different errors: - ER_NO_SUCH_TABLE on Unix - ER_FILE_NOT_FOUND on Windows because QUESTION MARK has special meaning on Windows. Make sure that any of these two errors happens. --- mysql-test/r/show_check.result | 2 +- mysql-test/t/show_check.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index dbb1f063513..66cd929ee05 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -753,5 +753,5 @@ Tables_in_test Table_type drop table `été`; set names latin1; show columns from `#mysql50#????????`; -ERROR 42S02: Table 'test.#mysql50#????????' doesn't exist +Got one of the listed errors End of 5.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 3aeb92ac203..8d41399df70 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -596,7 +596,7 @@ set names latin1; # # Bug#26402 Server crashes with old-style named table # ---error ER_NO_SUCH_TABLE +--error ER_NO_SUCH_TABLE,ER_FILE_NOT_FOUND show columns from `#mysql50#????????`; --echo End of 5.1 tests