summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@magare.gmz>2007-05-04 10:57:14 +0300
committerunknown <gkodinov/kgeorge@magare.gmz>2007-05-04 10:57:14 +0300
commitad06c4c08ee5bc9258dfce3455aabe39747d4875 (patch)
tree4ce958e6ff6f3d0cbac9a4870233fcf80ea461bf
parent8e8ece72eb0530bee9b200d92ba14a143cd1dec9 (diff)
parent0ad4e1b2a6f4919afbfc43a7cd71e828e3aeb74a (diff)
downloadmariadb-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.result7
-rw-r--r--mysql-test/t/subselect.test8
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/sql_select.cc36
-rw-r--r--sql/sql_select.h1
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 &&