Bug #27084 partitioning by list seems failing when using case
creation of the partitioned table could fail as we created Item-s for it's list function in thd->mem_root, and then do Item->fix_fields in the context of other table->mem_root (so that memory alloced there was alloced in this table->mem_root). As we freed the table->mem_root before we do thd->free_items, our Item-s had pointers to the freed memory, that caused the crash
This commit is contained in:
parent
2a54dcd997
commit
576f2f8474
@ -1219,4 +1219,14 @@ SELECT t2.id FROM t2 WHERE t2.id IN (SELECT id FROM t1 WHERE status = 'Verified'
|
||||
id
|
||||
22589
|
||||
drop table t1, t2;
|
||||
CREATE TABLE `t1` ( `a` varchar(1)) ENGINE=MyISAM
|
||||
PARTITION BY LIST (CASE a WHEN 'a' THEN 1
|
||||
WHEN 'b' THEN 2
|
||||
WHEN 'c' THEN 3
|
||||
END) (
|
||||
PARTITION a VALUES IN (1),
|
||||
PARTITION b VALUES IN (2),
|
||||
PARTITION c VALUES IN (3)
|
||||
);
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -1463,4 +1463,19 @@ SELECT t2.id FROM t2 WHERE t2.id IN (SELECT id FROM t1 WHERE status = 'Verified'
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Bug #27084 partitioning by list seems failing when using case
|
||||
#
|
||||
CREATE TABLE `t1` ( `a` varchar(1)) ENGINE=MyISAM
|
||||
PARTITION BY LIST (CASE a WHEN 'a' THEN 1
|
||||
WHEN 'b' THEN 2
|
||||
WHEN 'c' THEN 3
|
||||
END) (
|
||||
PARTITION a VALUES IN (1),
|
||||
PARTITION b VALUES IN (2),
|
||||
PARTITION c VALUES IN (3)
|
||||
);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -2099,6 +2099,21 @@ void Item_func_case::print(String *str)
|
||||
str->append(STRING_WITH_LEN("end)"));
|
||||
}
|
||||
|
||||
|
||||
void Item_func_case::cleanup()
|
||||
{
|
||||
uint i;
|
||||
DBUG_ENTER("Item_func_case::cleanup");
|
||||
Item_func::cleanup();
|
||||
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
||||
{
|
||||
delete cmp_items[i];
|
||||
cmp_items[i]= 0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Coalesce - return first not NULL argument.
|
||||
*/
|
||||
|
@ -1106,18 +1106,7 @@ public:
|
||||
Item *find_item(String *str);
|
||||
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
||||
bool check_partition_func_processor(byte *bool_arg) { return FALSE;}
|
||||
void cleanup()
|
||||
{
|
||||
uint i;
|
||||
DBUG_ENTER("Item_func_case::cleanup");
|
||||
Item_func::cleanup();
|
||||
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
||||
{
|
||||
delete cmp_items[i];
|
||||
cmp_items[i]= 0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -3684,6 +3684,8 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index,
|
||||
table Table object of partitioned table
|
||||
create_table_ind Is it called from CREATE TABLE
|
||||
default_db_type What is the default engine of the table
|
||||
work_part_info_used Flag is raised if we don't create new
|
||||
part_info, but used thd->work_part_info
|
||||
|
||||
RETURN VALUE
|
||||
TRUE Error
|
||||
@ -3704,7 +3706,8 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
uint part_info_len,
|
||||
uchar *part_state, uint part_state_len,
|
||||
TABLE* table, bool is_create_table_ind,
|
||||
handlerton *default_db_type)
|
||||
handlerton *default_db_type,
|
||||
bool *work_part_info_used)
|
||||
{
|
||||
bool result= TRUE;
|
||||
partition_info *part_info;
|
||||
@ -3716,6 +3719,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
thd->lex= &lex;
|
||||
thd->variables.character_set_client= system_charset_info;
|
||||
lex_start(thd, part_buf, part_info_len);
|
||||
*work_part_info_used= false;
|
||||
/*
|
||||
We need to use the current SELECT_LEX since I need to keep the
|
||||
Name_resolution_context object which is referenced from the
|
||||
@ -3805,6 +3809,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
thd->free_items();
|
||||
part_info= thd->work_part_info;
|
||||
table->s->version= 0UL;
|
||||
*work_part_info_used= true;
|
||||
}
|
||||
}
|
||||
table->part_info= part_info;
|
||||
|
@ -81,7 +81,8 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
uint part_info_len,
|
||||
uchar *part_state, uint part_state_len,
|
||||
TABLE *table, bool is_create_table_ind,
|
||||
handlerton *default_db_type);
|
||||
handlerton *default_db_type,
|
||||
bool *work_part_info_used);
|
||||
void make_used_partitions_str(partition_info *part_info, String *parts_str);
|
||||
uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
|
||||
bool left_endpoint,
|
||||
|
13
sql/table.cc
13
sql/table.cc
@ -1525,21 +1525,30 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||
thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
|
||||
thd->stmt_arena= &part_func_arena;
|
||||
bool tmp;
|
||||
bool work_part_info_used;
|
||||
|
||||
tmp= mysql_unpack_partition(thd, share->partition_info,
|
||||
share->partition_info_len,
|
||||
(uchar*)share->part_state,
|
||||
share->part_state_len,
|
||||
outparam, is_create_table,
|
||||
share->default_part_db_type);
|
||||
share->default_part_db_type,
|
||||
&work_part_info_used);
|
||||
outparam->part_info->is_auto_partitioned= share->auto_partitioned;
|
||||
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
|
||||
if (!tmp)
|
||||
/* we should perform the fix_partition_func in either local or
|
||||
caller's arena depending on work_part_info_used value
|
||||
*/
|
||||
if (!tmp && !work_part_info_used)
|
||||
tmp= fix_partition_func(thd, outparam, is_create_table);
|
||||
thd->stmt_arena= backup_stmt_arena_ptr;
|
||||
thd->restore_active_arena(&part_func_arena, &backup_arena);
|
||||
if (!tmp)
|
||||
{
|
||||
if (work_part_info_used)
|
||||
tmp= fix_partition_func(thd, outparam, is_create_table);
|
||||
outparam->part_info->item_free_list= part_func_arena.free_list;
|
||||
}
|
||||
if (tmp)
|
||||
{
|
||||
if (is_create_table)
|
||||
|
Loading…
x
Reference in New Issue
Block a user