Commit 847114a2 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #702403 that caused a crash on the tree for mwl#128

with the test case added by this patch.
The bug cannot be reproduced with the same test case for the main
5.3 tree because the backported fix for bug 59696 masks the 
problem that causes the crash in the mentioned test case. It's not
clear weather this fix masks this problem in all possible cases. 

Anyway the patch for bug 698882 introduced some inconsistent data
structures that could contain indirect references to deleted object.
It happened when two Item_equal objects were merged and the Item_field
list of the second object was joined to such list of the first object.
This operation required adjustment of the backward pointers in 
Item fields from the joined list. However the adjustment was missing 
and this caused crashes in the tree for mwl#128.

Now the backward pointers are set only when Item_equal items are
completely built and are not changed anymore.
 
parent 85c8e61f
...@@ -3885,3 +3885,23 @@ DROP TABLE t1; ...@@ -3885,3 +3885,23 @@ DROP TABLE t1;
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# -- End of 5.1 tests. # -- End of 5.1 tests.
# ----------------------------------------------------------------- # -----------------------------------------------------------------
#
# Bug#702403: crash with multiple equalities and a view
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (10);
CREATE TABLE t2 (pk int PRIMARY KEY, b int, INDEX idx (b));
INSERT INTO t2 VALUES (1,2), (3,4);
CREATE TABLE t3 (pk int PRIMARY KEY, b int, INDEX idx (b));
INSERT INTO t3 VALUES (1,2), (3,4);
CREATE VIEW v1 AS SELECT * FROM t1;
EXPLAIN
SELECT * FROM v1, t2, t3
WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT * FROM v1, t2, t3
WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
a pk b pk b
DROP VIEW v1;
DROP TABLE t1, t2, t3;
...@@ -3928,3 +3928,27 @@ DROP TABLE t1; ...@@ -3928,3 +3928,27 @@ DROP TABLE t1;
--echo # ----------------------------------------------------------------- --echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests. --echo # -- End of 5.1 tests.
--echo # ----------------------------------------------------------------- --echo # -----------------------------------------------------------------
--echo #
--echo # Bug#702403: crash with multiple equalities and a view
--echo #
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (10);
CREATE TABLE t2 (pk int PRIMARY KEY, b int, INDEX idx (b));
INSERT INTO t2 VALUES (1,2), (3,4);
CREATE TABLE t3 (pk int PRIMARY KEY, b int, INDEX idx (b));
INSERT INTO t3 VALUES (1,2), (3,4);
CREATE VIEW v1 AS SELECT * FROM t1;
EXPLAIN
SELECT * FROM v1, t2, t3
WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
SELECT * FROM v1, t2, t3
WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
DROP VIEW v1;
DROP TABLE t1, t2, t3;
...@@ -5523,7 +5523,6 @@ Item_equal::Item_equal(Item_field *f1, Item_field *f2) ...@@ -5523,7 +5523,6 @@ Item_equal::Item_equal(Item_field *f1, Item_field *f2)
const_item_cache= 0; const_item_cache= 0;
fields.push_back(f1); fields.push_back(f1);
fields.push_back(f2); fields.push_back(f2);
f1->item_equal= f2->item_equal= this;
} }
Item_equal::Item_equal(Item *c, Item_field *f) Item_equal::Item_equal(Item *c, Item_field *f)
...@@ -5601,7 +5600,6 @@ void Item_equal::add(Item *c) ...@@ -5601,7 +5600,6 @@ void Item_equal::add(Item *c)
void Item_equal::add(Item_field *f) void Item_equal::add(Item_field *f)
{ {
fields.push_back(f); fields.push_back(f);
f->item_equal= this;
} }
uint Item_equal::members() uint Item_equal::members()
...@@ -5714,7 +5712,7 @@ void Item_equal::update_const() ...@@ -5714,7 +5712,7 @@ void Item_equal::update_const()
bool Item_equal::fix_fields(THD *thd, Item **ref) bool Item_equal::fix_fields(THD *thd, Item **ref)
{ {
List_iterator_fast<Item_field> li(fields); List_iterator_fast<Item_field> li(fields);
Item *item; Item_field *item;
not_null_tables_cache= used_tables_cache= 0; not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 0; const_item_cache= 0;
while ((item= li++)) while ((item= li++))
...@@ -5725,6 +5723,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) ...@@ -5725,6 +5723,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
not_null_tables_cache|= tmp_table_map; not_null_tables_cache|= tmp_table_map;
if (item->maybe_null) if (item->maybe_null)
maybe_null=1; maybe_null=1;
item->item_equal= this;
} }
fix_length_and_dec(); fix_length_and_dec();
fixed= 1; fixed= 1;
......
...@@ -9589,7 +9589,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, ...@@ -9589,7 +9589,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
List_iterator_fast<Item_equal> it(cond_equal.current_level); List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++)) while ((item_equal= it++))
{ {
item_equal->fix_length_and_dec(); item_equal->fix_fields(thd, NULL);
item_equal->update_used_tables(); item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems, set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->members()); item_equal->members());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment