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 @@ ...@@ -13,8 +13,8 @@
QPF_query::QPF_query() QPF_query::QPF_query()
{ {
upd_del_plan= NULL; upd_del_plan= NULL;
memset(&unions, 0, sizeof(unions)); //memset(&unions, 0, sizeof(unions));
memset(&selects, 0, sizeof(selects)); //memset(&selects, 0, sizeof(selects));
} }
...@@ -22,25 +22,30 @@ QPF_query::~QPF_query() ...@@ -22,25 +22,30 @@ QPF_query::~QPF_query()
{ {
delete upd_del_plan; delete upd_del_plan;
uint i; uint i;
for (i=0 ; i < MAX_TABLES; i++) for (i= 0 ; i < unions.elements(); i++)
delete unions[i]; delete unions.at(i);
for (i=0 ; i < MAX_TABLES; i++) for (i= 0 ; i < selects.elements(); i++)
delete selects[i]; delete selects.at(i);
} }
QPF_node *QPF_query::get_node(uint select_id) QPF_node *QPF_query::get_node(uint select_id)
{ {
if (unions[select_id]) QPF_union *u;
return unions[select_id]; if ((u= get_union(select_id)))
return u;
else 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) 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) ...@@ -49,8 +54,13 @@ void QPF_query::add_node(QPF_node *node)
if (node->get_type() == QPF_node::QPF_UNION) if (node->get_type() == QPF_node::QPF_UNION)
{ {
QPF_union *u= (QPF_union*)node; QPF_union *u= (QPF_union*)node;
DBUG_ASSERT(!unions[u->get_select_id()]); uint select_id= u->get_select_id();
unions[u->get_select_id()]= u; 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 else
{ {
...@@ -62,8 +72,12 @@ void QPF_query::add_node(QPF_node *node) ...@@ -62,8 +72,12 @@ void QPF_query::add_node(QPF_node *node)
} }
else else
{ {
DBUG_ASSERT(!selects[sel->select_id]); uint select_id= sel->select_id;
selects[sel->select_id] = sel; 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 @@ class QPF_query : public Sql_alloc ...@@ -209,6 +209,8 @@ class QPF_query : public Sql_alloc
/* This will return a select (even if there is a union with this id) */ /* This will return a select (even if there is a union with this id) */
QPF_select *get_select(uint select_id); QPF_select *get_select(uint select_id);
QPF_union *get_union(uint select_id);
/* QPF_delete inherits from QPF_update */ /* QPF_delete inherits from QPF_update */
QPF_update *upd_del_plan; QPF_update *upd_del_plan;
...@@ -217,8 +219,10 @@ class QPF_query : public Sql_alloc ...@@ -217,8 +219,10 @@ class QPF_query : public Sql_alloc
MEM_ROOT *mem_root; MEM_ROOT *mem_root;
private: private:
QPF_union *unions[MAX_TABLES]; Dynamic_array<QPF_union*> unions;
QPF_select *selects[MAX_TABLES]; Dynamic_array<QPF_select*> selects;
//QPF_union *unions[MAX_TABLES];
//QPF_select *selects[MAX_TABLES];
}; };
......
...@@ -106,6 +106,7 @@ template <class Elem> class Dynamic_array ...@@ -106,6 +106,7 @@ template <class Elem> class Dynamic_array
Elem& at(size_t idx) Elem& at(size_t idx)
{ {
DBUG_ASSERT(idx < array.elements);
return *(((Elem*)array.buffer) + idx); return *(((Elem*)array.buffer) + idx);
} }
...@@ -139,6 +140,23 @@ template <class Elem> class Dynamic_array ...@@ -139,6 +140,23 @@ template <class Elem> class Dynamic_array
array.elements= n; 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() ~Dynamic_array()
{ {
delete_dynamic(&array); delete_dynamic(&array);
......
...@@ -11112,6 +11112,9 @@ void JOIN::cleanup(bool full) ...@@ -11112,6 +11112,9 @@ void JOIN::cleanup(bool full)
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 &&
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 && // for "SET" command in SPs.
!thd->lex->query_plan_footprint->get_select(select_lex->select_number)) !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