diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-06-21 22:26:03 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-06-21 22:26:03 +0400 |
commit | cebdf3de2ef2604f3459762fc05a50dd54c1c9f2 (patch) | |
tree | e23a75abd0b2376b437b595a61510e3d9eb0c6d7 | |
parent | af5e128e50cac8881f7bfca44cc473600abdce86 (diff) | |
download | mariadb-git-cebdf3de2ef2604f3459762fc05a50dd54c1c9f2.tar.gz |
[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)
-rw-r--r-- | sql/opt_qpf.cc | 42 | ||||
-rw-r--r-- | sql/opt_qpf.h | 8 | ||||
-rw-r--r-- | sql/sql_array.h | 18 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 |
4 files changed, 55 insertions, 16 deletions
diff --git a/sql/opt_qpf.cc b/sql/opt_qpf.cc index d5a228e8f41..204a7e00350 100644 --- a/sql/opt_qpf.cc +++ b/sql/opt_qpf.cc @@ -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; } } } diff --git a/sql/opt_qpf.h b/sql/opt_qpf.h index 501ac7c609e..1944f79254d 100644 --- a/sql/opt_qpf.h +++ b/sql/opt_qpf.h @@ -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]; }; diff --git a/sql/sql_array.h b/sql/sql_array.h index 43ca4ef4219..18f1fbd9f2f 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -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); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bad29d70af9..1b98d0b12ee 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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)) { |