Bug #20760261 mysqld crashed in materialized_cursor::
send_result_set_metadata Analysis -------- Cursor inside trigger accessing NEW/OLD row leads server exit. The reason for the bug was that implementation of function create_tmp_table() was not considering Item::TRIGGER_FIELD_ITEM as possible alternative for type of class being instantiated. This was resulting in a mismatch between a number of columns in result list and temp table definition. This mismatch leads to the failure of assertion DBUG_ASSERT(send_result_set_metadata.elements == item_list.elements) in the method Materialized_cursor::send_result_set_metadata in debug mode. Fix: --- Added code to consider Item::TRIGGER_FIELD_ITEM as valid type while creating fields.
This commit is contained in:
parent
c28626d0af
commit
f3dce250f4
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -3531,7 +3531,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
/* Add selected items to field list */
|
/* Add selected items to field list */
|
||||||
List_iterator_fast<Item> it(*items);
|
List_iterator_fast<Item> it(*items);
|
||||||
Item *item;
|
Item *item;
|
||||||
Field *tmp_field;
|
|
||||||
bool not_used;
|
bool not_used;
|
||||||
DBUG_ENTER("create_table_from_items");
|
DBUG_ENTER("create_table_from_items");
|
||||||
|
|
||||||
@ -3549,22 +3548,48 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
while ((item=it++))
|
while ((item=it++))
|
||||||
{
|
{
|
||||||
Create_field *cr_field;
|
Field *tmp_table_field;
|
||||||
Field *field, *def_field;
|
|
||||||
if (item->type() == Item::FUNC_ITEM)
|
if (item->type() == Item::FUNC_ITEM)
|
||||||
|
{
|
||||||
if (item->result_type() != STRING_RESULT)
|
if (item->result_type() != STRING_RESULT)
|
||||||
field= item->tmp_table_field(&tmp_table);
|
tmp_table_field= item->tmp_table_field(&tmp_table);
|
||||||
else
|
else
|
||||||
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
|
tmp_table_field= item->tmp_table_field_from_field_type(&tmp_table, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
field= create_tmp_field(thd, &tmp_table, item, item->type(),
|
{
|
||||||
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
|
Field *from_field, *default_field;
|
||||||
0);
|
tmp_table_field= create_tmp_field(thd, &tmp_table, item, item->type(),
|
||||||
if (!field ||
|
(Item ***) 0, &from_field, &default_field,
|
||||||
!(cr_field=new Create_field(field,(item->type() == Item::FIELD_ITEM ?
|
0, 0, 0, 0, 0);
|
||||||
((Item_field *)item)->field :
|
}
|
||||||
(Field*) 0))))
|
|
||||||
DBUG_RETURN(0);
|
if (!tmp_table_field)
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
|
Field *table_field;
|
||||||
|
|
||||||
|
switch (item->type())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We have to take into account both the real table's fields and
|
||||||
|
pseudo-fields used in trigger's body. These fields are used
|
||||||
|
to copy defaults values later inside constructor of
|
||||||
|
the class Create_field.
|
||||||
|
*/
|
||||||
|
case Item::FIELD_ITEM:
|
||||||
|
case Item::TRIGGER_FIELD_ITEM:
|
||||||
|
table_field= ((Item_field *) item)->field;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
table_field= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Create_field *cr_field= new Create_field(tmp_table_field, table_field);
|
||||||
|
|
||||||
|
if (!cr_field)
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
if (item->maybe_null)
|
if (item->maybe_null)
|
||||||
cr_field->flags &= ~NOT_NULL_FLAG;
|
cr_field->flags &= ~NOT_NULL_FLAG;
|
||||||
alter_info->create_list.push_back(cr_field);
|
alter_info->create_list.push_back(cr_field);
|
||||||
@ -3639,7 +3664,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
}
|
}
|
||||||
reenable_binlog(thd);
|
reenable_binlog(thd);
|
||||||
if (!table) // open failed
|
if (!table) // open failed
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("sleep_create_select_before_lock", my_sleep(6000000););
|
DBUG_EXECUTE_IF("sleep_create_select_before_lock", my_sleep(6000000););
|
||||||
|
@ -9820,6 +9820,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
}
|
}
|
||||||
case Item::FIELD_ITEM:
|
case Item::FIELD_ITEM:
|
||||||
case Item::DEFAULT_VALUE_ITEM:
|
case Item::DEFAULT_VALUE_ITEM:
|
||||||
|
case Item::TRIGGER_FIELD_ITEM:
|
||||||
{
|
{
|
||||||
Item_field *field= (Item_field*) item;
|
Item_field *field= (Item_field*) item;
|
||||||
bool orig_modify= modify_item;
|
bool orig_modify= modify_item;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user