summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2012-03-13 13:34:20 -0700
committerIgor Babaev <igor@askmonty.org>2012-03-13 13:34:20 -0700
commitc1f5e25c045538309e9da7aa2d9f0e4bd189977d (patch)
tree35a435eb0554db02c3a8fe5d0895d28a1d06e07b
parent223483aedf0c53bc66cb6833210228b46448003a (diff)
downloadmariadb-git-c1f5e25c045538309e9da7aa2d9f0e4bd189977d.tar.gz
Fixed LP bug #953649.
Do not call, directly or indirectly, SQL_SELECT::test_quick_select() for derived materialized tables / views when optimizing joins referring to these tables / views to get cost estimates of materialization. The current code does not create B-tree indexes for materialized derived tables / views. So now it's not possible to get any estimates for ranges conditions over the results of the materialization. The function mysql_derived_create() must take into account the fact that array of the KEY structures specifying the keys over a derived table / view may be moved after the optimization phase if the derived table / view is materialized.
-rw-r--r--mysql-test/r/derived_view.result38
-rw-r--r--mysql-test/t/derived_view.test35
-rw-r--r--sql/sql_derived.cc1
-rw-r--r--sql/sql_select.cc14
4 files changed, 81 insertions, 7 deletions
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 49e1422c3d4..28c4c362a9d 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1960,6 +1960,42 @@ ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA);
COUNT(*) > 0
1
DROP TABLE t1;
-set SESSION optimizer_switch= @save_optimizer_switch;
+SET SESSION optimizer_switch= @save_optimizer_switch;
+#
+# LP BUG#953649: crash when estimating the cost of a look-up
+# into a derived table to be materialized
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (132);
+CREATE TABLE t2 (b int, c varchar(256));
+INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3');
+CREATE VIEW v AS
+SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where
+2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort
+SELECT * FROM t1, v WHERE a = b;
+a b gc
+132 132 test1,text3
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ref key0 key0 5 const 0
+2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort
+SELECT * FROM t1, v WHERE a = b;
+a b gc
+132 132 test1,text3
+SET SESSION optimizer_switch= @save_optimizer_switch;
+DROP VIEW v;
+DROP TABLE t1,t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index 9660dd1e5f5..d1ed2ff5ba6 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1345,7 +1345,40 @@ SELECT COUNT(*) > 0
DROP TABLE t1;
-set SESSION optimizer_switch= @save_optimizer_switch;
+SET SESSION optimizer_switch= @save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#953649: crash when estimating the cost of a look-up
+--echo # into a derived table to be materialized
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (132);
+
+CREATE TABLE t2 (b int, c varchar(256));
+INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3');
+
+CREATE VIEW v AS
+ SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+
+SET SESSION optimizer_switch='derived_merge=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+SELECT * FROM t1, v WHERE a = b;
+
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+SELECT * FROM t1, v WHERE a = b;
+
+SET SESSION optimizer_switch= @save_optimizer_switch;
+
+DROP VIEW v;
+DROP TABLE t1,t2;
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 02a26254336..99d20090623 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -811,6 +811,7 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
select_union *result= (select_union*)unit->result;
if (table->s->db_type() == TMP_ENGINE_HTON)
{
+ result->tmp_table_param.keyinfo= table->s->key_info;
if (create_internal_tmp_table(table, result->tmp_table_param.keyinfo,
result->tmp_table_param.start_recinfo,
&result->tmp_table_param.recinfo,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 437833eb90c..31d87905da6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3513,12 +3513,16 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
Perform range analysis if there are keys it could use (1).
Don't do range analysis if we're on the inner side of an outer join (2).
Do range analysis if we're on the inner side of a semi-join (3).
+ Don't do range analysis for materialized subqueries (4).
+ Don't do range analysis for materialized derived tables (5)
*/
- if (!s->const_keys.is_clear_all() && // (1)
- (!s->table->pos_in_table_list->embedding || // (2)
- (s->table->pos_in_table_list->embedding && // (3)
- s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3)
- !s->table->is_filled_at_execution())
+ if (!s->const_keys.is_clear_all() && // (1)
+ (!s->table->pos_in_table_list->embedding || // (2)
+ (s->table->pos_in_table_list->embedding && // (3)
+ s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3)
+ !s->table->is_filled_at_execution() && // (4)
+ !(s->table->pos_in_table_list->derived && // (5)
+ s->table->pos_in_table_list->is_materialized_derived())) // (5)
{
ha_rows records;
SQL_SELECT *select;