Commit a20195bb authored by Sergei Golubchik's avatar Sergei Golubchik Committed by Oleksandr Byelkin

MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition

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.
parent 72fa9dab
#
# 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; 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 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 show spatial_ref_sys
...@@ -10,3 +15,30 @@ show geometry_columns; ...@@ -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 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; 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 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
#
# --echo #
# MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS --echo # MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS
# MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS --echo # 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 # MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings
# --echo #
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
show statistics; show statistics;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
...@@ -13,3 +13,27 @@ show system_variables; ...@@ -13,3 +13,27 @@ show system_variables;
show geometry_columns; show geometry_columns;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
show nonexistent; 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 #
...@@ -4939,7 +4939,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags, ...@@ -4939,7 +4939,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
uint counter; uint counter;
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_normal_and_derived_tables"); DBUG_ENTER("open_normal_and_derived_tables");
DBUG_ASSERT(!thd->fill_derived_tables());
if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) || if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) ||
mysql_handle_derived(thd->lex, dt_phases)) mysql_handle_derived(thd->lex, dt_phases))
goto end; goto end;
......
...@@ -3469,10 +3469,6 @@ class THD :public Statement, ...@@ -3469,10 +3469,6 @@ class THD :public Statement,
{ {
return server_status & SERVER_STATUS_IN_TRANS; 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() inline bool fill_information_schema_tables()
{ {
return !stmt_arena->is_stmt_prepare(); return !stmt_arena->is_stmt_prepare();
......
...@@ -70,7 +70,6 @@ bool ...@@ -70,7 +70,6 @@ bool
mysql_handle_derived(LEX *lex, uint phases) mysql_handle_derived(LEX *lex, uint phases)
{ {
bool res= FALSE; bool res= FALSE;
THD *thd= lex->thd;
DBUG_ENTER("mysql_handle_derived"); DBUG_ENTER("mysql_handle_derived");
DBUG_PRINT("enter", ("phases: 0x%x", phases)); DBUG_PRINT("enter", ("phases: 0x%x", phases));
if (!lex->derived_tables) if (!lex->derived_tables)
...@@ -85,8 +84,6 @@ mysql_handle_derived(LEX *lex, uint phases) ...@@ -85,8 +84,6 @@ mysql_handle_derived(LEX *lex, uint phases)
break; break;
if (!(phases & phase_flag)) if (!(phases & phase_flag))
continue; continue;
if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
break;
for (SELECT_LEX *sl= lex->all_selects_list; for (SELECT_LEX *sl= lex->all_selects_list;
sl && !res; sl && !res;
...@@ -169,7 +166,6 @@ bool ...@@ -169,7 +166,6 @@ bool
mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
{ {
bool res= FALSE; bool res= FALSE;
THD *thd= lex->thd;
uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE : uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE :
DT_PHASES_MATERIALIZE); DT_PHASES_MATERIALIZE);
DBUG_ENTER("mysql_handle_single_derived"); DBUG_ENTER("mysql_handle_single_derived");
...@@ -192,8 +188,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) ...@@ -192,8 +188,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
if (phase_flag != DT_PREPARE && if (phase_flag != DT_PREPARE &&
!(allowed_phases & phase_flag)) !(allowed_phases & phase_flag))
continue; continue;
if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
break;
if ((res= (*processors[phase])(lex->thd, lex, derived))) if ((res= (*processors[phase])(lex->thd, lex, derived)))
break; break;
...@@ -1376,4 +1370,3 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) ...@@ -1376,4 +1370,3 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
thd->lex->current_select= save_curr_select; thd->lex->current_select= save_curr_select;
DBUG_RETURN(false); DBUG_RETURN(false);
} }
...@@ -1659,7 +1659,7 @@ static int mysql_test_select(Prepared_statement *stmt, ...@@ -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, 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; goto error;
thd->lex->used_tables= 0; // Updated by setup_fields thd->lex->used_tables= 0; // Updated by setup_fields
...@@ -1721,7 +1721,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, ...@@ -1721,7 +1721,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, 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(TRUE);
DBUG_RETURN(setup_fields(thd, Ref_ptr_array(), DBUG_RETURN(setup_fields(thd, Ref_ptr_array(),
*values, MARK_COLUMNS_NONE, 0, NULL, 0)); *values, MARK_COLUMNS_NONE, 0, NULL, 0));
...@@ -1753,7 +1753,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, ...@@ -1753,7 +1753,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
if ((tables && if ((tables &&
check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) || check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) ||
open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE)) DT_INIT | DT_PREPARE))
goto error; goto error;
while ((var= it++)) while ((var= it++))
...@@ -1918,7 +1918,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt) ...@@ -1918,7 +1918,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, if (open_normal_and_derived_tables(stmt->thd, lex->query_tables,
MYSQL_OPEN_FORCE_SHARED_MDL, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_INIT | DT_PREPARE | DT_CREATE)) DT_INIT | DT_PREPARE))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
select_lex->context.resolve_in_select_list= TRUE; select_lex->context.resolve_in_select_list= TRUE;
......
...@@ -1528,7 +1528,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) ...@@ -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, if (open_normal_and_derived_tables(thd, table_list,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL,
DT_INIT | DT_PREPARE | DT_CREATE)) DT_INIT | DT_PREPARE))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
table= table_list->table; table= table_list->table;
...@@ -4414,7 +4414,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, ...@@ -4414,7 +4414,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
(can_deadlock ? (can_deadlock ?
MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)), 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 Restore old value of sql_command back as it is being looked at in
......
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