diff options
author | Kristofer Pettersson <kristofer.pettersson@sun.com> | 2009-07-16 01:23:57 +0200 |
---|---|---|
committer | Kristofer Pettersson <kristofer.pettersson@sun.com> | 2009-07-16 01:23:57 +0200 |
commit | fae95a4933899edfd560735a3977a947e5551410 (patch) | |
tree | 08f32c85b9864081ad0e8a70215a655e64422eaf /sql/sql_handler.cc | |
parent | ed3b0a69cfbc5778f000df4d2e46baa1f1173c57 (diff) | |
download | mariadb-git-fae95a4933899edfd560735a3977a947e5551410.tar.gz |
Bug#45781 infinite hang/crash in "opening tables" after handler tries to open merge
table
The MERGE table storage engine does not support the HA_CAN_SQL_HANDLE feature
and any attempt to open the merge table will fail with ER_ILLEGAL_HA.
After an error occurred the tables that was opened must be closed again
or they will be left in an inconsistent state. However, the assumption
made in the code for closing and register handler tables was that only
one table will be opened, and this is not true for MERGE tables which
will cause multiple tables to open.
The next time a SELECT operation was issued on the merge table it
caused the system to freeze.
This patch fixes this issue by making sure that all tables which
are opened also are closed in the event of an error.
mysql-test/r/merge.result:
Added test case for bug 45781
mysql-test/t/merge.test:
Added test case for bug 45781
sql/sql_handler.cc:
* mysql_ha_open() was never ment to open more than one table. If we encounter more tables, we should
close all tables related to the current substatement and raise an exception.
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r-- | sql/sql_handler.cc | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 16810e29343..1e92d95573a 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -252,14 +252,37 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) /* for now HANDLER can be used only for real TABLES */ tables->required_type= FRMTYPE_TABLE; + /* + We use open_tables() here, rather than, say, + open_ltable() or open_table() because we would like to be able + to open a temporary table. + */ error= open_tables(thd, &tables, &counter, 0); - /* restore the state and merge the opened table into handler_tables list */ if (thd->open_tables) { - thd->open_tables->next= thd->handler_tables; - thd->handler_tables= thd->open_tables; + if (thd->open_tables->next) + { + /* + We opened something that is more than a single table. + This happens with MERGE engine. Don't try to link + this mess into thd->handler_tables list, close it + and report an error. We must do it right away + because mysql_ha_close_table(), called down the road, + can close a single table only. + */ + close_thread_tables(thd); + my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); + error= 1; + } + else + { + /* Merge the opened table into handler_tables list. */ + thd->open_tables->next= thd->handler_tables; + thd->handler_tables= thd->open_tables; + } } + /* Restore the state. */ thd->open_tables= backup_open_tables; if (error) |