mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
[SHOW] EXPLAIN UPDATE/DELETE, code re-structuring
- Make query plan be re-saved after the first join execution (saving it after JOIN::cleanup is too late because EXPLAIN output is currently produced before that) - Handle QPF allocation/deallocation for edge cases, like unsuccessful BINLOG command. - Work around the problem with UNION's direct subselects not being visible. - Update test results ("Using temporary; Using filesort" are now always printed last in the Extra column) - This cset gets rid of memory leaks/crashes. Some result mismatches still remain.
This commit is contained in:
parent
99a8bfe68c
commit
8b7bbcf4dc
11 changed files with 68 additions and 18 deletions
|
@ -1031,7 +1031,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255;
|
|||
explain select t21.* from t21,t22 where t21.a = t22.a and
|
||||
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary
|
||||
1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Start temporary; Using temporary; Using filesort
|
||||
1 PRIMARY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
|
||||
1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; End temporary; Using join buffer (flat, BNL join)
|
||||
1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
|
||||
|
|
|
@ -1041,7 +1041,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255;
|
|||
explain select t21.* from t21,t22 where t21.a = t22.a and
|
||||
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary
|
||||
1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Start temporary; Using temporary; Using filesort
|
||||
1 PRIMARY t12 hash_ALL NULL #hash#$hj 4 test.t11.a 8 Using where; Using join buffer (flat, BNLH join)
|
||||
1 PRIMARY t22 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; End temporary; Using join buffer (incremental, BNLH join)
|
||||
1 PRIMARY t21 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (incremental, BNLH join)
|
||||
|
|
|
@ -3584,7 +3584,7 @@ View Create View character_set_client collation_connection
|
|||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` FORCE INDEX (PRIMARY) FORCE INDEX (`b`) order by `t1`.`a` latin1 latin1_swedish_ci
|
||||
EXPLAIN SELECT * FROM v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 15
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL 15
|
||||
CREATE VIEW v2 AS SELECT * FROM t1 USE KEY () ORDER BY a;
|
||||
SHOW CREATE VIEW v2;
|
||||
View Create View character_set_client collation_connection
|
||||
|
|
|
@ -9041,6 +9041,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
|
|||
call might reset the value of current_stmt_binlog_format, so
|
||||
we need to do any changes to that value after this function.
|
||||
*/
|
||||
delete_qpf_query(thd->lex);
|
||||
lex_start(thd);
|
||||
mysql_reset_thd_for_next_command(thd, 0);
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
QPF_query::QPF_query()
|
||||
{
|
||||
upd_del_plan= NULL;
|
||||
operations= 0;
|
||||
//memset(&unions, 0, sizeof(unions));
|
||||
//memset(&selects, 0, sizeof(selects));
|
||||
}
|
||||
|
@ -51,15 +52,18 @@ QPF_select *QPF_query::get_select(uint select_id)
|
|||
|
||||
void QPF_query::add_node(QPF_node *node)
|
||||
{
|
||||
operations++;
|
||||
if (node->get_type() == QPF_node::QPF_UNION)
|
||||
{
|
||||
QPF_union *u= (QPF_union*)node;
|
||||
uint select_id= u->get_select_id();
|
||||
DBUG_ASSERT(!get_union(select_id));
|
||||
|
||||
if (unions.elements() <= select_id)
|
||||
unions.resize(max(select_id+1, unions.elements()*2), NULL);
|
||||
|
||||
QPF_union *old_node;
|
||||
if ((old_node= get_union(select_id)))
|
||||
delete old_node;
|
||||
|
||||
unions.at(select_id)= u;
|
||||
}
|
||||
else
|
||||
|
@ -73,10 +77,14 @@ void QPF_query::add_node(QPF_node *node)
|
|||
else
|
||||
{
|
||||
uint select_id= sel->select_id;
|
||||
DBUG_ASSERT(!get_select(select_id));
|
||||
|
||||
QPF_select *old_node;
|
||||
//DBUG_ASSERT(!get_select(select_id));
|
||||
if (selects.elements() <= select_id)
|
||||
selects.resize(max(select_id+1, selects.elements()*2), NULL);
|
||||
|
||||
if ((old_node= get_select(select_id)))
|
||||
delete old_node;
|
||||
|
||||
selects.at(select_id)= sel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,6 +223,8 @@ private:
|
|||
Dynamic_array<QPF_select*> selects;
|
||||
//QPF_union *unions[MAX_TABLES];
|
||||
//QPF_select *selects[MAX_TABLES];
|
||||
|
||||
longlong operations;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2552,7 +2552,8 @@ void Query_tables_list::destroy_query_tables_list()
|
|||
*/
|
||||
|
||||
LEX::LEX()
|
||||
:result(0), option_type(OPT_DEFAULT), is_lex_started(0),
|
||||
: query_plan_footprint(NULL),
|
||||
result(0), option_type(OPT_DEFAULT), is_lex_started(0),
|
||||
limit_rows_examined_cnt(ULONGLONG_MAX)
|
||||
{
|
||||
|
||||
|
|
|
@ -4750,8 +4750,14 @@ finish:
|
|||
ha_maria::implicit_commit(thd, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
lex->unit.cleanup();
|
||||
//psergey-todo: print EXPLAIN here? After the above JOIN::cleanup calls?
|
||||
// how do we print EXPLAIN extended, then?
|
||||
if (lex->describe)
|
||||
{
|
||||
DBUG_ASSERT(lex->query_plan_footprint);
|
||||
///..
|
||||
}
|
||||
/* Free tables */
|
||||
thd_proc_info(thd, "closing tables");
|
||||
close_thread_tables(thd);
|
||||
|
|
|
@ -2347,6 +2347,36 @@ void JOIN::exec()
|
|||
|
||||
exec_inner();
|
||||
|
||||
if (!exec_qpf_saved)
|
||||
{
|
||||
if (select_lex->select_number != UINT_MAX &&
|
||||
select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
|
||||
have_query_plan != QEP_NOT_PRESENT_YET &&
|
||||
have_query_plan != QEP_DELETED && // this happens when there was no QEP ever, but then
|
||||
//cleanup() is called multiple times
|
||||
|
||||
thd->lex->query_plan_footprint //&& // for "SET" command in SPs.
|
||||
/*!thd->lex->query_plan_footprint->get_select(select_lex->select_number)*/)
|
||||
{
|
||||
const char *message= NULL;
|
||||
|
||||
if (!table_count || !tables_list || zero_result_cause)
|
||||
{
|
||||
/* It's a degenerate join */
|
||||
message= zero_result_cause ? zero_result_cause : "No tables used";
|
||||
}
|
||||
|
||||
save_qpf(thd->lex->query_plan_footprint,
|
||||
need_tmp, // need_tmp_table
|
||||
// !skip_sort_order && !no_order &&
|
||||
// (order || group_list), // bool need_order
|
||||
order != 0 && !skip_sort_order,
|
||||
select_distinct, // bool distinct
|
||||
message); // message
|
||||
}
|
||||
exec_qpf_saved= true;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("show_explain_probe_join_exec_end",
|
||||
if (dbug_user_var_equals_int(thd,
|
||||
"show_explain_probe_select_id",
|
||||
|
@ -11151,7 +11181,7 @@ void JOIN::cleanup(bool full)
|
|||
|
||||
if (full)
|
||||
{
|
||||
//
|
||||
/* Save it again */
|
||||
#if 0
|
||||
if (select_lex->select_number != UINT_MAX &&
|
||||
select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
|
||||
|
@ -11159,8 +11189,8 @@ void JOIN::cleanup(bool full)
|
|||
have_query_plan != QEP_DELETED && // this happens when there was no QEP ever, but then
|
||||
//cleanup() is called multiple times
|
||||
|
||||
thd->lex->query_plan_footprint && // for "SET" command in SPs.
|
||||
!thd->lex->query_plan_footprint->get_select(select_lex->select_number))
|
||||
thd->lex->query_plan_footprint //&& // for "SET" command in SPs.
|
||||
/*!thd->lex->query_plan_footprint->get_select(select_lex->select_number)*/)
|
||||
{
|
||||
const char *message= NULL;
|
||||
|
||||
|
@ -11178,8 +11208,6 @@ void JOIN::cleanup(bool full)
|
|||
message); // message
|
||||
}
|
||||
#endif
|
||||
//
|
||||
|
||||
have_query_plan= QEP_DELETED; //psergey: this is a problem!
|
||||
}
|
||||
|
||||
|
|
|
@ -1336,7 +1336,10 @@ public:
|
|||
pre_sort_join_tab= NULL;
|
||||
emb_sjm_nest= NULL;
|
||||
sjm_lookup_tables= 0;
|
||||
|
||||
exec_qpf_saved= false;
|
||||
}
|
||||
bool exec_qpf_saved;
|
||||
|
||||
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||
|
|
|
@ -617,6 +617,7 @@ bool st_select_lex_unit::exec()
|
|||
ulonglong add_rows=0;
|
||||
ha_rows examined_rows= 0;
|
||||
DBUG_ENTER("st_select_lex_unit::exec");
|
||||
bool was_executed= executed;
|
||||
|
||||
if (executed && !uncacheable && !describe)
|
||||
DBUG_RETURN(FALSE);
|
||||
|
@ -626,8 +627,8 @@ bool st_select_lex_unit::exec()
|
|||
|
||||
saved_error= optimize();
|
||||
|
||||
|
||||
save_union_qpf(thd->lex->query_plan_footprint);
|
||||
if (!was_executed && thd->lex->query_plan_footprint)
|
||||
save_union_qpf(thd->lex->query_plan_footprint);
|
||||
|
||||
if (uncacheable || !item || !item->assigned() || describe)
|
||||
{
|
||||
|
@ -776,8 +777,8 @@ bool st_select_lex_unit::exec()
|
|||
if (!fake_select_lex->ref_pointer_array)
|
||||
fake_select_lex->n_child_sum_items+= global_parameters->n_sum_items;
|
||||
|
||||
|
||||
save_union_qpf_part2(thd->lex->query_plan_footprint);
|
||||
if (!was_executed && thd->lex->query_plan_footprint)
|
||||
save_union_qpf_part2(thd->lex->query_plan_footprint);
|
||||
|
||||
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
|
||||
&result_table_list,
|
||||
|
|
Loading…
Add table
Reference in a new issue