diff options
author | unknown <gkodinov/kgeorge@magare.gmz> | 2007-05-04 10:57:14 +0300 |
---|---|---|
committer | unknown <gkodinov/kgeorge@magare.gmz> | 2007-05-04 10:57:14 +0300 |
commit | ad06c4c08ee5bc9258dfce3455aabe39747d4875 (patch) | |
tree | 4ce958e6ff6f3d0cbac9a4870233fcf80ea461bf | |
parent | 8e8ece72eb0530bee9b200d92ba14a143cd1dec9 (diff) | |
parent | 0ad4e1b2a6f4919afbfc43a7cd71e828e3aeb74a (diff) | |
download | mariadb-git-ad06c4c08ee5bc9258dfce3455aabe39747d4875.tar.gz |
Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into magare.gmz:/home/kgeorge/mysql/autopush/B27807-5.0-opt
sql/sql_select.cc:
Auto merged
mysql-test/r/subselect.result:
merge to 5.0-opt
mysql-test/t/subselect.test:
merge to 5.0-opt
-rw-r--r-- | mysql-test/r/subselect.result | 7 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 8 | ||||
-rw-r--r-- | sql/item_subselect.cc | 15 | ||||
-rw-r--r-- | sql/sql_select.cc | 36 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
5 files changed, 59 insertions, 8 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 06ff23b32b7..2e82d948edb 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4034,4 +4034,11 @@ SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) ) FROM t1; ERROR HY000: Invalid use of group function DROP TABLE t1,t2; +CREATE TABLE t1 (a int, b int, KEY (a)); +INSERT INTO t1 VALUES (1,1),(2,1); +EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref a a 5 const 1 Using where; Using index +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 5cd2cd5fa7d..64de2ada93c 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2874,4 +2874,12 @@ FROM t1; DROP TABLE t1,t2; +# +# Bug #27807: Server crash when executing subquery with EXPLAIN +# +CREATE TABLE t1 (a int, b int, KEY (a)); +INSERT INTO t1 VALUES (1,1),(2,1); +EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b); +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index b3744d6eb96..a4d07e08473 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1774,6 +1774,21 @@ int subselect_single_select_engine::exec() thd->lex->current_select= save_select; DBUG_RETURN(join->error ? join->error : 1); } + if (!select_lex->uncacheable && thd->lex->describe && + !(join->select_options & SELECT_DESCRIBE) && + join->need_tmp && item->const_item()) + { + /* + Force join->join_tmp creation, because this subquery will be replaced + by a simple select from the materialization temp table by optimize() + called by EXPLAIN and we need to preserve the initial query structure + so we can display it. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + if (join->init_save_join_tab()) + DBUG_RETURN(1); + } if (item->engine_changed) { DBUG_RETURN(1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index acef5a5ff48..d5cb0d22509 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1426,14 +1426,13 @@ JOIN::optimize() } } - if (select_lex->uncacheable && !is_top_level_join()) - { - /* If this join belongs to an uncacheable subquery */ - if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) - DBUG_RETURN(-1); - error= 0; // Ensure that tmp_join.error= 0 - restore_tmp(); - } + /* + If this join belongs to an uncacheable subquery save + the original join + */ + if (select_lex->uncacheable && !is_top_level_join() && + init_save_join_tab()) + DBUG_RETURN(-1); } error= 0; @@ -1495,6 +1494,27 @@ JOIN::reinit() DBUG_RETURN(0); } +/** + @brief Save the original join layout + + @details Saves the original join layout so it can be reused in + re-execution and for EXPLAIN. + + @return Operation status + @retval 0 success. + @retval 1 error occurred. +*/ + +bool +JOIN::init_save_join_tab() +{ + if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) + return 1; + error= 0; // Ensure that tmp_join.error= 0 + restore_tmp(); + return 0; +} + bool JOIN::save_join_tab() diff --git a/sql/sql_select.h b/sql/sql_select.h index 9aa6fc1cfcd..5081366c10b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -434,6 +434,7 @@ public: void cleanup(bool full); void clear(); bool save_join_tab(); + bool init_save_join_tab(); bool send_row_on_empty_set() { return (do_send_rows && tmp_table_param.sum_func_count != 0 && |