From af660df0ef0772ed48062880f94d68c53a2da8d7 Mon Sep 17 00:00:00 2001 From: "evgen@sunlight.local" <> Date: Mon, 13 Mar 2006 21:11:15 +0300 Subject: [PATCH] Fixed bug#17366: Unchecked Item_int results in server crash When there is conjunction of conds, the substitute_for_best_equal_field() will call the eliminate_item_equal() function in loop to build final expression. But if eliminate_item_equal() finds that some cond will always evaluate to 0, then that cond will be substituted by Item_int with value == 0. In this case on the next iteration eliminate_item_equal() will get that Item_int and treat it as Item_cond. This is leads to memory corruption and server crash on cleanup phase. To the eliminate_item_equal() function was added DBUG_ASSERT for checking that all items treaten as Item_cond are really Item_cond. The substitute_for_best_equal_field() now checks that if eliminate_item_equal() returns Item_int and it's value is 0 then this value is returned as the result of whole conjunction. --- mysql-test/r/subselect.result | 7 +++++++ mysql-test/t/subselect.test | 7 +++++++ sql/sql_select.cc | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 33b12c05f98..52b6be063b8 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3157,3 +3157,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where 2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 9 Using filesort DROP TABLE t1; +create table t1( f1 int,f2 int); +insert into t1 values (1,1),(2,2); +select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1'; +t +crash1 +crash1 +drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9e09b215951..0ab8c2892e4 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2073,3 +2073,10 @@ SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); DROP TABLE t1; +# +# Bug#17366: Unchecked Item_int results in server crash +# +create table t1( f1 int,f2 int); +insert into t1 values (1,1),(2,2); +select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1'; +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 768ae7bf71f..24811b55b0b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7066,7 +7066,10 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, if (!cond) cond= new Item_cond_and(eq_list); else + { + DBUG_ASSERT(cond->type() == Item::COND_ITEM); ((Item_cond *) cond)->add_at_head(&eq_list); + } cond->quick_fix_field(); cond->update_used_tables(); @@ -7151,6 +7154,11 @@ static COND* substitute_for_best_equal_field(COND *cond, while ((item_equal= it++)) { cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal); + // This occurs when eliminate_item_equal() founds that cond is + // always false and substitues it with Item_int 0. + // Due to this, value of item_equal will be 0, so just return it. + if (cond->type() != Item::ITEM_COND) + break; } } }