diff options
author | Sergei Golubchik <serg@mariadb.org> | 2021-05-03 23:26:30 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-05-04 09:01:55 +0200 |
commit | 5ad7f52558cb283c685322df1fcdbd10daf3c3ae (patch) | |
tree | df71238c727173fa80e3c18f909800e52ea95e1d | |
parent | 1ae7673aae7f82c4e659b1337177f2696c8e45ba (diff) | |
download | mariadb-git-5ad7f52558cb283c685322df1fcdbd10daf3c3ae.tar.gz |
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.
-rw-r--r-- | mysql-test/r/show.result | 32 | ||||
-rw-r--r-- | mysql-test/t/show.test | 34 | ||||
-rw-r--r-- | sql/sql_base.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_derived.cc | 7 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 8 | ||||
-rw-r--r-- | sql/sql_show.cc | 4 |
7 files changed, 67 insertions, 23 deletions
diff --git a/mysql-test/r/show.result b/mysql-test/r/show.result index 3dd7af5de05..d1b373d8969 100644 --- a/mysql-test/r/show.result +++ b/mysql-test/r/show.result @@ -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 @@ -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 +# diff --git a/mysql-test/t/show.test b/mysql-test/t/show.test index 3101f443264..f2f6efc4e45 100644 --- a/mysql-test/t/show.test +++ b/mysql-test/t/show.test @@ -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 @@ -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 # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3403f9e03ff..16689f86c4e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -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; diff --git a/sql/sql_class.h b/sql/sql_class.h index ce4bf67e745..e08bb3e6358 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3469,10 +3469,6 @@ public: { 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(); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 5f90f2f9ab0..3ab93840d80 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -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) @@ -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; @@ -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"); @@ -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; @@ -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); } - diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 56a38757f28..a8a671075f9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -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 @@ -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)); @@ -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++)) @@ -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; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7023e5fe9ea..b5622497a06 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -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; @@ -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 |