Commit cebdf3de authored by Sergey Petrunya's avatar Sergey Petrunya

[SHOW] EXPLAIN UPDATE/DELETE, code re-structuring

- Handle another specific case where there the JOIN 
  never had a query plan, but had multiple join->cleanup(full=true) calls
- The idea that there can only be MAX_TABLES subuqeries/unions was 
  wrong. Switch QPF_query to using a Dynamic_array.
  = make Dynamic_array template support size growth. its underlying
    DYNAMIC_ARRAY supports it. (this part will need more polishing)
parent af5e128e
......@@ -13,8 +13,8 @@
QPF_query::QPF_query()
{
upd_del_plan= NULL;
memset(&unions, 0, sizeof(unions));
memset(&selects, 0, sizeof(selects));
//memset(&unions, 0, sizeof(unions));
//memset(&selects, 0, sizeof(selects));
}
......@@ -22,25 +22,30 @@ QPF_query::~QPF_query()
{
delete upd_del_plan;
uint i;
for (i=0 ; i < MAX_TABLES; i++)
delete unions[i];
for (i=0 ; i < MAX_TABLES; i++)
delete selects[i];
for (i= 0 ; i < unions.elements(); i++)
delete unions.at(i);
for (i= 0 ; i < selects.elements(); i++)
delete selects.at(i);
}
QPF_node *QPF_query::get_node(uint select_id)
{
if (unions[select_id])
return unions[select_id];
QPF_union *u;
if ((u= get_union(select_id)))
return u;
else
return selects[select_id];
return get_select(select_id);
}
QPF_union *QPF_query::get_union(uint select_id)
{
return (unions.elements() > select_id) ? unions.at(select_id) : NULL;
}
QPF_select *QPF_query::get_select(uint select_id)
{
return selects[select_id];
return (selects.elements() > select_id) ? selects.at(select_id) : NULL;
}
......@@ -49,8 +54,13 @@ void QPF_query::add_node(QPF_node *node)
if (node->get_type() == QPF_node::QPF_UNION)
{
QPF_union *u= (QPF_union*)node;
DBUG_ASSERT(!unions[u->get_select_id()]);
unions[u->get_select_id()]= u;
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);
unions.at(select_id)= u;
}
else
{
......@@ -62,8 +72,12 @@ void QPF_query::add_node(QPF_node *node)
}
else
{
DBUG_ASSERT(!selects[sel->select_id]);
selects[sel->select_id] = sel;
uint select_id= sel->select_id;
DBUG_ASSERT(!get_select(select_id));
if (selects.elements() <= select_id)
selects.resize(max(select_id+1, selects.elements()*2), NULL);
selects.at(select_id)= sel;
}
}
}
......
......@@ -209,6 +209,8 @@ public:
/* This will return a select (even if there is a union with this id) */
QPF_select *get_select(uint select_id);
QPF_union *get_union(uint select_id);
/* QPF_delete inherits from QPF_update */
QPF_update *upd_del_plan;
......@@ -217,8 +219,10 @@ public:
MEM_ROOT *mem_root;
private:
QPF_union *unions[MAX_TABLES];
QPF_select *selects[MAX_TABLES];
Dynamic_array<QPF_union*> unions;
Dynamic_array<QPF_select*> selects;
//QPF_union *unions[MAX_TABLES];
//QPF_select *selects[MAX_TABLES];
};
......
......@@ -106,6 +106,7 @@ public:
Elem& at(size_t idx)
{
DBUG_ASSERT(idx < array.elements);
return *(((Elem*)array.buffer) + idx);
}
......@@ -139,6 +140,23 @@ public:
array.elements= n;
}
bool resize(size_t new_size, Elem default_val)
{
size_t old_size= elements();
if (allocate_dynamic(&array, new_size))
return true;
if (new_size > old_size)
{
set_dynamic(&array, (uchar*)&default_val, new_size - 1);
/*for (size_t i= old_size; i != new_size; i++)
{
at(i)= default_val;
}*/
}
return false;
}
~Dynamic_array()
{
delete_dynamic(&array);
......
......@@ -11112,6 +11112,9 @@ void JOIN::cleanup(bool full)
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))
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment