mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Code cleanup
This commit is contained in:
@ -102,3 +102,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 8 Using where
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 8 Using where
|
||||||
1 SIMPLE t1 ref a a 5 test.t0.a 4 Using index
|
1 SIMPLE t1 ref a a 5 test.t0.a 4 Using index
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
#
|
||||||
|
# Try DELETE ... RETURNING ...
|
||||||
|
#
|
||||||
|
create table t0 (a int);
|
||||||
|
insert into t0 values (1),(2),(3),(4);
|
||||||
|
explain delete from t0 where a=1 returning a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 4 Using where
|
||||||
|
explain delete from t0 returning a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 4
|
||||||
|
drop table t0;
|
||||||
|
@ -14,8 +14,6 @@ QPF_query::QPF_query()
|
|||||||
{
|
{
|
||||||
upd_del_plan= NULL;
|
upd_del_plan= NULL;
|
||||||
operations= 0;
|
operations= 0;
|
||||||
//memset(&unions, 0, sizeof(unions));
|
|
||||||
//memset(&selects, 0, sizeof(selects));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -105,18 +103,13 @@ int QPF_query::print_explain(select_result_sink *output,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Start with id=1
|
// Start printing from id=1
|
||||||
QPF_node *node= get_node(1);
|
QPF_node *node= get_node(1);
|
||||||
return node->print_explain(this, output, explain_flags);
|
return node->print_explain(this, output, explain_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QPF_union::push_table_name(List<Item> *item_list)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void push_str(List<Item> *item_list, const char *str)
|
static void push_str(List<Item> *item_list, const char *str)
|
||||||
{
|
{
|
||||||
item_list->push_back(new Item_string(str,
|
item_list->push_back(new Item_string(str,
|
||||||
@ -134,7 +127,7 @@ static void push_string(List<Item> *item_list, String *str)
|
|||||||
int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
|
int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
|
||||||
uint8 explain_flags)
|
uint8 explain_flags)
|
||||||
{
|
{
|
||||||
// print all children, in order
|
/* print all UNION children, in order */
|
||||||
for (int i= 0; i < (int) union_members.elements(); i++)
|
for (int i= 0; i < (int) union_members.elements(); i++)
|
||||||
{
|
{
|
||||||
QPF_select *sel= query->get_select(union_members.at(i));
|
QPF_select *sel= query->get_select(union_members.at(i));
|
||||||
@ -152,7 +145,6 @@ int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
|
|||||||
push_str(&item_list, fake_select_type);
|
push_str(&item_list, fake_select_type);
|
||||||
|
|
||||||
/* `table` column: something like "<union1,2>" */
|
/* `table` column: something like "<union1,2>" */
|
||||||
//
|
|
||||||
{
|
{
|
||||||
char table_name_buffer[SAFE_NAME_LEN];
|
char table_name_buffer[SAFE_NAME_LEN];
|
||||||
uint childno= 0;
|
uint childno= 0;
|
||||||
@ -180,8 +172,6 @@ int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
|
|||||||
const CHARSET_INFO *cs= system_charset_info;
|
const CHARSET_INFO *cs= system_charset_info;
|
||||||
item_list.push_back(new Item_string(table_name_buffer, len, cs));
|
item_list.push_back(new Item_string(table_name_buffer, len, cs));
|
||||||
}
|
}
|
||||||
//
|
|
||||||
push_table_name(&item_list);
|
|
||||||
|
|
||||||
/* `partitions` column */
|
/* `partitions` column */
|
||||||
if (explain_flags & DESCRIBE_PARTITIONS)
|
if (explain_flags & DESCRIBE_PARTITIONS)
|
||||||
@ -221,11 +211,19 @@ int QPF_union::print_explain(QPF_query *query, select_result_sink *output,
|
|||||||
//output->unit.offset_limit_cnt= 0;
|
//output->unit.offset_limit_cnt= 0;
|
||||||
if (output->send_data(item_list))
|
if (output->send_data(item_list))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Print all subquery children (UNION children have already been printed at
|
||||||
|
the start of this function)
|
||||||
|
*/
|
||||||
return print_explain_for_children(query, output, explain_flags);
|
return print_explain_for_children(query, output, explain_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Print EXPLAINs for all children nodes (i.e. for subqueries)
|
||||||
|
*/
|
||||||
|
|
||||||
int QPF_node::print_explain_for_children(QPF_query *query,
|
int QPF_node::print_explain_for_children(QPF_query *query,
|
||||||
select_result_sink *output,
|
select_result_sink *output,
|
||||||
uint8 explain_flags)
|
uint8 explain_flags)
|
||||||
@ -301,6 +299,12 @@ int QPF_select::print_explain(QPF_query *query, select_result_sink *output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QPF_table_access::push_extra(enum Extra_tag extra_tag)
|
||||||
|
{
|
||||||
|
extra_tags.append(extra_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_flags,
|
int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_flags,
|
||||||
uint select_id, const char *select_type,
|
uint select_id, const char *select_type,
|
||||||
bool using_temporary, bool using_filesort)
|
bool using_temporary, bool using_filesort)
|
||||||
@ -422,13 +426,17 @@ int QPF_table_access::print_explain(select_result_sink *output, uint8 explain_fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Elements in this array match members of enum Extra_tag, defined in opt_qpf.h.
|
||||||
|
*/
|
||||||
|
|
||||||
const char * extra_tag_text[]=
|
const char * extra_tag_text[]=
|
||||||
{
|
{
|
||||||
"ET_none",
|
"ET_none",
|
||||||
"Using index condition",
|
"Using index condition",
|
||||||
"Using index condition(BKA)",
|
"Using index condition(BKA)",
|
||||||
"Using ", //special
|
"Using ", // special handling
|
||||||
"Range checked for each record (index map: 0x", //special
|
"Range checked for each record (index map: 0x", // special handling
|
||||||
"Using where with pushed condition",
|
"Using where with pushed condition",
|
||||||
"Using where",
|
"Using where",
|
||||||
"Not exists",
|
"Not exists",
|
||||||
@ -443,17 +451,17 @@ const char * extra_tag_text[]=
|
|||||||
"Scanned 1 database",
|
"Scanned 1 database",
|
||||||
"Scanned all databases",
|
"Scanned all databases",
|
||||||
|
|
||||||
"Using index for group-by", // Special?
|
"Using index for group-by", // special handling
|
||||||
|
|
||||||
"USING MRR: DONT PRINT ME", // Special!
|
"USING MRR: DONT PRINT ME", // special handling
|
||||||
|
|
||||||
"Distinct",
|
"Distinct",
|
||||||
"LooseScan",
|
"LooseScan",
|
||||||
"Start temporary",
|
"Start temporary",
|
||||||
"End temporary",
|
"End temporary",
|
||||||
"FirstMatch", //TODO: also handle special variant!
|
"FirstMatch", // special handling
|
||||||
|
|
||||||
"Using join buffer", // Special!,
|
"Using join buffer", // special handling
|
||||||
|
|
||||||
"const row not found",
|
"const row not found",
|
||||||
"unique row not found",
|
"unique row not found",
|
||||||
|
@ -146,7 +146,6 @@ public:
|
|||||||
{
|
{
|
||||||
union_members.append(select_no);
|
union_members.append(select_no);
|
||||||
}
|
}
|
||||||
void push_table_name(List<Item> *item_list);
|
|
||||||
int print_explain(QPF_query *query, select_result_sink *output,
|
int print_explain(QPF_query *query, select_result_sink *output,
|
||||||
uint8 explain_flags);
|
uint8 explain_flags);
|
||||||
|
|
||||||
@ -231,6 +230,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some of the tags have matching text. See extra_tag_text for text names, and
|
||||||
|
QPF_table_access::append_tag_name() for code to convert from tag form to text
|
||||||
|
form.
|
||||||
|
*/
|
||||||
enum Extra_tag
|
enum Extra_tag
|
||||||
{
|
{
|
||||||
ET_none= 0, /* not-a-tag */
|
ET_none= 0, /* not-a-tag */
|
||||||
@ -347,7 +351,6 @@ public:
|
|||||||
StringBuffer<64> mrr_type;
|
StringBuffer<64> mrr_type;
|
||||||
|
|
||||||
// valid with ET_USING_JOIN_BUFFER
|
// valid with ET_USING_JOIN_BUFFER
|
||||||
//StringBuffer<64> join_buffer_type;
|
|
||||||
QPF_BKA_TYPE bka_type;
|
QPF_BKA_TYPE bka_type;
|
||||||
|
|
||||||
//TABLE *firstmatch_table;
|
//TABLE *firstmatch_table;
|
||||||
|
@ -11172,7 +11172,7 @@ void JOIN::cleanup(bool full)
|
|||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
/* Save it again */
|
/* Save it again */
|
||||||
#if 0
|
#if 0 psergey-todo: remove?
|
||||||
if (select_lex->select_number != UINT_MAX &&
|
if (select_lex->select_number != UINT_MAX &&
|
||||||
select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
|
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_NOT_PRESENT_YET &&
|
||||||
@ -22487,11 +22487,7 @@ void explain_append_mrr_info(QUICK_RANGE_SELECT *quick, String *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void QPF_table_access::push_extra(enum Extra_tag extra_tag)
|
|
||||||
{
|
|
||||||
extra_tags.append(extra_tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_possible_keys(String *str, TABLE *table, key_map possible_keys)
|
void append_possible_keys(String *str, TABLE *table, key_map possible_keys)
|
||||||
{
|
{
|
||||||
@ -22548,24 +22544,7 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
|
|||||||
}
|
}
|
||||||
else if (join->select_lex == join->unit->fake_select_lex)
|
else if (join->select_lex == join->unit->fake_select_lex)
|
||||||
{
|
{
|
||||||
#if 0
|
/* Do nothing, QPF_union will create and print fake_select_lex */
|
||||||
select_lex->set_explain_type(on_the_fly);
|
|
||||||
QPF_union *qp_union= new (output->mem_root) QPF_union;
|
|
||||||
qp_node= qp_union;
|
|
||||||
|
|
||||||
SELECT_LEX *child;
|
|
||||||
for (child= select_lex->master_unit()->first_select(); child;
|
|
||||||
child=child->next_select())
|
|
||||||
{
|
|
||||||
qp_union->add_select(child->select_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
qp_union->fake_select_type= select_lex->type;
|
|
||||||
qp_union->using_filesort=
|
|
||||||
test(select_lex->master_unit()->global_parameters->order_list.first);
|
|
||||||
|
|
||||||
output->add_node(qp_union);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
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())
|
||||||
@ -22713,7 +22692,7 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
|
|||||||
|
|
||||||
// tmp2 holds key_name
|
// tmp2 holds key_name
|
||||||
// tmp3 holds key_length
|
// tmp3 holds key_length
|
||||||
// tmp4 holds ref?
|
// tmp4 holds ref
|
||||||
if (tab_type == JT_NEXT)
|
if (tab_type == JT_NEXT)
|
||||||
{
|
{
|
||||||
key_info= table->key_info+tab->index;
|
key_info= table->key_info+tab->index;
|
||||||
@ -23074,16 +23053,16 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function servers as "shortcut point" for EXPLAIN queries.
|
This function serves as "shortcut point" for EXPLAIN queries.
|
||||||
|
|
||||||
|
The EXPLAIN statement executes just like its SELECT counterpart would
|
||||||
|
execute, except that JOIN::exec() will call select_describe() instead of
|
||||||
|
actually executing the query.
|
||||||
|
|
||||||
For UNIONs and JOINs, EXPLAIN statement executes just like its SELECT
|
Inside select_describe():
|
||||||
statement would execute, except that JOIN::exec() will call select_describe()
|
- Query plan is updated with latest QEP choices made at the start of
|
||||||
instead of actually executing the query.
|
JOIN::exec().
|
||||||
|
- the proces of "almost execution" is invoked for the children subqueries.
|
||||||
The purpose of select_describe() is:
|
|
||||||
- update the query plan with info about last-minute choices made at the start
|
|
||||||
of JOIN::exec
|
|
||||||
- Invoke "pseudo-execution" for the children subqueries.
|
|
||||||
|
|
||||||
Overall, select_describe() is a legacy of old EXPLAIN implementation and
|
Overall, select_describe() is a legacy of old EXPLAIN implementation and
|
||||||
should be removed.
|
should be removed.
|
||||||
@ -23096,9 +23075,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
select_result *result=join->result;
|
select_result *result=join->result;
|
||||||
DBUG_ENTER("select_describe");
|
DBUG_ENTER("select_describe");
|
||||||
|
|
||||||
// Update the QPF:
|
/* Update the QPF with latest values of using_temporary, using_filesort */
|
||||||
QPF_select *qp;
|
QPF_select *qp;
|
||||||
if ((qp= thd->lex->query_plan_footprint->get_select(join->select_lex->select_number)))
|
uint select_nr= join->select_lex->select_number;
|
||||||
|
if ((qp= thd->lex->query_plan_footprint->get_select(select_nr)))
|
||||||
{
|
{
|
||||||
qp->using_temporary= need_tmp_table;
|
qp->using_temporary= need_tmp_table;
|
||||||
qp->using_filesort= need_order;
|
qp->using_filesort= need_order;
|
||||||
|
@ -259,7 +259,6 @@ typedef struct st_join_table {
|
|||||||
|
|
||||||
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
||||||
enum Extra_tag info;
|
enum Extra_tag info;
|
||||||
//const char *info;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
|
Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
|
||||||
|
Reference in New Issue
Block a user