diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index aa47b8c437e..bab60774b32 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1807,3 +1807,47 @@ USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) WHERE COLUMNS.TABLE_SCHEMA = 'test' 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 +# +# 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 +# diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f5fab966bdd..bc73e8411ca 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1555,3 +1555,56 @@ WHERE COLUMNS.TABLE_SCHEMA = 'test' 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 # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fe7ec83b845..8caae3ee406 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2902,8 +2902,12 @@ retry_share: */ if (check_and_update_table_version(thd, table_list, share)) 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; + } /* Open view */ if (open_new_frm(thd, share, alias, @@ -2931,7 +2935,11 @@ retry_share: */ 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; + } if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16deb50b17c..a25cfcdedc8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4934,18 +4934,29 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, else 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; if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) { /* - We should use tables->view->select_lex.item_list here and - can not use Field_iterator_view because the view always uses - temporary algorithm during opening for I_S and - TABLE_LIST fields 'field_translation' & 'field_translation_end' - are uninitialized is this case. + We should use tables->view->select_lex.item_list here + and can not use Field_iterator_view because the view + always uses temporary algorithm during opening for I_S + and TABLE_LIST fields 'field_translation' + & 'field_translation_end' are uninitialized is this + case. */ List *fields= &tables->view->select_lex.item_list; List_iterator it(*fields);