Commit 3d44204e authored by igor@olga.mysql.com's avatar igor@olga.mysql.com

Merge olga.mysql.com:/home/igor/mysql-5.0-opt

into  olga.mysql.com:/home/igor/dev-opt/mysql-5.0-opt-bug30396
parents 4fdadd62 d790ec42
...@@ -4005,4 +4005,61 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -4005,4 +4005,61 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0; EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0;
ERROR HY000: Too high level of nesting for select ERROR HY000: Too high level of nesting for select
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
c1 int(11) NOT NULL AUTO_INCREMENT,
c2 varchar(1000) DEFAULT NULL,
c3 bigint(20) DEFAULT NULL,
c4 bigint(20) DEFAULT NULL,
PRIMARY KEY (c1)
);
EXPLAIN EXTENDED
SELECT join_2.c1
FROM
t1 AS join_0,
t1 AS join_1,
t1 AS join_2,
t1 AS join_3,
t1 AS join_4,
t1 AS join_5,
t1 AS join_6,
t1 AS join_7
WHERE
join_0.c1=join_1.c1 AND
join_1.c1=join_2.c1 AND
join_2.c1=join_3.c1 AND
join_3.c1=join_4.c1 AND
join_4.c1=join_5.c1 AND
join_5.c1=join_6.c1 AND
join_6.c1=join_7.c1
OR
join_0.c2 < '?' AND
join_1.c2 < '?' AND
join_2.c2 > '?' AND
join_2.c2 < '!' AND
join_3.c2 > '?' AND
join_4.c2 = '?' AND
join_5.c2 <> '?' AND
join_6.c2 <> '?' AND
join_7.c2 >= '?' AND
join_0.c1=join_1.c1 AND
join_1.c1=join_2.c1 AND
join_2.c1=join_3.c1 AND
join_3.c1=join_4.c1 AND
join_4.c1=join_5.c1 AND
join_5.c1=join_6.c1 AND
join_6.c1=join_7.c1
GROUP BY
join_3.c1,
join_2.c1,
join_7.c1,
join_1.c1,
join_0.c1;
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
Warnings:
Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
SHOW WARNINGS;
Level Code Message
Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -3400,4 +3400,64 @@ eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0; ...@@ -3400,4 +3400,64 @@ eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #30396: crash for a join with equalities and sargable predicates
# in disjunctive parts of the WHERE condition
#
CREATE TABLE t1 (
c1 int(11) NOT NULL AUTO_INCREMENT,
c2 varchar(1000) DEFAULT NULL,
c3 bigint(20) DEFAULT NULL,
c4 bigint(20) DEFAULT NULL,
PRIMARY KEY (c1)
);
EXPLAIN EXTENDED
SELECT join_2.c1
FROM
t1 AS join_0,
t1 AS join_1,
t1 AS join_2,
t1 AS join_3,
t1 AS join_4,
t1 AS join_5,
t1 AS join_6,
t1 AS join_7
WHERE
join_0.c1=join_1.c1 AND
join_1.c1=join_2.c1 AND
join_2.c1=join_3.c1 AND
join_3.c1=join_4.c1 AND
join_4.c1=join_5.c1 AND
join_5.c1=join_6.c1 AND
join_6.c1=join_7.c1
OR
join_0.c2 < '?' AND
join_1.c2 < '?' AND
join_2.c2 > '?' AND
join_2.c2 < '!' AND
join_3.c2 > '?' AND
join_4.c2 = '?' AND
join_5.c2 <> '?' AND
join_6.c2 <> '?' AND
join_7.c2 >= '?' AND
join_0.c1=join_1.c1 AND
join_1.c1=join_2.c1 AND
join_2.c1=join_3.c1 AND
join_3.c1=join_4.c1 AND
join_4.c1=join_5.c1 AND
join_5.c1=join_6.c1 AND
join_6.c1=join_7.c1
GROUP BY
join_3.c1,
join_2.c1,
join_7.c1,
join_1.c1,
join_0.c1;
SHOW WARNINGS;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -1506,7 +1506,6 @@ public: ...@@ -1506,7 +1506,6 @@ public:
the current and level */ the current and level */
COND_EQUAL() COND_EQUAL()
{ {
max_members= 0;
upper_levels= 0; upper_levels= 0;
} }
}; };
......
...@@ -5611,6 +5611,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, ...@@ -5611,6 +5611,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
thd->set_query_id=1; thd->set_query_id=1;
select_lex->cond_count= 0; select_lex->cond_count= 0;
select_lex->between_count= 0; select_lex->between_count= 0;
select_lex->max_equal_elems= 0;
for (table= tables; table; table= table->next_local) for (table= tables; table; table= table->next_local)
{ {
......
...@@ -1183,6 +1183,7 @@ void st_select_lex::init_query() ...@@ -1183,6 +1183,7 @@ void st_select_lex::init_query()
*/ */
parent_lex->push_context(&context); parent_lex->push_context(&context);
cond_count= between_count= with_wild= 0; cond_count= between_count= with_wild= 0;
max_equal_elems= 0;
conds_processed_with_permanent_arena= 0; conds_processed_with_permanent_arena= 0;
ref_pointer_array= 0; ref_pointer_array= 0;
select_n_where_fields= 0; select_n_where_fields= 0;
......
...@@ -534,6 +534,7 @@ public: ...@@ -534,6 +534,7 @@ public:
uint select_n_having_items; uint select_n_having_items;
uint cond_count; /* number of arguments of and/or/xor in where/having/on */ uint cond_count; /* number of arguments of and/or/xor in where/having/on */
uint between_count; /* number of between predicates in where/having/on */ uint between_count; /* number of between predicates in where/having/on */
uint max_equal_elems; /* maximal number of elements in multiple equalities */
/* /*
Number of fields used in select list or where clause of current select Number of fields used in select list or where clause of current select
and all inner subselects. and all inner subselects.
......
...@@ -3524,10 +3524,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, ...@@ -3524,10 +3524,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
uint and_level,i,found_eq_constant; uint and_level,i,found_eq_constant;
KEY_FIELD *key_fields, *end, *field; KEY_FIELD *key_fields, *end, *field;
uint sz; uint sz;
uint m= 1; uint m= max(select_lex->max_equal_elems,1);
if (cond_equal && cond_equal->max_members)
m= cond_equal->max_members;
/* /*
We use the same piece of memory to store both KEY_FIELD We use the same piece of memory to store both KEY_FIELD
...@@ -3547,7 +3544,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, ...@@ -3547,7 +3544,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
it is considered as sargable only for its first argument. it is considered as sargable only for its first argument.
Multiple equality can add elements that are filled after Multiple equality can add elements that are filled after
substitution of field arguments by equal fields. There substitution of field arguments by equal fields. There
can be not more than cond_equal->max_members such substitutions. can be not more than select_lex->max_equal_elems such
substitutions.
*/ */
sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))* sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
(((thd->lex->current_select->cond_count+1)*2 + (((thd->lex->current_select->cond_count+1)*2 +
...@@ -7189,8 +7187,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal, ...@@ -7189,8 +7187,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
just an argument of a comparison predicate. just an argument of a comparison predicate.
The function also determines the maximum number of members in The function also determines the maximum number of members in
equality lists of each Item_cond_and object assigning it to equality lists of each Item_cond_and object assigning it to
cond_equal->max_members of this object and updating accordingly thd->lex->current_select->max_equal_elems.
the upper levels COND_EQUAL structures.
NOTES NOTES
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
...@@ -7235,7 +7232,6 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, ...@@ -7235,7 +7232,6 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
COND_EQUAL *inherited) COND_EQUAL *inherited)
{ {
Item_equal *item_equal; Item_equal *item_equal;
uint members;
COND_EQUAL cond_equal; COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited; cond_equal.upper_levels= inherited;
...@@ -7273,19 +7269,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, ...@@ -7273,19 +7269,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{ {
item_equal->fix_length_and_dec(); item_equal->fix_length_and_dec();
item_equal->update_used_tables(); item_equal->update_used_tables();
members= item_equal->members(); set_if_bigger(thd->lex->current_select->max_equal_elems,
if (cond_equal.max_members < members) item_equal->members());
cond_equal.max_members= members;
}
members= cond_equal.max_members;
if (inherited && inherited->max_members < members)
{
do
{
inherited->max_members= members;
inherited= inherited->upper_levels;
}
while (inherited);
} }
((Item_cond_and*)cond)->cond_equal= cond_equal; ((Item_cond_and*)cond)->cond_equal= cond_equal;
...@@ -7340,10 +7325,12 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, ...@@ -7340,10 +7325,12 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{ {
item_equal->fix_length_and_dec(); item_equal->fix_length_and_dec();
item_equal->update_used_tables(); item_equal->update_used_tables();
return item_equal;
} }
else else
return eq_list.pop(); item_equal= (Item_equal *) eq_list.pop();
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->members());
return item_equal;
} }
else else
{ {
...@@ -7359,9 +7346,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, ...@@ -7359,9 +7346,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{ {
item_equal->fix_length_and_dec(); item_equal->fix_length_and_dec();
item_equal->update_used_tables(); item_equal->update_used_tables();
members= item_equal->members(); set_if_bigger(thd->lex->current_select->max_equal_elems,
if (cond_equal.max_members < members) item_equal->members());
cond_equal.max_members= members;
} }
and_cond->cond_equal= cond_equal; and_cond->cond_equal= cond_equal;
args->concat((List<Item> *)&cond_equal.current_level); args->concat((List<Item> *)&cond_equal.current_level);
......
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