From: Date: May 3 2008 9:51pm Subject: bk commit into 5.1 tree (istruewing:1.2568) BUG#35068 List-Archive: http://lists.mysql.com/commits/46333 X-Bug: 35068 Message-Id: Below is the list of changes that have just been committed into a local 5.1 repository of istruewing. When istruewing does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2008-05-03 21:51:42+02:00, istruewing@stripped +3 -0 Bug#35068 - Assertion fails when reading from i_s.tables and there is incorrect merge table SELECT * on INFORMATION_SCHEMA.TABLES crashed the server when a MERGE table included a non-existent MyISAM table. The MERGE table adds its children to the table list so that open_tables() opens them too. If a child cannot be opened, open_tables() returns with the open MERGE table and opened MyISAM tables as far as they could be opened. However, the returned error message is ER_NO_SUCH_TABLE. get_all_tables() from information schema assumed that it opens one table at a time. If it cannot be opened, and the error is ER_NO_SUCH_TABLE, it assumed that no table needs to be closed. Added condition !thd->open_tables to detect open failure of MERGE table. So if any table was opened, closing will not be skipped. mysql-test/r/merge.result@stripped, 2008-05-03 21:51:40+02:00, istruewing@stripped +6 -0 Bug#35068 - Assertion fails when reading from i_s.tables and there is incorrect merge table Added test result. mysql-test/t/merge.test@stripped, 2008-05-03 21:51:40+02:00, istruewing@stripped +11 -0 Bug#35068 - Assertion fails when reading from i_s.tables and there is incorrect merge table Added test. sql/sql_show.cc@stripped, 2008-05-03 21:51:40+02:00, istruewing@stripped +14 -1 Bug#35068 - Assertion fails when reading from i_s.tables and there is incorrect merge table Added condition !thd->open_tables to detect open failure of MERGE table. diff -Nrup a/mysql-test/r/merge.result b/mysql-test/r/merge.result --- a/mysql-test/r/merge.result 2008-04-22 14:32:08 +02:00 +++ b/mysql-test/r/merge.result 2008-05-03 21:51:40 +02:00 @@ -2011,3 +2011,9 @@ test.t1 optimize status OK FLUSH TABLES m1, t1; UNLOCK TABLES; DROP TABLE t1, m1; +CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=FIRST; +SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT +NULL test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Table 'test.t1' doesn't exist +DROP TABLE tm1; +End of 5.1 tests diff -Nrup a/mysql-test/t/merge.test b/mysql-test/t/merge.test --- a/mysql-test/t/merge.test 2008-04-22 14:32:08 +02:00 +++ b/mysql-test/t/merge.test 2008-05-03 21:51:40 +02:00 @@ -1401,3 +1401,14 @@ FLUSH TABLES m1, t1; UNLOCK TABLES; DROP TABLE t1, m1; +# +# Bug#35068 - Assertion fails when reading from i_s.tables +# and there is incorrect merge table +# +CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=FIRST; +--replace_column 8 # 9 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 17 # 19 # 20 # +SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'; +DROP TABLE tm1; + +--echo End of 5.1 tests + diff -Nrup a/sql/sql_show.cc b/sql/sql_show.cc --- a/sql/sql_show.cc 2008-03-28 11:03:04 +01:00 +++ b/sql/sql_show.cc 2008-05-03 21:51:40 +02:00 @@ -3275,6 +3275,18 @@ int get_all_tables(THD *thd, TABLE_LIST lex->sql_command= SQLCOM_SHOW_FIELDS; show_table_list->i_s_requested_object= schema_table->i_s_requested_object; + /* + Below we want to ignore non-existing tables. + ER_NO_SUCH_TABLE is not sufficient for a MERGE table if + one of the children does not exist. In this case we get + ER_NO_SUCH_TABLE, but thd->open_tables contains the MERGE + parent and perhaps some children. So we use the + combination of ER_NO_SUCH_TABLE && !thd->open_tables for + the final decision. Here we assert that thd->open_tables + is empty before we open the table. If this fails, we need + another condition to catch a MERGE table. + */ + DBUG_ASSERT(!thd->open_tables); res= open_normal_and_derived_tables(thd, show_table_list, MYSQL_LOCK_IGNORE_FLUSH); lex->sql_command= save_sql_command; @@ -3287,7 +3299,8 @@ int get_all_tables(THD *thd, TABLE_LIST for thd->main_da.sql_errno(). */ if (res && thd->is_error() && - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + thd->main_da.sql_errno() == ER_NO_SUCH_TABLE && + !thd->open_tables) { /* Hide error for not existing table.