mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed
- Fix the bug: SHOW EXPLAIN may hit a case where a join is partially optimized. - Change JOIN::optimized to use enum instead of numeric constants
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
drop table if exists t0, t1, t2;
|
drop table if exists t0, t1, t2;
|
||||||
|
drop view if exists v1;
|
||||||
create table t0 (a int);
|
create table t0 (a int);
|
||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
@ -337,4 +338,36 @@ Warnings:
|
|||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` join `test`.`t2` group by `test`.`t2`.`a`
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` join `test`.`t2` group by `test`.`t2`.`a`
|
||||||
set debug='';
|
set debug='';
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
#
|
||||||
|
# MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed in
|
||||||
|
# JOIN::print_explain on query with a JOIN, TEMPTABLE view,
|
||||||
|
#
|
||||||
|
CREATE TABLE t3 (a INT);
|
||||||
|
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t3;
|
||||||
|
INSERT INTO t3 VALUES (8);
|
||||||
|
CREATE TABLE t2 (b INT);
|
||||||
|
INSERT INTO t2 VALUES (4),(5),(6),(7),(8),(9);
|
||||||
|
explain SELECT * FROM v1, t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 6
|
||||||
|
2 DERIVED t3 system NULL NULL NULL NULL 1
|
||||||
|
set @show_explain_probe_select_id=2;
|
||||||
|
set debug='d,show_explain_probe_join_exec_end';
|
||||||
|
SELECT * FROM v1, t2;
|
||||||
|
show explain for $thr2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Not yet optimized
|
||||||
|
Warnings:
|
||||||
|
Note 1003 SELECT * FROM v1, t2
|
||||||
|
a b
|
||||||
|
8 4
|
||||||
|
8 5
|
||||||
|
8 6
|
||||||
|
8 7
|
||||||
|
8 8
|
||||||
|
8 9
|
||||||
|
set debug='';
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t2, t3;
|
||||||
drop table t0,t1;
|
drop table t0,t1;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t0, t1, t2;
|
drop table if exists t0, t1, t2;
|
||||||
|
drop view if exists v1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -346,6 +347,30 @@ set debug='';
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed in
|
||||||
|
--echo # JOIN::print_explain on query with a JOIN, TEMPTABLE view,
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t3 (a INT);
|
||||||
|
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t3;
|
||||||
|
INSERT INTO t3 VALUES (8);
|
||||||
|
CREATE TABLE t2 (b INT);
|
||||||
|
INSERT INTO t2 VALUES (4),(5),(6),(7),(8),(9);
|
||||||
|
explain SELECT * FROM v1, t2;
|
||||||
|
|
||||||
|
set @show_explain_probe_select_id=2;
|
||||||
|
set debug='d,show_explain_probe_join_exec_end';
|
||||||
|
send SELECT * FROM v1, t2;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
evalp show explain for $thr2;
|
||||||
|
connection con1;
|
||||||
|
reap;
|
||||||
|
set debug='';
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t2, t3;
|
||||||
|
|
||||||
## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a
|
## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a
|
||||||
## thread and served together.
|
## thread and served together.
|
||||||
|
|
||||||
|
@ -2910,7 +2910,7 @@ int subselect_single_select_engine::exec()
|
|||||||
SELECT_LEX *save_select= thd->lex->current_select;
|
SELECT_LEX *save_select= thd->lex->current_select;
|
||||||
thd->lex->current_select= select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
|
|
||||||
if (!join->optimized)
|
if (join->optimized != JOIN::OPTIMIZATION_DONE)
|
||||||
{
|
{
|
||||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||||
|
|
||||||
@ -4647,7 +4647,9 @@ int subselect_hash_sj_engine::exec()
|
|||||||
*/
|
*/
|
||||||
thd->lex->current_select= materialize_engine->select_lex;
|
thd->lex->current_select= materialize_engine->select_lex;
|
||||||
/* The subquery should be optimized, and materialized only once. */
|
/* The subquery should be optimized, and materialized only once. */
|
||||||
DBUG_ASSERT(materialize_join->optimized && !is_materialized);
|
DBUG_ASSERT(materialize_join->optimized == JOIN::OPTIMIZATION_DONE &&
|
||||||
|
!is_materialized);
|
||||||
|
|
||||||
materialize_join->exec();
|
materialize_join->exec();
|
||||||
if ((res= test(materialize_join->error || thd->is_fatal_error ||
|
if ((res= test(materialize_join->error || thd->is_fatal_error ||
|
||||||
thd->is_error())))
|
thd->is_error())))
|
||||||
|
@ -3750,7 +3750,7 @@ int st_select_lex::print_explain(select_result_sink *output,
|
|||||||
uint8 explain_flags)
|
uint8 explain_flags)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (join && join->optimized == 2)
|
if (join && join->optimized == JOIN::OPTIMIZATION_DONE)
|
||||||
{
|
{
|
||||||
res= join->print_explain(output, explain_flags, TRUE,
|
res= join->print_explain(output, explain_flags, TRUE,
|
||||||
join->need_tmp, // need_tmp_table
|
join->need_tmp, // need_tmp_table
|
||||||
|
@ -608,7 +608,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
DBUG_ENTER("JOIN::prepare");
|
DBUG_ENTER("JOIN::prepare");
|
||||||
|
|
||||||
// to prevent double initialization on EXPLAIN
|
// to prevent double initialization on EXPLAIN
|
||||||
if (optimized)
|
if (optimized != JOIN::NOT_OPTIMIZED)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
conds= conds_init;
|
conds= conds_init;
|
||||||
@ -936,7 +936,7 @@ err:
|
|||||||
int JOIN::optimize()
|
int JOIN::optimize()
|
||||||
{
|
{
|
||||||
int res= optimize_inner();
|
int res= optimize_inner();
|
||||||
optimized= 2;
|
optimized= JOIN::OPTIMIZATION_DONE;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -960,9 +960,9 @@ JOIN::optimize_inner()
|
|||||||
DBUG_ENTER("JOIN::optimize");
|
DBUG_ENTER("JOIN::optimize");
|
||||||
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
||||||
// to prevent double initialization on EXPLAIN
|
// to prevent double initialization on EXPLAIN
|
||||||
if (optimized)
|
if (optimized != JOIN::NOT_OPTIMIZED)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
optimized= 1;
|
optimized= JOIN::OPTIMIZATION_IN_PROGRESS;
|
||||||
thd_proc_info(thd, "optimizing");
|
thd_proc_info(thd, "optimizing");
|
||||||
|
|
||||||
set_allowed_join_cache_types();
|
set_allowed_join_cache_types();
|
||||||
@ -1731,7 +1731,7 @@ int JOIN::init_execution()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::init_execution");
|
DBUG_ENTER("JOIN::init_execution");
|
||||||
|
|
||||||
DBUG_ASSERT(optimized);
|
DBUG_ASSERT(optimized == JOIN::OPTIMIZATION_DONE);
|
||||||
DBUG_ASSERT(!(select_options & SELECT_DESCRIBE));
|
DBUG_ASSERT(!(select_options & SELECT_DESCRIBE));
|
||||||
initialized= true;
|
initialized= true;
|
||||||
|
|
||||||
@ -21187,7 +21187,7 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags,
|
|||||||
DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
|
DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
|
||||||
(ulong)join->select_lex, join->select_lex->type,
|
(ulong)join->select_lex, join->select_lex->type,
|
||||||
message ? message : "NULL"));
|
message ? message : "NULL"));
|
||||||
DBUG_ASSERT(this->optimized == 2);
|
|
||||||
/* Don't log this into the slow query log */
|
/* Don't log this into the slow query log */
|
||||||
|
|
||||||
if (!on_the_fly)
|
if (!on_the_fly)
|
||||||
@ -21204,6 +21204,10 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags,
|
|||||||
{
|
{
|
||||||
item_list.push_back(new Item_int((int32)
|
item_list.push_back(new Item_int((int32)
|
||||||
join->select_lex->select_number));
|
join->select_lex->select_number));
|
||||||
|
|
||||||
|
if (on_the_fly)
|
||||||
|
join->select_lex->set_explain_type(on_the_fly);
|
||||||
|
|
||||||
item_list.push_back(new Item_string(join->select_lex->type,
|
item_list.push_back(new Item_string(join->select_lex->type,
|
||||||
strlen(join->select_lex->type), cs));
|
strlen(join->select_lex->type), cs));
|
||||||
for (uint i=0 ; i < 7; i++)
|
for (uint i=0 ; i < 7; i++)
|
||||||
@ -21227,6 +21231,7 @@ int JOIN::print_explain(select_result_sink *result, uint8 explain_flags,
|
|||||||
else if (!join->select_lex->master_unit()->derived ||
|
else if (!join->select_lex->master_unit()->derived ||
|
||||||
join->select_lex->master_unit()->derived->is_materialized_derived())
|
join->select_lex->master_unit()->derived->is_materialized_derived())
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(optimized == JOIN::OPTIMIZATION_DONE);
|
||||||
table_map used_tables=0;
|
table_map used_tables=0;
|
||||||
//if (!join->select_lex->type)
|
//if (!join->select_lex->type)
|
||||||
if (on_the_fly)
|
if (on_the_fly)
|
||||||
|
@ -1178,7 +1178,11 @@ public:
|
|||||||
const char *zero_result_cause; ///< not 0 if exec must return zero result
|
const char *zero_result_cause; ///< not 0 if exec must return zero result
|
||||||
|
|
||||||
bool union_part; ///< this subselect is part of union
|
bool union_part; ///< this subselect is part of union
|
||||||
int optimized; ///< flag to avoid double optimization in EXPLAIN
|
|
||||||
|
enum join_optimization_state { NOT_OPTIMIZED=0,
|
||||||
|
OPTIMIZATION_IN_PROGRESS=1,
|
||||||
|
OPTIMIZATION_DONE=2};
|
||||||
|
join_optimization_state optimized; ///< flag to avoid double optimization in EXPLAIN
|
||||||
bool initialized; ///< flag to avoid double init_execution calls
|
bool initialized; ///< flag to avoid double init_execution calls
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1261,7 +1265,7 @@ public:
|
|||||||
ref_pointer_array= items0= items1= items2= items3= 0;
|
ref_pointer_array= items0= items1= items2= items3= 0;
|
||||||
ref_pointer_array_size= 0;
|
ref_pointer_array_size= 0;
|
||||||
zero_result_cause= 0;
|
zero_result_cause= 0;
|
||||||
optimized= 0;
|
optimized= JOIN::NOT_OPTIMIZED;
|
||||||
initialized= 0;
|
initialized= 0;
|
||||||
cond_equal= 0;
|
cond_equal= 0;
|
||||||
having_equal= 0;
|
having_equal= 0;
|
||||||
|
Reference in New Issue
Block a user