mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +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
|
COUNT(*) > 0
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
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 optimizer_switch=@exit_optimizer_switch;
|
||||||
set join_cache_level=@exit_join_cache_level;
|
set join_cache_level=@exit_join_cache_level;
|
||||||
|
@ -1345,7 +1345,40 @@ SELECT COUNT(*) > 0
|
|||||||
|
|
||||||
DROP TABLE t1;
|
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
|
# The following command must be the last one the file
|
||||||
set optimizer_switch=@exit_optimizer_switch;
|
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;
|
select_union *result= (select_union*)unit->result;
|
||||||
if (table->s->db_type() == TMP_ENGINE_HTON)
|
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,
|
if (create_internal_tmp_table(table, result->tmp_table_param.keyinfo,
|
||||||
result->tmp_table_param.start_recinfo,
|
result->tmp_table_param.start_recinfo,
|
||||||
&result->tmp_table_param.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).
|
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).
|
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).
|
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)
|
if (!s->const_keys.is_clear_all() && // (1)
|
||||||
(!s->table->pos_in_table_list->embedding || // (2)
|
(!s->table->pos_in_table_list->embedding || // (2)
|
||||||
(s->table->pos_in_table_list->embedding && // (3)
|
(s->table->pos_in_table_list->embedding && // (3)
|
||||||
s->table->pos_in_table_list->embedding->sj_on_expr)) && // (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;
|
ha_rows records;
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
|
Reference in New Issue
Block a user