Commit efcb38e7 authored by Konstantin Osipov's avatar Konstantin Osipov

A fix and a test case for Bug#56540 "Exception (crash) in

sql_show.cc during rqg_info_schema test on Windows".

Ensure we do not access freed memory when filling
information_schema.views when one of the views
could not be properly opened.
parent 7774a004
...@@ -1807,3 +1807,47 @@ USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) ...@@ -1807,3 +1807,47 @@ USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
WHERE COLUMNS.TABLE_SCHEMA = 'test' WHERE COLUMNS.TABLE_SCHEMA = 'test'
AND COLUMNS.TABLE_NAME = 't1'; AND COLUMNS.TABLE_NAME = 't1';
TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME TABLE_CATALOG ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME TABLE_CATALOG ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
#
# A test case for Bug#56540 "Exception (crash) in sql_show.cc
# during rqg_info_schema test on Windows"
# Ensure that we never access memory of a closed table,
# in particular, never access table->field[] array.
# Before the fix, the below test case, produced
# valgrind errors.
#
drop table if exists t1;
drop view if exists v1;
create table t1 (a int, b int);
create view v1 as select t1.a, t1.b from t1;
alter table t1 change b c int;
lock table t1 read;
# --> connection con1
flush tables;
# --> connection default
select * from information_schema.views;
TABLE_CATALOG def
TABLE_SCHEMA test
TABLE_NAME v1
VIEW_DEFINITION select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`
CHECK_OPTION NONE
IS_UPDATABLE
DEFINER root@localhost
SECURITY_TYPE DEFINER
CHARACTER_SET_CLIENT latin1
COLLATION_CONNECTION latin1_swedish_ci
Warnings:
Level Warning
Code 1356
Message View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
unlock tables;
#
# Cleanup.
#
# --> connection con1
# Reaping 'flush tables'
# --> connection default
drop table t1;
drop view v1;
#
# End of 5.5 tests
#
...@@ -1555,3 +1555,56 @@ WHERE COLUMNS.TABLE_SCHEMA = 'test' ...@@ -1555,3 +1555,56 @@ WHERE COLUMNS.TABLE_SCHEMA = 'test'
AND COLUMNS.TABLE_NAME = 't1'; AND COLUMNS.TABLE_NAME = 't1';
--echo #
--echo # A test case for Bug#56540 "Exception (crash) in sql_show.cc
--echo # during rqg_info_schema test on Windows"
--echo # Ensure that we never access memory of a closed table,
--echo # in particular, never access table->field[] array.
--echo # Before the fix, the below test case, produced
--echo # valgrind errors.
--echo #
--disable_warnings
drop table if exists t1;
drop view if exists v1;
--enable_warnings
create table t1 (a int, b int);
create view v1 as select t1.a, t1.b from t1;
alter table t1 change b c int;
lock table t1 read;
connect(con1, localhost, root,,);
--echo # --> connection con1
connection con1;
send flush tables;
--echo # --> connection default
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table flush" and
info = "flush tables";
--source include/wait_condition.inc
--vertical_results
select * from information_schema.views;
--horizontal_results
unlock tables;
--echo #
--echo # Cleanup.
--echo #
--echo # --> connection con1
connection con1;
--echo # Reaping 'flush tables'
reap;
disconnect con1;
--source include/wait_until_disconnected.inc
--echo # --> connection default
connection default;
drop table t1;
drop view v1;
--echo #
--echo # End of 5.5 tests
--echo #
...@@ -2902,8 +2902,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -2902,8 +2902,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
*/ */
if (check_and_update_table_version(thd, table_list, share)) if (check_and_update_table_version(thd, table_list, share))
goto err_unlock; goto err_unlock;
if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) if (table_list->i_s_requested_object & OPEN_TABLE_ONLY)
{
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
table_list->table_name);
goto err_unlock; goto err_unlock;
}
/* Open view */ /* Open view */
if (open_new_frm(thd, share, alias, if (open_new_frm(thd, share, alias,
...@@ -2931,7 +2935,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -2931,7 +2935,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
*/ */
if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) if (table_list->i_s_requested_object & OPEN_VIEW_ONLY)
{
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
table_list->table_name);
goto err_unlock; goto err_unlock;
}
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
{ {
......
...@@ -4934,18 +4934,29 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, ...@@ -4934,18 +4934,29 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
else else
table->field[4]->store(STRING_WITH_LEN("NONE"), cs); table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
if (table->pos_in_table_list->table_open_method & /*
OPEN_FULL_TABLE) Only try to fill in the information about view updatability
if it is requested as part of the top-level query (i.e.
it's select * from i_s.views, as opposed to, say, select
security_type from i_s.views). Do not try to access the
underlying tables if there was an error when opening the
view: all underlying tables are released back to the table
definition cache on error inside open_normal_and_derived_tables().
If a field is not assigned explicitly, it defaults to NULL.
*/
if (res == FALSE &&
table->pos_in_table_list->table_open_method & OPEN_FULL_TABLE)
{ {
updatable_view= 0; updatable_view= 0;
if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
{ {
/* /*
We should use tables->view->select_lex.item_list here and We should use tables->view->select_lex.item_list here
can not use Field_iterator_view because the view always uses and can not use Field_iterator_view because the view
temporary algorithm during opening for I_S and always uses temporary algorithm during opening for I_S
TABLE_LIST fields 'field_translation' & 'field_translation_end' and TABLE_LIST fields 'field_translation'
are uninitialized is this case. & 'field_translation_end' are uninitialized is this
case.
*/ */
List<Item> *fields= &tables->view->select_lex.item_list; List<Item> *fields= &tables->view->select_lex.item_list;
List_iterator<Item> it(*fields); List_iterator<Item> it(*fields);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment