MDEV-10679 Crash in performance schema and partitioning with discovery

Crash happened because in discover, table->work_part_info was not properly
reset before execution.
Fixed by resetting before calling execute alter table, create table or
mysql_create_frm_image.
This commit is contained in:
Monty 2018-05-25 11:51:43 +03:00
parent 199517f501
commit d8da920264
6 changed files with 33 additions and 6 deletions

View File

@ -0,0 +1,10 @@
#
# MDEV-10679
# Server crashes in in mysql_create_frm_image upon query from
# performance schema in ps-protocol mode
#
CREATE TABLE t1 (i INT);
ALTER TABLE t1 ADD PARTITION (PARTITION p VALUES LESS THAN (1));
ERROR HY000: Partition management on a not partitioned table is not possible
SELECT * FROM performance_schema.events_stages_summary_by_user_by_event_name;
DROP TABLE t1;

View File

@ -0,0 +1,15 @@
--source include/have_perfschema.inc
--echo #
--echo # MDEV-10679
--echo # Server crashes in in mysql_create_frm_image upon query from
--echo # performance schema in ps-protocol mode
--echo #
CREATE TABLE t1 (i INT);
--error ER_PARTITION_MGMT_ON_NONPARTITIONED
ALTER TABLE t1 ADD PARTITION (PARTITION p VALUES LESS THAN (1));
--disable_result_log
SELECT * FROM performance_schema.events_stages_summary_by_user_by_event_name;
--enable_result_log
DROP TABLE t1;

View File

@ -262,8 +262,8 @@ bool Sql_cmd_alter_table::execute(THD *thd)
- For temporary MERGE tables we do not track if their child tables are
base or temporary. As result we can't guarantee that privilege check
which was done in presence of temporary child will stay relevant later
as this temporary table might be removed.
which was done in presence of temporary child will stay relevant
later as this temporary table might be removed.
If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for
the underlying *base* tables, it would create a security breach as in
@ -303,6 +303,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
create_info.data_file_name= create_info.index_file_name= NULL;
thd->enable_slow_log= opt_log_slow_admin_statements;
thd->work_part_info= 0;
#ifdef WITH_WSREP
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);

View File

@ -2475,10 +2475,6 @@ mysql_execute_command(THD *thd)
#endif
DBUG_ENTER("mysql_execute_command");
#ifdef WITH_PARTITION_STORAGE_ENGINE
thd->work_part_info= 0;
#endif
DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt);
/*
Each statement or replication event which might produce deadlock
@ -3318,6 +3314,7 @@ mysql_execute_command(THD *thd)
create_info.add(DDL_options_st::OPT_OR_REPLACE_SLAVE_GENERATED);
}
thd->work_part_info= 0;
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
partition_info *part_info= thd->lex->part_info;

View File

@ -6057,6 +6057,7 @@ remove_key:
}
}
DBUG_ASSERT(thd->work_part_info == 0);
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *tab_part_info= table->part_info;
thd->work_part_info= thd->lex->part_info;
@ -8411,6 +8412,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_ENTER("mysql_alter_table");
thd->work_part_info= 0; // Used by partitioning
/*
Check if we attempt to alter mysql.slow_log or
mysql.general_log table and return an error if

View File

@ -2233,6 +2233,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
goto ret;
thd->lex->create_info.db_type= hton;
thd->work_part_info= 0; // For partitioning
if (tabledef_version.str)
thd->lex->create_info.tabledef_version= tabledef_version;