diff options
author | igor@olga.mysql.com <> | 2007-08-16 17:22:50 -0700 |
---|---|---|
committer | igor@olga.mysql.com <> | 2007-08-16 17:22:50 -0700 |
commit | ff3f6e806b39dad00b275ce6823dfc5eddeb62d9 (patch) | |
tree | 8df9e6e80c1b71015982942c7f7276fc5b2c4160 | |
parent | 68048e426626a0feb510ca8a92c0c063ea1327be (diff) | |
parent | d790ec42e1de68d93e4c6c19580aa88f4d06dedb (diff) | |
download | mariadb-git-ff3f6e806b39dad00b275ce6823dfc5eddeb62d9.tar.gz |
Merge olga.mysql.com:/home/igor/dev-opt/mysql-5.0-opt-bug30396
into olga.mysql.com:/home/igor/dev-opt/mysql-5.1-opt-bug30396
-rw-r--r-- | libmysql/libmysql.c | 10 | ||||
-rw-r--r-- | mysql-test/r/select.result | 57 | ||||
-rw-r--r-- | mysql-test/t/select.test | 60 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 38 |
8 files changed, 142 insertions, 29 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index b2f59ba2a5a..95ac45f40c4 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4673,9 +4673,17 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) MYSQL *mysql= stmt->mysql; MYSQL_DATA *result= &stmt->result; MYSQL_ROWS *cur, **prev_ptr= &result->data; - NET *net = &mysql->net; + NET *net; + + if (!mysql) + { + set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); + return 1; + } + DBUG_ENTER("cli_read_binary_rows"); + net = &mysql->net; mysql= mysql->last_used_con; while ((pkt_len= cli_safe_read(mysql)) != packet_error) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 1ebed6d17d5..f1bfbec1555 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3990,4 +3990,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; ERROR HY000: Too high level of nesting for select 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 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index b513d17bfa0..3f17eb92d40 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3389,4 +3389,64 @@ eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0; 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 diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 47914c59b4c..7e5d30a92f9 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1570,7 +1570,6 @@ public: the current and level */ COND_EQUAL() { - max_members= 0; upper_levels= 0; } }; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 24c6979c0f6..737ad39745a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6738,6 +6738,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); select_lex->cond_count= 0; select_lex->between_count= 0; + select_lex->max_equal_elems= 0; for (table= tables; table; table= table->next_local) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c83c7a1c894..cb314362b5c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1517,6 +1517,7 @@ void st_select_lex::init_query() */ parent_lex->push_context(&context); cond_count= between_count= with_wild= 0; + max_equal_elems= 0; conds_processed_with_permanent_arena= 0; ref_pointer_array= 0; select_n_where_fields= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 11273bba314..3969d75f64d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -606,7 +606,8 @@ public: */ uint select_n_having_items; 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 and all inner subselects. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6f3851b66a1..a7d0bd30346 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3562,10 +3562,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, uint and_level,i,found_eq_constant; KEY_FIELD *key_fields, *end, *field; uint sz; - uint m= 1; - - if (cond_equal && cond_equal->max_members) - m= cond_equal->max_members; + uint m= max(select_lex->max_equal_elems,1); /* We use the same piece of memory to store both KEY_FIELD @@ -3585,7 +3582,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, it is considered as sargable only for its first argument. Multiple equality can add elements that are filled after 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))* (((thd->lex->current_select->cond_count+1)*2 + @@ -7388,8 +7386,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal, just an argument of a comparison predicate. The function also determines the maximum number of members in equality lists of each Item_cond_and object assigning it to - cond_equal->max_members of this object and updating accordingly - the upper levels COND_EQUAL structures. + thd->lex->current_select->max_equal_elems. NOTES Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of @@ -7434,7 +7431,6 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, COND_EQUAL *inherited) { Item_equal *item_equal; - uint members; COND_EQUAL cond_equal; cond_equal.upper_levels= inherited; @@ -7472,19 +7468,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, { item_equal->fix_length_and_dec(); item_equal->update_used_tables(); - members= item_equal->members(); - if (cond_equal.max_members < 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); + set_if_bigger(thd->lex->current_select->max_equal_elems, + item_equal->members()); } ((Item_cond_and*)cond)->cond_equal= cond_equal; @@ -7539,10 +7524,12 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, { item_equal->fix_length_and_dec(); item_equal->update_used_tables(); - return item_equal; } 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 { @@ -7558,9 +7545,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond, { item_equal->fix_length_and_dec(); item_equal->update_used_tables(); - members= item_equal->members(); - if (cond_equal.max_members < members) - cond_equal.max_members= members; + set_if_bigger(thd->lex->current_select->max_equal_elems, + item_equal->members()); } and_cond->cond_equal= cond_equal; args->concat((List<Item> *)&cond_equal.current_level); |