mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
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. mysql-test/r/information_schema.result: Update results - a fix for Bug#56540. mysql-test/t/information_schema.test: Add a test case for Bug#56540 sql/sql_base.cc: Push an error into the Diagnostics area when we return an error. This directs get_all_tables() to the execution branch which doesn't involve 'process_table()' when no table/view was opened. sql/sql_show.cc: Do not try to access underlying table fields when opening of a view failed. The underlying table is closed in that case, and accessing its fields may lead to dereferencing a damaged pointer.
This commit is contained in:
parent
5a57a45c66
commit
248625d910
4 changed files with 124 additions and 8 deletions
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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<Item> *fields= &tables->view->select_lex.item_list;
|
||||
List_iterator<Item> it(*fields);
|
||||
|
|
Loading…
Reference in a new issue