mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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())
|
||||
!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;
|
||||
|
Reference in New Issue
Block a user