From 3190b21f95e58886e1507384bf792ed68a9f8397 Mon Sep 17 00:00:00 2001 From: unknown <evgen@moonbone.local> Date: Thu, 24 Nov 2005 19:16:51 +0300 Subject: [PATCH] Fix bug #14482 Wrongly applied optimization in resolve_const_item() caused crash resolve_const_item() substitutes item which will evaluate to constant with equvalent constant item, basing on the item's result type. In this case subselect was resolved as constant, and resolve_const_item() was substituting it's result's Item_caches to Item_null. Later Item_cache's function was called for Item_null object, which caused server crash. resolve_const_item() now substitutes constants for items with result_type == ROW_RESULT only for Item_rows. sql/item.cc: Fix bug #14482 Wrongly applied optimization in resolve_const_item() caused crash resolve_const_item() now applies optimization for items with result_type == ROW_RESULT only to Item_rows. mysql-test/t/select.test: Test case for bug #14482 Wrongly applied optimization in resolve_const_item() caused crash mysql-test/r/select.result: Test case for bug #14482 Wrongly applied optimization in resolve_const_item() caused crash --- mysql-test/r/select.result | 8 ++++++++ mysql-test/t/select.test | 11 +++++++++++ sql/item.cc | 15 ++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 64c329ee10..b80ca2b195 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2706,3 +2706,11 @@ select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; count(f2) >0 1 drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 39c7cdfa8a..996d585485 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2237,4 +2237,15 @@ insert into t1 values (1,1); insert into t2 values (1,1),(1,2); select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; drop table t1,t2; + +# +# Bug #14482 Server crash when subselecting from the same table +# +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +drop table t1,t2; + # End of 4.1 tests diff --git a/sql/item.cc b/sql/item.cc index 642a0ccf1b..6ca2627dbf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2863,7 +2863,7 @@ Item_result item_cmp_type(Item_result a,Item_result b) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; - Item *new_item; + Item *new_item= NULL; if (item->basic_const_item()) return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), @@ -2892,8 +2892,17 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } - else if (res_type == ROW_RESULT) + else if (res_type == ROW_RESULT && item->type() == Item::ROW_ITEM && + comp_item->type() == Item::ROW_ITEM) { + /* + Substitute constants only in Item_rows. Don't affect other Items + with ROW_RESULT (eg Item_singlerow_subselect). + + For such Items more optimal is to detect if it is constant and replace + it with Item_row. This would optimize queries like this: + SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); + */ Item_row *item_row= (Item_row*) item; Item_row *comp_item_row= (Item_row*) comp_item; uint col; @@ -2910,7 +2919,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) while (col-- > 0) resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col)); } - else + else if (res_type == REAL_RESULT) { // It must REAL_RESULT double result=item->val(); uint length=item->max_length,decimals=item->decimals; -- 2.30.9