1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-5103: server crashed on singular Item_equal

Singular Item_equal support added.

The problem was that during constant table substitution Item_equal become containing only one constant which was not supported internally.
This commit is contained in:
unknown
2013-11-11 16:40:46 +02:00
parent 542ce5a068
commit c85db2c494
4 changed files with 117 additions and 2 deletions

View File

@@ -5564,6 +5564,12 @@ void Item_equal::add_const(Item *c, Item *f)
func->quick_fix_field();
cond_false= !func->val_int();
}
/*
TODO: also support the case where Item_equal becomes singular with
this->is_cond_true()=1. When I attempted to mark the item as constant,
the optimizer attempted to remove it, however it is still referenced from
COND_EQUAL and I got a crash.
*/
if (cond_false)
const_item_cache= 1;
}
@@ -5768,7 +5774,8 @@ void Item_equal::merge_into_list(List<Item_equal> *list,
void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
{
bubble_sort<Item>(&equal_items, compare, arg);
if (equal_items.elements > 1)
bubble_sort<Item>(&equal_items, compare, arg);
}
@@ -5868,6 +5875,12 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
void Item_equal::update_used_tables()
{
not_null_tables_cache= used_tables_cache= 0;
/*
TODO: also support the case where Item_equal becomes singular with
this->is_cond_true()=1. When I attempted to mark the item as constant,
the optimizer attempted to remove it, however it is still referenced from
COND_EQUAL and I got a crash.
*/
if ((const_item_cache= cond_false))
return;
Item_equal_fields_iterator it(*this);
@@ -5916,6 +5929,8 @@ longlong Item_equal::val_int()
{
if (cond_false)
return 0;
if (is_cond_true())
return 1;
Item *item= get_const();
Item_equal_fields_iterator it(*this);
if (!item)
@@ -5940,6 +5955,11 @@ longlong Item_equal::val_int()
void Item_equal::fix_length_and_dec()
{
Item *item= get_first(NO_PARTICULAR_TAB, NULL);
if (!item)
{
DBUG_ASSERT(is_cond_true()); // it should be the only constant
item= equal_items.head();
}
eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation);
}