Fixed bug mdev-4336.
When iterating over a list of conditions using List_iterator the function remove_eq_conds should skip all predicates that replace a condition from the list. Otherwise it can come to an infinite recursion.
This commit is contained in:
parent
b249680fd1
commit
920c479c6e
@ -1822,4 +1822,18 @@ b c d
|
|||||||
5 8 88
|
5 8 88
|
||||||
5 8 81
|
5 8 81
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-4336: LEFT JOIN with disjunctive
|
||||||
|
# <non-nullable datetime field> IS NULL in WHERE
|
||||||
|
# causes a hang and eventual crash
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int(11) NOT NULL,
|
||||||
|
modified datetime NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
SELECT a.* FROM t1 a LEFT JOIN t1 b ON a.id = b.id
|
||||||
|
WHERE a.modified > b.modified or b.modified IS NULL;
|
||||||
|
id modified
|
||||||
|
DROP TABLE t1;
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -1833,6 +1833,20 @@ b c d
|
|||||||
5 8 88
|
5 8 88
|
||||||
5 8 81
|
5 8 81
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-4336: LEFT JOIN with disjunctive
|
||||||
|
# <non-nullable datetime field> IS NULL in WHERE
|
||||||
|
# causes a hang and eventual crash
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int(11) NOT NULL,
|
||||||
|
modified datetime NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
SELECT a.* FROM t1 a LEFT JOIN t1 b ON a.id = b.id
|
||||||
|
WHERE a.modified > b.modified or b.modified IS NULL;
|
||||||
|
id modified
|
||||||
|
DROP TABLE t1;
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
|
@ -1359,4 +1359,21 @@ ORDER BY t1.b;
|
|||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug mdev-4336: LEFT JOIN with disjunctive
|
||||||
|
--echo # <non-nullable datetime field> IS NULL in WHERE
|
||||||
|
--echo # causes a hang and eventual crash
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int(11) NOT NULL,
|
||||||
|
modified datetime NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT a.* FROM t1 a LEFT JOIN t1 b ON a.id = b.id
|
||||||
|
WHERE a.modified > b.modified or b.modified IS NULL;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -13198,6 +13198,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
{
|
{
|
||||||
Item *list_item;
|
Item *list_item;
|
||||||
Item *new_list_item;
|
Item *new_list_item;
|
||||||
|
uint cnt= new_item_and_list->elements;
|
||||||
List_iterator<Item> it(*new_item_and_list);
|
List_iterator<Item> it(*new_item_and_list);
|
||||||
while ((list_item= it++))
|
while ((list_item= it++))
|
||||||
{
|
{
|
||||||
@ -13212,6 +13213,8 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
new_list_item->update_used_tables();
|
new_list_item->update_used_tables();
|
||||||
}
|
}
|
||||||
li.replace(*new_item_and_list);
|
li.replace(*new_item_and_list);
|
||||||
|
for (cnt--; cnt; cnt--)
|
||||||
|
item= li++;
|
||||||
}
|
}
|
||||||
cond_and_list->concat((List<Item>*) cond_equal_items);
|
cond_and_list->concat((List<Item>*) cond_equal_items);
|
||||||
}
|
}
|
||||||
@ -13232,7 +13235,13 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
if (new_item->type() == Item::COND_ITEM &&
|
if (new_item->type() == Item::COND_ITEM &&
|
||||||
((Item_cond*) new_item)->functype() ==
|
((Item_cond*) new_item)->functype() ==
|
||||||
((Item_cond*) cond)->functype())
|
((Item_cond*) cond)->functype())
|
||||||
li.replace(*((Item_cond*) new_item)->argument_list());
|
{
|
||||||
|
List<Item> *arg_list= ((Item_cond*) new_item)->argument_list();
|
||||||
|
uint cnt= arg_list->elements;
|
||||||
|
li.replace(*arg_list);
|
||||||
|
for ( cnt--; cnt; cnt--)
|
||||||
|
item= li++;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
li.replace(new_item);
|
li.replace(new_item);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user