mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Bug#52856 concurrent show columns or show full columns causes a crash!!!1
We should avoid any SHARE fields assignments as this is shared structure and assignments may affect other therads. To avoid this copy of SHARE struct is created and stored into TABLE struct which is used in get_schema_coulumns_record later. mysql-test/r/mdl_sync.result: test case mysql-test/t/mdl_sync.test: test case sql/sql_show.cc: We should avoid any SHARE fields assignments as this is shared structure and assignments may affect other therads. To avoid this copy of SHARE struct is created and stored into TABLE struct which is used in get_schema_coulumns_record later.
This commit is contained in:
parent
bac571e136
commit
8fa381fda3
3 changed files with 45 additions and 34 deletions
|
@ -2381,3 +2381,17 @@ commit;
|
|||
# Reap ALTER TABLE.
|
||||
set debug_sync= 'RESET';
|
||||
drop table t1;
|
||||
#
|
||||
# Bug#52856 concurrent show columns or show full columns causes a crash!!!
|
||||
#
|
||||
CREATE TABLE t1(a CHAR(255));
|
||||
SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed";
|
||||
SHOW FULL COLUMNS FROM t1;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR waiting";
|
||||
SHOW FULL COLUMNS FROM t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
a char(255) latin1_swedish_ci YES NULL select,insert,update,references
|
||||
SET DEBUG_SYNC= "now SIGNAL completed";
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
a char(255) latin1_swedish_ci YES NULL select,insert,update,references
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -3468,6 +3468,26 @@ connection default;
|
|||
set debug_sync= 'RESET';
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#52856 concurrent show columns or show full columns causes a crash!!!
|
||||
--echo #
|
||||
CREATE TABLE t1(a CHAR(255));
|
||||
|
||||
connect(con1, localhost, root);
|
||||
SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed";
|
||||
--send SHOW FULL COLUMNS FROM t1
|
||||
|
||||
connection default;
|
||||
SET DEBUG_SYNC= "now WAIT_FOR waiting";
|
||||
SHOW FULL COLUMNS FROM t1;
|
||||
SET DEBUG_SYNC= "now SIGNAL completed";
|
||||
|
||||
connection con1;
|
||||
--reap
|
||||
connection default;
|
||||
DROP TABLE t1;
|
||||
disconnect con1;
|
||||
|
||||
|
||||
# Check that all connections opened by test cases in this file are really
|
||||
# gone so execution of other tests won't be affected by their presence.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||
#include "sql_priv.h"
|
||||
#include "debug_sync.h"
|
||||
#include "unireg.h"
|
||||
#include "sql_acl.h" // fill_schema_*_privileges
|
||||
#include "sql_select.h" // For select_describe
|
||||
|
@ -3292,12 +3293,17 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
|
|||
goto end_share;
|
||||
}
|
||||
|
||||
if (!open_table_from_share(thd, share, table_name->str, 0,
|
||||
(EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
|
||||
thd->open_options, &tbl, FALSE))
|
||||
{
|
||||
tbl.s= share;
|
||||
table_list.table= &tbl;
|
||||
table_list.view= (LEX*) share->is_view;
|
||||
res= schema_table->process_table(thd, &table_list, table,
|
||||
res, db_name, table_name);
|
||||
free_root(&tbl.mem_root, MYF(0));
|
||||
my_free((char*) tbl.alias, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
|
||||
end_share:
|
||||
|
@ -4024,7 +4030,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
TABLE *show_table;
|
||||
TABLE_SHARE *show_table_share;
|
||||
Field **ptr, *field, *timestamp_field;
|
||||
int count;
|
||||
DBUG_ENTER("get_schema_column_record");
|
||||
|
@ -4047,37 +4052,11 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
}
|
||||
|
||||
show_table= tables->table;
|
||||
show_table_share= show_table->s;
|
||||
count= 0;
|
||||
|
||||
if (tables->view || tables->schema_table)
|
||||
{
|
||||
ptr= show_table->field;
|
||||
timestamp_field= show_table->timestamp_field;
|
||||
show_table->use_all_columns(); // Required for default
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr= show_table_share->field;
|
||||
timestamp_field= show_table_share->timestamp_field;
|
||||
/*
|
||||
read_set may be inited in case of
|
||||
temporary table
|
||||
*/
|
||||
if (!show_table->read_set)
|
||||
{
|
||||
/* to satisfy 'field->val_str' ASSERTs */
|
||||
uchar *bitmaps;
|
||||
uint bitmap_size= show_table_share->column_bitmap_size;
|
||||
if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
|
||||
DBUG_RETURN(0);
|
||||
bitmap_init(&show_table->def_read_set,
|
||||
(my_bitmap_map*) bitmaps, show_table_share->fields, FALSE);
|
||||
bitmap_set_all(&show_table->def_read_set);
|
||||
show_table->read_set= &show_table->def_read_set;
|
||||
}
|
||||
bitmap_set_all(show_table->read_set);
|
||||
}
|
||||
ptr= show_table->field;
|
||||
timestamp_field= show_table->timestamp_field;
|
||||
show_table->use_all_columns(); // Required for default
|
||||
restore_record(show_table, s->default_values);
|
||||
|
||||
for (; (field= *ptr) ; ptr++)
|
||||
{
|
||||
|
@ -4086,9 +4065,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
|
|||
String type(tmp,sizeof(tmp), system_charset_info);
|
||||
char *end;
|
||||
|
||||
/* to satisfy 'field->val_str' ASSERTs */
|
||||
field->table= show_table;
|
||||
show_table->in_use= thd;
|
||||
DEBUG_SYNC(thd, "get_schema_column");
|
||||
|
||||
if (wild && wild[0] &&
|
||||
wild_case_compare(system_charset_info, field->field_name,wild))
|
||||
|
|
Loading…
Reference in a new issue