diff options
author | unknown <igor@olga.mysql.com> | 2007-03-31 00:23:03 -0700 |
---|---|---|
committer | unknown <igor@olga.mysql.com> | 2007-03-31 00:23:03 -0700 |
commit | 7887a74491051d67fe0d780e19a62b5f055d07f9 (patch) | |
tree | 30965172fb391f49ca43b269726d625266437a20 | |
parent | 8aa507edb99a6f24553b9a8f773411327307aa0b (diff) | |
download | mariadb-git-7887a74491051d67fe0d780e19a62b5f055d07f9.tar.gz |
Fixed bug #27154: memory corruption when using row equalities in where
conditions.
When allocating memory for KEY_FIELD/SARGABLE_PARAM structures the
function update_ref_and_keys did not take into account the fact that
a single row equality could be replaced by several simple equalities.
Fixed by adjusting the counter cond_count accordingly for each subquery
when performing substitution of a row equality for simple equalities.
mysql-test/r/row.result:
Added a test case for bug #27154.
mysql-test/t/row.test:
Added a test case for bug #27154.
-rw-r--r-- | mysql-test/r/row.result | 13 | ||||
-rw-r--r-- | mysql-test/t/row.test | 17 | ||||
-rw-r--r-- | sql/sql_select.cc | 45 |
3 files changed, 60 insertions, 15 deletions
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index 5b5f8b7b954..faf9b11d7c9 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -306,3 +306,16 @@ a b a b c 1 1 1 2 1 1 2 1 2 1 DROP TABLE t1,t2; +CREATE TABLE t1( +a int, b int, c int, d int, e int, f int, g int, h int, +PRIMARY KEY (a,b,c,d,e,f,g) +); +INSERT INTO t1 VALUES (1,2,3,4,5,6,7,99); +SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7); +h +99 +SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7)); +SELECT @x; +@x +99 +DROP TABLE t1; diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index 63c611e6be6..1d5c7a543ea 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -139,3 +139,20 @@ EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1); SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1); DROP TABLE t1,t2; + +# +# Bug #27154: crash (memory corruption) when using row equalities +# + +CREATE TABLE t1( + a int, b int, c int, d int, e int, f int, g int, h int, + PRIMARY KEY (a,b,c,d,e,f,g) +); +INSERT INTO t1 VALUES (1,2,3,4,5,6,7,99); + +SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7); + +SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7)); +SELECT @x; + +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 08780efbedb..27e19657935 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6947,6 +6947,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, SYNOPSIS check_row_equality() + thd thread handle left_row left term of the row equality to be processed right_row right term of the row equality to be processed cond_equal multiple equalities that must hold together with the predicate @@ -6967,7 +6968,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, FALSE otherwise */ -static bool check_row_equality(Item *left_row, Item_row *right_row, +static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row, COND_EQUAL *cond_equal, List<Item>* eq_list) { uint n= left_row->cols(); @@ -6978,13 +6979,21 @@ static bool check_row_equality(Item *left_row, Item_row *right_row, Item *right_item= right_row->element_index(i); if (left_item->type() == Item::ROW_ITEM && right_item->type() == Item::ROW_ITEM) - is_converted= check_row_equality((Item_row *) left_item, - (Item_row *) right_item, - cond_equal, eq_list); - else + { + is_converted= check_row_equality(thd, + (Item_row *) left_item, + (Item_row *) right_item, + cond_equal, eq_list); + if (!is_converted) + thd->lex->current_select->cond_count++; + } + else + { is_converted= check_simple_equality(left_item, right_item, 0, cond_equal); - - if (!is_converted) + thd->lex->current_select->cond_count++; + } + + if (!is_converted) { Item_func_eq *eq_item; if (!(eq_item= new Item_func_eq(left_item, right_item))) @@ -7003,6 +7012,7 @@ static bool check_row_equality(Item *left_row, Item_row *right_row, SYNOPSIS check_equality() + thd thread handle item predicate to process cond_equal multiple equalities that must hold together with the predicate eq_list results of conversions of row equalities that are not simple @@ -7027,7 +7037,7 @@ static bool check_row_equality(Item *left_row, Item_row *right_row, or, if the procedure fails by a fatal error. */ -static bool check_equality(Item *item, COND_EQUAL *cond_equal, +static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal, List<Item> *eq_list) { if (item->type() == Item::FUNC_ITEM && @@ -7038,9 +7048,13 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal, if (left_item->type() == Item::ROW_ITEM && right_item->type() == Item::ROW_ITEM) - return check_row_equality((Item_row *) left_item, + { + thd->lex->current_select->cond_count--; + return check_row_equality(thd, + (Item_row *) left_item, (Item_row *) right_item, cond_equal, eq_list); + } else return check_simple_equality(left_item, right_item, item, cond_equal); } @@ -7053,6 +7067,7 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal, SYNOPSIS build_equal_items_for_cond() + thd thread handle cond condition(expression) where to make replacement inherited path to all inherited multiple equality items @@ -7115,7 +7130,7 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal, pointer to the transformed condition */ -static COND *build_equal_items_for_cond(COND *cond, +static COND *build_equal_items_for_cond(THD *thd, COND *cond, COND_EQUAL *inherited) { Item_equal *item_equal; @@ -7148,7 +7163,7 @@ static COND *build_equal_items_for_cond(COND *cond, structure here because it's restored before each re-execution of any prepared statement/stored procedure. */ - if (check_equality(item, &cond_equal, &eq_list)) + if (check_equality(thd, item, &cond_equal, &eq_list)) li.remove(); } @@ -7183,7 +7198,7 @@ static COND *build_equal_items_for_cond(COND *cond, while ((item= li++)) { Item *new_item; - if ((new_item = build_equal_items_for_cond(item, inherited))!= item) + if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item) { /* This replacement happens only for standalone equalities */ /* @@ -7213,7 +7228,7 @@ static COND *build_equal_items_for_cond(COND *cond, for WHERE a=b AND c=d AND (b=c OR d=5) b=c is replaced by =(a,b,c,d). */ - if (check_equality(cond, &cond_equal, &eq_list)) + if (check_equality(thd, cond, &cond_equal, &eq_list)) { int n= cond_equal.current_level.elements + eq_list.elements; if (n == 0) @@ -7276,7 +7291,7 @@ static COND *build_equal_items_for_cond(COND *cond, SYNOPSIS build_equal_items() - thd Thread handler + thd thread handle cond condition to build the multiple equalities for inherited path to all inherited multiple equality items join_list list of join tables to which the condition refers to @@ -7337,7 +7352,7 @@ static COND *build_equal_items(THD *thd, COND *cond, if (cond) { - cond= build_equal_items_for_cond(cond, inherited); + cond= build_equal_items_for_cond(thd, cond, inherited); cond->update_used_tables(); if (cond->type() == Item::COND_ITEM && ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) |