Skip to content

Commit

Permalink
MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition
Browse files Browse the repository at this point in the history
When you only need view structure, don't call handle_derived with
DT_CREATE and rely on its internal hackish check to skip DT_CREATE.
Because handle_derived is called from many different places,
and this internal hackish check is indiscriminative.

Instead, just don't ask handle_derived to do DT_CREATE
if you don't want it to do DT_CREATE.
  • Loading branch information
vuvova committed May 4, 2021
1 parent 1ae7673 commit 5ad7f52
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 23 deletions.
32 changes: 32 additions & 0 deletions mysql-test/r/show.result
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#
# MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS
# MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS
# MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings
#
show statistics;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'statistics' at line 1
show spatial_ref_sys
Expand All @@ -10,3 +15,30 @@ show geometry_columns;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'geometry_columns' at line 1
show nonexistent;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'nonexistent' at line 1
#
# MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition
#
create table t1 (nm varchar(32), a int);
insert t1 values ('1',1),('2',2),('3',3);
show tables
where tables_in_test in (select *
from (select nm from test.t1 group by nm) dt);
Tables_in_test
show fields from test.t1
where field in (select * from (select nm from test.t1 group by nm) dt);
Field Type Null Key Default Extra
insert t1 values ('nm',0);
show fields from test.t1
where field in (select * from (select nm from test.t1 group by nm) dt);
Field Type Null Key Default Extra
nm varchar(32) YES NULL
show fields from test.t1 where field in
(select * from (select column_name from information_schema.columns
where table_name='t1' group by column_name) dt);
Field Type Null Key Default Extra
nm varchar(32) YES NULL
a int(11) YES NULL
drop table t1;
#
# End of 10.2 tests
#
34 changes: 29 additions & 5 deletions mysql-test/t/show.test
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS
# MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS
# MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings
#
--echo #
--echo # MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS
--echo # MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS
--echo # MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings
--echo #
--error ER_PARSE_ERROR
show statistics;
--error ER_PARSE_ERROR
Expand All @@ -13,3 +13,27 @@ show system_variables;
show geometry_columns;
--error ER_PARSE_ERROR
show nonexistent;

--echo #
--echo # MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition
--echo #
create table t1 (nm varchar(32), a int);
insert t1 values ('1',1),('2',2),('3',3);

show tables
where tables_in_test in (select *
from (select nm from test.t1 group by nm) dt);
show fields from test.t1
where field in (select * from (select nm from test.t1 group by nm) dt);
insert t1 values ('nm',0);
show fields from test.t1
where field in (select * from (select nm from test.t1 group by nm) dt);

show fields from test.t1 where field in
(select * from (select column_name from information_schema.columns
where table_name='t1' group by column_name) dt);
drop table t1;

--echo #
--echo # End of 10.2 tests
--echo #
1 change: 0 additions & 1 deletion sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4939,7 +4939,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
uint counter;
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_normal_and_derived_tables");
DBUG_ASSERT(!thd->fill_derived_tables());
if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) ||
mysql_handle_derived(thd->lex, dt_phases))
goto end;
Expand Down
4 changes: 0 additions & 4 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -3469,10 +3469,6 @@ class THD :public Statement,
{
return server_status & SERVER_STATUS_IN_TRANS;
}
inline bool fill_derived_tables()
{
return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure();
}
inline bool fill_information_schema_tables()
{
return !stmt_arena->is_stmt_prepare();
Expand Down
7 changes: 0 additions & 7 deletions sql/sql_derived.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ bool
mysql_handle_derived(LEX *lex, uint phases)
{
bool res= FALSE;
THD *thd= lex->thd;
DBUG_ENTER("mysql_handle_derived");
DBUG_PRINT("enter", ("phases: 0x%x", phases));
if (!lex->derived_tables)
Expand All @@ -85,8 +84,6 @@ mysql_handle_derived(LEX *lex, uint phases)
break;
if (!(phases & phase_flag))
continue;
if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
break;

for (SELECT_LEX *sl= lex->all_selects_list;
sl && !res;
Expand Down Expand Up @@ -169,7 +166,6 @@ bool
mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
{
bool res= FALSE;
THD *thd= lex->thd;
uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE :
DT_PHASES_MATERIALIZE);
DBUG_ENTER("mysql_handle_single_derived");
Expand All @@ -192,8 +188,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
if (phase_flag != DT_PREPARE &&
!(allowed_phases & phase_flag))
continue;
if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
break;

if ((res= (*processors[phase])(lex->thd, lex, derived)))
break;
Expand Down Expand Up @@ -1376,4 +1370,3 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
thd->lex->current_select= save_curr_select;
DBUG_RETURN(false);
}

8 changes: 4 additions & 4 deletions sql/sql_prepare.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,7 @@ static int mysql_test_select(Prepared_statement *stmt,
}

if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE))
DT_INIT | DT_PREPARE))
goto error;

thd->lex->used_tables= 0; // Updated by setup_fields
Expand Down Expand Up @@ -1721,7 +1721,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
DBUG_RETURN(TRUE);

if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE))
DT_INIT | DT_PREPARE))
DBUG_RETURN(TRUE);
DBUG_RETURN(setup_fields(thd, Ref_ptr_array(),
*values, MARK_COLUMNS_NONE, 0, NULL, 0));
Expand Down Expand Up @@ -1753,7 +1753,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
if ((tables &&
check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) ||
open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE))
DT_INIT | DT_PREPARE))
goto error;

while ((var= it++))
Expand Down Expand Up @@ -1918,7 +1918,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt)

if (open_normal_and_derived_tables(stmt->thd, lex->query_tables,
MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE))
DT_INIT | DT_PREPARE))
DBUG_RETURN(TRUE);

select_lex->context.resolve_in_select_list= TRUE;
Expand Down
4 changes: 2 additions & 2 deletions sql/sql_show.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1528,7 +1528,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)

if (open_normal_and_derived_tables(thd, table_list,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL,
DT_INIT | DT_PREPARE | DT_CREATE))
DT_INIT | DT_PREPARE))
DBUG_VOID_RETURN;
table= table_list->table;

Expand Down Expand Up @@ -4414,7 +4414,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
(can_deadlock ?
MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)),
DT_INIT | DT_PREPARE | DT_CREATE));
DT_INIT | DT_PREPARE));

/*
Restore old value of sql_command back as it is being looked at in
Expand Down

0 comments on commit 5ad7f52

Please sign in to comment.